Meta with timestamp

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Meta with timestamp

José Rafael
Hello,

I'm using the code below to timestamp a pipeline and get a delay in the end for the buffers.
It work fine usually, putting the but timestamp at the src pad and getting the difference in the sink.
However, in a longer transcoding pipeline the transform function always get non writable buffers, and the meta is not replicated.

Is there a way to now who is blocking the buffer, or a workaround?

Any tips will be really appreciated.

Regards
Rafael

/* meta functions */
#include <gst/gst.h>
#include <unistd.h>
#include <sys/time.h>
#include <glib.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <argp.h>

typedef struct _GstMetaTS GstMetaTS;

struct _GstMetaTS {
        GstMeta meta;
        GstClockTime in_timestamp;
};

GType gst_meta_ts_api_get_type (void);

const GstMetaInfo* gst_meta_ts_get_info (void);

#define GST_META_TS_GET(buf) ((GstMetaTS *)gst_buffer_get_meta(buf,gst_meta_ts_api_get_type()))
#define GST_META_TS_ADD(buf) ((GstMetaTS *)gst_buffer_add_meta(buf,gst_meta_ts_get_info(),(gpointer)NULL))

gboolean gst_meta_ts_transform (GstBuffer *dest_buf, GstMeta *src_meta, GstBuffer *src_buf, GQuark type, gpointer data) {
        GstBuffer * buf = NULL;
        if(! gst_buffer_is_writable(dest_buf))
        {
                GST_DEBUG("NOT WRITABLE, NOT ABLE TO TRANSFORM\n");
                return FALSE;
        }
        GstMeta* dest_meta = (GstMeta*)GST_META_TS_ADD(dest_buf);
        GstMetaTS* src_meta_ts = (GstMetaTS*)src_meta;
        GstMetaTS* dest_meta_ts = (GstMetaTS*)dest_meta;
        dest_meta_ts->in_timestamp = src_meta_ts->in_timestamp;
        return TRUE;
}

void gst_meta_ts_free (GstMeta *meta, GstBuffer *buffer) {
}

gboolean gst_meta_ts_init(GstMeta *meta, gpointer params, GstBuffer *buffer){
        GstMetaTS* ts_meta = (GstMetaTS*)meta;
        ts_meta->in_timestamp = GST_CLOCK_TIME_NONE;
        return TRUE;
}

GType gst_meta_ts_api_get_type (void){
  static volatile GType type;
  static const gchar *tags[] = { NULL };
  if (g_once_init_enter (&type)) {
        GType _type = gst_meta_api_type_register ("GstMetaTSAPI", tags);
        g_once_init_leave (&type, _type);
  }
  return type;
}

/* transcoder code */
static GstPadProbeReturn probe_src (GstPad *pad, GstPadProbeInfo *info, gpointer user_data){
        if (playing){
                GstBuffer *b;
                b = GST_PAD_PROBE_INFO_BUFFER (info);
                if (! gst_buffer_is_writable(b))
                {
                        return GST_PAD_PROBE_OK;
                }
                GstMetaTS* meta = GST_META_TS_ADD(b);
                GstClock* clock = gst_system_clock_obtain ();
                meta->in_timestamp = gst_clock_get_time(clock);
                gst_object_unref(clock);
        }
        return GST_PAD_PROBE_OK;
}

static GstPadProbeReturn probe_sink (GstPad *pad, GstPadProbeInfo *info, gpointer user_data){
        GstBuffer *b;
        b = GST_PAD_PROBE_INFO_BUFFER (info);
        if (! gst_buffer_is_writable(b))
        {
                return GST_PAD_PROBE_OK;
        }
        GstMetaTS* meta = GST_META_TS_GET(b);
        if(meta == NULL) {
                return GST_PAD_PROBE_OK;
        }
        GstClock* clock = gst_system_clock_obtain ();
        GstClockTimeDiff diff = GST_CLOCK_DIFF(meta->in_timestamp, gst_clock_get_time(clock));
        delay_avg = ((delay_avg*delay_count)+diff)/++delay_count;
        if (last_delay_print + DELAY_PRINT_INTERVAL < get_time_us()){
                printf("DELAY_NOW:%3.4fms,DELAY_AVG:%3.4fms\n",((double)diff)/1000/1000,delay_avg/1000/1000);
                last_delay_print = get_time_us();
        }
        gst_object_unref(clock);
        gst_buffer_remove_meta(b, (GstMeta*)meta);
        return GST_PAD_PROBE_OK;
}

