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