mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-22 22:16:22 +00:00
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:
parent
2f9b765326
commit
c2b649d692
2 changed files with 64 additions and 1 deletions
|
@ -47,11 +47,13 @@ GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK,
|
||||||
|
|
||||||
/* Properties */
|
/* Properties */
|
||||||
#define DEFAULT_PROP_DROP TRUE
|
#define DEFAULT_PROP_DROP TRUE
|
||||||
|
#define DEFAULT_CONFIG_INTERVAL (0)
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_DROP,
|
PROP_DROP,
|
||||||
|
PROP_CONFIG_INTERVAL,
|
||||||
PROP_LAST
|
PROP_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -478,14 +480,54 @@ gst_mpeg4vparse_push (GstMpeg4VParse * parse, gsize size)
|
||||||
GstBuffer *out_buf;
|
GstBuffer *out_buf;
|
||||||
|
|
||||||
out_buf = gst_adapter_take_buffer (parse->adapter, parse->offset);
|
out_buf = gst_adapter_take_buffer (parse->adapter, parse->offset);
|
||||||
|
GST_BUFFER_TIMESTAMP (out_buf) = parse->timestamp;
|
||||||
|
|
||||||
if (out_buf) {
|
if (out_buf) {
|
||||||
/* Set GST_BUFFER_FLAG_DELTA_UNIT if it's not an intra frame */
|
/* Set GST_BUFFER_FLAG_DELTA_UNIT if it's not an intra frame */
|
||||||
if (!parse->intra_frame) {
|
if (!parse->intra_frame) {
|
||||||
GST_BUFFER_FLAG_SET (out_buf, GST_BUFFER_FLAG_DELTA_UNIT);
|
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_set_caps (out_buf, GST_PAD_CAPS (parse->srcpad));
|
||||||
GST_BUFFER_TIMESTAMP (out_buf) = parse->timestamp;
|
|
||||||
gst_pad_push (parse->srcpad, out_buf);
|
gst_pad_push (parse->srcpad, out_buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -820,6 +862,7 @@ gst_mpeg4vparse_cleanup (GstMpeg4VParse * parse)
|
||||||
parse->state = PARSE_NEED_START;
|
parse->state = PARSE_NEED_START;
|
||||||
parse->have_config = FALSE;
|
parse->have_config = FALSE;
|
||||||
parse->offset = 0;
|
parse->offset = 0;
|
||||||
|
parse->last_report = GST_CLOCK_TIME_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstStateChangeReturn
|
static GstStateChangeReturn
|
||||||
|
@ -884,6 +927,9 @@ gst_mpeg4vparse_set_property (GObject * object, guint property_id,
|
||||||
case PROP_DROP:
|
case PROP_DROP:
|
||||||
parse->drop = g_value_get_boolean (value);
|
parse->drop = g_value_get_boolean (value);
|
||||||
break;
|
break;
|
||||||
|
case PROP_CONFIG_INTERVAL:
|
||||||
|
parse->interval = g_value_get_uint (value);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
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:
|
case PROP_DROP:
|
||||||
g_value_set_boolean (value, parse->drop);
|
g_value_set_boolean (value, parse->drop);
|
||||||
break;
|
break;
|
||||||
|
case PROP_CONFIG_INTERVAL:
|
||||||
|
g_value_set_uint (value, parse->interval);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
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,
|
"in the stream or through caps", DEFAULT_PROP_DROP,
|
||||||
G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
|
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 =
|
gstelement_class->change_state =
|
||||||
GST_DEBUG_FUNCPTR (gst_mpeg4vparse_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->adapter = gst_adapter_new ();
|
||||||
|
|
||||||
|
parse->interval = DEFAULT_CONFIG_INTERVAL;
|
||||||
|
parse->last_report = GST_CLOCK_TIME_NONE;
|
||||||
|
|
||||||
gst_mpeg4vparse_cleanup (parse);
|
gst_mpeg4vparse_cleanup (parse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,9 @@ struct _GstMpeg4VParse {
|
||||||
GstPad * sinkpad;
|
GstPad * sinkpad;
|
||||||
GstPad * srcpad;
|
GstPad * srcpad;
|
||||||
|
|
||||||
|
guint interval;
|
||||||
|
GstClockTime last_report;
|
||||||
|
|
||||||
GstAdapter * adapter;
|
GstAdapter * adapter;
|
||||||
guint offset;
|
guint offset;
|
||||||
guint vos_offset;
|
guint vos_offset;
|
||||||
|
|
Loading…
Reference in a new issue