mpeg4videoparse: add config-interval parameter to re-insert config in stream

Add a new config-interval property to instruct the parser to insert
config (VOSH, VOS, etc) at periodic intervals in the stream
(when a GOP or VOP-I is encountered).

Based on patch by <marc.leeman at gmail.com>

Fixes #621205.
This commit is contained in:
Mark Nauwelaerts 2010-06-15 11:16:34 +02:00
parent 2f9b765326
commit c2b649d692
2 changed files with 64 additions and 1 deletions

View file

@ -47,11 +47,13 @@ GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK,
/* Properties */
#define DEFAULT_PROP_DROP TRUE
#define DEFAULT_CONFIG_INTERVAL (0)
enum
{
PROP_0,
PROP_DROP,
PROP_CONFIG_INTERVAL,
PROP_LAST
};
@ -478,14 +480,54 @@ gst_mpeg4vparse_push (GstMpeg4VParse * parse, gsize size)
GstBuffer *out_buf;
out_buf = gst_adapter_take_buffer (parse->adapter, parse->offset);
GST_BUFFER_TIMESTAMP (out_buf) = parse->timestamp;
if (out_buf) {
/* Set GST_BUFFER_FLAG_DELTA_UNIT if it's not an intra frame */
if (!parse->intra_frame) {
GST_BUFFER_FLAG_SET (out_buf, GST_BUFFER_FLAG_DELTA_UNIT);
} else if (parse->interval > 0 && parse->config) {
GstClockTime timestamp = GST_BUFFER_TIMESTAMP (out_buf);
guint64 diff;
/* init */
if (!GST_CLOCK_TIME_IS_VALID (parse->last_report)) {
parse->last_report = timestamp;
}
/* insert on intra frames */
if (timestamp > parse->last_report)
diff = timestamp - parse->last_report;
else
diff = 0;
GST_LOG_OBJECT (parse,
"now %" GST_TIME_FORMAT ", last VOP-I %" GST_TIME_FORMAT,
GST_TIME_ARGS (timestamp), GST_TIME_ARGS (parse->last_report));
GST_DEBUG_OBJECT (parse,
"interval since last config %" GST_TIME_FORMAT,
GST_TIME_ARGS (diff));
if (GST_TIME_AS_SECONDS (diff) >= parse->interval) {
/* we need to send config now first */
GstBuffer *superbuf;
GST_LOG_OBJECT (parse, "inserting config in stream");
/* insert header */
superbuf = gst_buffer_merge (parse->config, out_buf);
GST_BUFFER_TIMESTAMP (superbuf) = timestamp;
gst_buffer_unref (out_buf);
out_buf = superbuf;
if (timestamp != -1) {
parse->last_report = timestamp;
}
}
}
gst_buffer_set_caps (out_buf, GST_PAD_CAPS (parse->srcpad));
GST_BUFFER_TIMESTAMP (out_buf) = parse->timestamp;
gst_pad_push (parse->srcpad, out_buf);
}
}
@ -820,6 +862,7 @@ gst_mpeg4vparse_cleanup (GstMpeg4VParse * parse)
parse->state = PARSE_NEED_START;
parse->have_config = FALSE;
parse->offset = 0;
parse->last_report = GST_CLOCK_TIME_NONE;
}
static GstStateChangeReturn
@ -884,6 +927,9 @@ gst_mpeg4vparse_set_property (GObject * object, guint property_id,
case PROP_DROP:
parse->drop = g_value_get_boolean (value);
break;
case PROP_CONFIG_INTERVAL:
parse->interval = g_value_get_uint (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
@ -899,6 +945,9 @@ gst_mpeg4vparse_get_property (GObject * object, guint property_id,
case PROP_DROP:
g_value_set_boolean (value, parse->drop);
break;
case PROP_CONFIG_INTERVAL:
g_value_set_uint (value, parse->interval);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
@ -925,6 +974,14 @@ gst_mpeg4vparse_class_init (GstMpeg4VParseClass * klass)
"in the stream or through caps", DEFAULT_PROP_DROP,
G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, PROP_CONFIG_INTERVAL,
g_param_spec_uint ("config-interval",
"Configuration Send Interval",
"Send Configuration Insertion Interval in seconds (configuration headers "
"will be multiplexed in the data stream when detected.) (0 = disabled)",
0, 3600, DEFAULT_CONFIG_INTERVAL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_mpeg4vparse_change_state);
}
@ -949,6 +1006,9 @@ gst_mpeg4vparse_init (GstMpeg4VParse * parse, GstMpeg4VParseClass * g_class)
parse->adapter = gst_adapter_new ();
parse->interval = DEFAULT_CONFIG_INTERVAL;
parse->last_report = GST_CLOCK_TIME_NONE;
gst_mpeg4vparse_cleanup (parse);
}

View file

@ -54,6 +54,9 @@ struct _GstMpeg4VParse {
GstPad * sinkpad;
GstPad * srcpad;
guint interval;
GstClockTime last_report;
GstAdapter * adapter;
guint offset;
guint vos_offset;