(...)

GstPad *pad = gst_element_get_static_pad (tra_src, "src");
gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER, (GstPadProbeCallback) probe_src, NULL, NULL);
gst_object_unref (pad);

pad = gst_element_get_static_pad (tra_sink, "sink");
gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER, (GstPadProbeCallback) probe_sink, NULL, NULL);
gst_object_unref (pad);



_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Meta with timestamp

Edward Hervey-4
Hi,

  Just ensure the buffer is writable (it won't actually copy the
underlying memory) with gst_buffer_make_writable() and set it back to
the GST_PAD_PROBE_INFO_DATA so that it gets propagated.

   Edward

On Tue, 2018-03-20 at 13:39 +0100, José Rafael wrote:

> Hello,
>
> I'm using the code below to timestamp a pipeline and get a delay in
> the end for the buffers.
> It work fine usually, putting the but timestamp at the src pad and
> getting the difference in the sink.
> However, in a longer transcoding pipeline the transform function
> always get non writable buffers, and the meta is not replicated.
>
> Is there a way to now who is blocking the buffer, or a workaround?
>
> Any tips will be really appreciated.
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Meta with timestamp

José Rafael
Hi Edward

Thank you for the help. 

With gst_buffer_make_writable(), as below, I have the first meta propagated, and after a segmentation fault.
It should make a copy if not writable, no? 

If I use gst_buffer_copy() it processes the buffer without the seg fault, but not writing back on the right buffer. 

This make me think dest_buff is being changes somewhere else.

I don't get the funcionality of  GST_PAD_PROBE_INFO_DATA(), should be in the transformation function?

Regards
Rafael

gboolean gst_meta_ts_transform (GstBuffer *dest_buf, GstMeta *src_meta, GstBuffer *src_buf, GQuark type, gpointer data) {
        dest_buf = gst_buffer_make_writable(dest_buf);
        if(! gst_buffer_is_writable(dest_buf))
        {
                printf("gst_meta_ts_transform: not writable to be transformed\n");
                return FALSE;
        }
        GstMeta* dest_meta = (GstMeta*)GST_META_TS_ADD(dest_buf);
        GstMetaTS* src_meta_ts = (GstMetaTS*)src_meta;
        GstMetaTS* dest_meta_ts = (GstMetaTS*)dest_meta;
        dest_meta_ts->in_timestamp = src_meta_ts->in_timestamp;
        return TRUE;
}



On 20 March 2018 at 15:24, Edward Hervey <[hidden email]> wrote:
Hi,

  Just ensure the buffer is writable (it won't actually copy the
underlying memory) with gst_buffer_make_writable() and set it back to
the GST_PAD_PROBE_INFO_DATA so that it gets propagated.

   Edward

On Tue, 2018-03-20 at 13:39 +0100, José Rafael wrote:
> Hello,
>
> I'm using the code below to timestamp a pipeline and get a delay in
> the end for the buffers.
> It work fine usually, putting the but timestamp at the src pad and
> getting the difference in the sink.
> However, in a longer transcoding pipeline the transform function
> always get non writable buffers, and the meta is not replicated.
>
> Is there a way to now who is blocking the buffer, or a workaround?
>
> Any tips will be really appreciated.
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel


_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Meta with timestamp

Frederik
Hi Rafeal,
did you find a solution for your problem ? I'm facing the same problem.



--
Sent from: http://gstreamer-devel.966125.n4.nabble.com/
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel