Meta with timestamp

José Rafael zerafael at gmail.com
Tue Mar 20 12:39:59 UTC 2018


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);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/gstreamer-devel/attachments/20180320/5493cbae/attachment.html>


More information about the gstreamer-devel mailing list