asfdemux: if video is h264, check the codec_data for bytestream data
For bytestream we don't want to expose it as codec_data but rather as streamheader as it is not out-of-band data but data that should be prepended to the beginning of the stream before the other buffers. https://bugzilla.gnome.org/show_bug.cgi?id=735070
This commit is contained in:
parent
2402349d13
commit
2863d9ae00
@ -147,6 +147,10 @@ gst_asf_demux_free_stream (GstASFDemux * demux, AsfStream * stream)
|
|||||||
gst_tag_list_unref (stream->pending_tags);
|
gst_tag_list_unref (stream->pending_tags);
|
||||||
stream->pending_tags = NULL;
|
stream->pending_tags = NULL;
|
||||||
}
|
}
|
||||||
|
if (stream->streamheader) {
|
||||||
|
gst_buffer_unref (stream->streamheader);
|
||||||
|
stream->streamheader = NULL;
|
||||||
|
}
|
||||||
if (stream->pad) {
|
if (stream->pad) {
|
||||||
if (stream->active) {
|
if (stream->active) {
|
||||||
gst_element_remove_pad (GST_ELEMENT_CAST (demux), stream->pad);
|
gst_element_remove_pad (GST_ELEMENT_CAST (demux), stream->pad);
|
||||||
@ -525,6 +529,7 @@ gst_asf_demux_reset_stream_state_after_discont (GstASFDemux * demux)
|
|||||||
|
|
||||||
for (n = 0; n < demux->num_streams; n++) {
|
for (n = 0; n < demux->num_streams; n++) {
|
||||||
demux->stream[n].discont = TRUE;
|
demux->stream[n].discont = TRUE;
|
||||||
|
demux->stream[n].first_buffer = TRUE;
|
||||||
|
|
||||||
while (demux->stream[n].payloads->len > 0) {
|
while (demux->stream[n].payloads->len > 0) {
|
||||||
AsfPayload *payload;
|
AsfPayload *payload;
|
||||||
@ -1707,6 +1712,15 @@ gst_asf_demux_push_complete_payloads (GstASFDemux * demux, gboolean force)
|
|||||||
payload->buf);
|
payload->buf);
|
||||||
|
|
||||||
if (stream->active) {
|
if (stream->active) {
|
||||||
|
if (G_UNLIKELY (stream->first_buffer)) {
|
||||||
|
if (stream->streamheader != NULL) {
|
||||||
|
GST_DEBUG_OBJECT (stream->pad,
|
||||||
|
"Pushing streamheader before first buffer");
|
||||||
|
gst_pad_push (stream->pad, gst_buffer_ref (stream->streamheader));
|
||||||
|
}
|
||||||
|
stream->first_buffer = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
ret = gst_pad_push (stream->pad, payload->buf);
|
ret = gst_pad_push (stream->pad, payload->buf);
|
||||||
ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
|
ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
|
||||||
} else {
|
} else {
|
||||||
@ -2339,7 +2353,8 @@ gst_asf_demux_get_stream (GstASFDemux * demux, guint16 id)
|
|||||||
|
|
||||||
static AsfStream *
|
static AsfStream *
|
||||||
gst_asf_demux_setup_pad (GstASFDemux * demux, GstPad * src_pad,
|
gst_asf_demux_setup_pad (GstASFDemux * demux, GstPad * src_pad,
|
||||||
GstCaps * caps, guint16 id, gboolean is_video, GstTagList * tags)
|
GstCaps * caps, guint16 id, gboolean is_video, GstBuffer * streamheader,
|
||||||
|
GstTagList * tags)
|
||||||
{
|
{
|
||||||
AsfStream *stream;
|
AsfStream *stream;
|
||||||
|
|
||||||
@ -2359,6 +2374,12 @@ gst_asf_demux_setup_pad (GstASFDemux * demux, GstPad * src_pad,
|
|||||||
stream->is_video = is_video;
|
stream->is_video = is_video;
|
||||||
stream->pending_tags = tags;
|
stream->pending_tags = tags;
|
||||||
stream->discont = TRUE;
|
stream->discont = TRUE;
|
||||||
|
stream->first_buffer = TRUE;
|
||||||
|
stream->streamheader = streamheader;
|
||||||
|
if (stream->streamheader) {
|
||||||
|
stream->streamheader = gst_buffer_make_writable (streamheader);
|
||||||
|
GST_BUFFER_FLAG_SET (stream->streamheader, GST_BUFFER_FLAG_HEADER);
|
||||||
|
}
|
||||||
if (is_video) {
|
if (is_video) {
|
||||||
GstStructure *st;
|
GstStructure *st;
|
||||||
gint par_x, par_y;
|
gint par_x, par_y;
|
||||||
@ -2383,6 +2404,22 @@ gst_asf_demux_setup_pad (GstASFDemux * demux, GstPad * src_pad,
|
|||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_asf_demux_add_stream_headers_to_caps (GstASFDemux * demux,
|
||||||
|
GstBuffer * buffer, GstStructure * structure)
|
||||||
|
{
|
||||||
|
GValue arr_val = G_VALUE_INIT;
|
||||||
|
GValue buf_val = G_VALUE_INIT;
|
||||||
|
|
||||||
|
g_value_init (&arr_val, GST_TYPE_ARRAY);
|
||||||
|
g_value_init (&buf_val, GST_TYPE_BUFFER);
|
||||||
|
|
||||||
|
gst_value_set_buffer (&buf_val, buffer);
|
||||||
|
gst_value_array_append_and_take_value (&arr_val, &buf_val);
|
||||||
|
|
||||||
|
gst_structure_take_value (structure, "streamheader", &arr_val);
|
||||||
|
}
|
||||||
|
|
||||||
static AsfStream *
|
static AsfStream *
|
||||||
gst_asf_demux_add_audio_stream (GstASFDemux * demux,
|
gst_asf_demux_add_audio_stream (GstASFDemux * demux,
|
||||||
asf_stream_audio * audio, guint16 id, guint8 ** p_data, guint64 * p_size)
|
asf_stream_audio * audio, guint16 id, guint8 ** p_data, guint64 * p_size)
|
||||||
@ -2439,7 +2476,7 @@ gst_asf_demux_add_audio_stream (GstASFDemux * demux,
|
|||||||
|
|
||||||
++demux->num_audio_streams;
|
++demux->num_audio_streams;
|
||||||
|
|
||||||
return gst_asf_demux_setup_pad (demux, src_pad, caps, id, FALSE, tags);
|
return gst_asf_demux_setup_pad (demux, src_pad, caps, id, FALSE, NULL, tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static AsfStream *
|
static AsfStream *
|
||||||
@ -2456,6 +2493,7 @@ gst_asf_demux_add_video_stream (GstASFDemux * demux,
|
|||||||
gchar *name = NULL;
|
gchar *name = NULL;
|
||||||
gchar *codec_name = NULL;
|
gchar *codec_name = NULL;
|
||||||
gint size_left = video->size - 40;
|
gint size_left = video->size - 40;
|
||||||
|
GstBuffer *streamheader = NULL;
|
||||||
|
|
||||||
/* Create the video pad */
|
/* Create the video pad */
|
||||||
name = g_strdup_printf ("video_%u", demux->num_video_streams);
|
name = g_strdup_printf ("video_%u", demux->num_video_streams);
|
||||||
@ -2513,6 +2551,23 @@ gst_asf_demux_add_video_stream (GstASFDemux * demux,
|
|||||||
str = g_strdup_printf ("%" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (video->tag));
|
str = g_strdup_printf ("%" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (video->tag));
|
||||||
gst_caps_set_simple (caps, "format", G_TYPE_STRING, str, NULL);
|
gst_caps_set_simple (caps, "format", G_TYPE_STRING, str, NULL);
|
||||||
g_free (str);
|
g_free (str);
|
||||||
|
|
||||||
|
/* check if h264 has codec_data (avc) or streamheaders (bytestream) */
|
||||||
|
} else if (gst_structure_has_name (caps_s, "video/x-h264")) {
|
||||||
|
const GValue *value = gst_structure_get_value (caps_s, "codec_data");
|
||||||
|
GstBuffer *buf = gst_value_get_buffer (value);
|
||||||
|
GstMapInfo mapinfo;
|
||||||
|
|
||||||
|
if (gst_buffer_map (buf, &mapinfo, GST_MAP_READ)) {
|
||||||
|
if (mapinfo.size >= 4 && GST_READ_UINT32_BE (mapinfo.data) == 1) {
|
||||||
|
/* this looks like a bytestream start */
|
||||||
|
streamheader = gst_buffer_ref (buf);
|
||||||
|
gst_asf_demux_add_stream_headers_to_caps (demux, buf, caps_s);
|
||||||
|
gst_structure_remove_field (caps_s, "codec_data");
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_buffer_unmap (buf, &mapinfo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (codec_name) {
|
if (codec_name) {
|
||||||
@ -2529,7 +2584,8 @@ gst_asf_demux_add_video_stream (GstASFDemux * demux,
|
|||||||
|
|
||||||
++demux->num_video_streams;
|
++demux->num_video_streams;
|
||||||
|
|
||||||
return gst_asf_demux_setup_pad (demux, src_pad, caps, id, TRUE, tags);
|
return gst_asf_demux_setup_pad (demux, src_pad, caps, id, TRUE,
|
||||||
|
streamheader, tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -96,9 +96,12 @@ typedef struct
|
|||||||
|
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
|
|
||||||
|
GstBuffer *streamheader;
|
||||||
|
|
||||||
GstTagList *pending_tags;
|
GstTagList *pending_tags;
|
||||||
|
|
||||||
gboolean discont;
|
gboolean discont;
|
||||||
|
gboolean first_buffer;
|
||||||
|
|
||||||
/* Descrambler settings */
|
/* Descrambler settings */
|
||||||
guint8 span;
|
guint8 span;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user