mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-23 15:48:23 +00:00
flvdemux: Don't create AAC/H264 caps without codec_data
Instead delay creating the caps until we read the codec_data from the stream, or fail if we get normal data before the codec_data. AAC raw caps and H264 avc caps always need codec_data, setting caps on the pad without them is going to make negotiation fail most of the time. Even if we later set new caps with the codec_data, that's usually going to be too late. https://bugzilla.gnome.org/show_bug.cgi?id=746682
This commit is contained in:
parent
5e88b53212
commit
c9b42951fe
1 changed files with 79 additions and 46 deletions
|
@ -704,8 +704,12 @@ gst_flv_demux_audio_negotiate (GstFlvDemux * demux, guint32 codec_tag,
|
|||
break;
|
||||
case 10:
|
||||
{
|
||||
if (demux->audio_codec_data) {
|
||||
GstMapInfo map;
|
||||
if (!demux->audio_codec_data) {
|
||||
GST_DEBUG_OBJECT (demux, "don't have AAC codec data yet");
|
||||
ret = TRUE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
gst_buffer_map (demux->audio_codec_data, &map, GST_MAP_READ);
|
||||
|
||||
|
@ -726,7 +730,6 @@ gst_flv_demux_audio_negotiate (GstFlvDemux * demux, guint32 codec_tag,
|
|||
}
|
||||
}
|
||||
gst_buffer_unmap (demux->audio_codec_data, &map);
|
||||
}
|
||||
|
||||
caps = gst_caps_new_simple ("audio/mpeg",
|
||||
"mpegversion", G_TYPE_INT, 4, "framed", G_TYPE_BOOLEAN, TRUE,
|
||||
|
@ -823,6 +826,7 @@ gst_flv_demux_audio_negotiate (GstFlvDemux * demux, guint32 codec_tag,
|
|||
|
||||
ret = gst_pad_set_caps (demux->audio_pad, caps);
|
||||
|
||||
done:
|
||||
if (G_LIKELY (ret)) {
|
||||
/* Store the caps we got from tags */
|
||||
demux->audio_codec_tag = codec_tag;
|
||||
|
@ -830,6 +834,7 @@ gst_flv_demux_audio_negotiate (GstFlvDemux * demux, guint32 codec_tag,
|
|||
demux->channels = channels;
|
||||
demux->width = width;
|
||||
|
||||
if (caps) {
|
||||
codec_name = gst_pb_utils_get_codec_description (caps);
|
||||
|
||||
if (codec_name) {
|
||||
|
@ -842,11 +847,15 @@ gst_flv_demux_audio_negotiate (GstFlvDemux * demux, guint32 codec_tag,
|
|||
|
||||
GST_DEBUG_OBJECT (demux->audio_pad, "successfully negotiated caps %"
|
||||
GST_PTR_FORMAT, caps);
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (demux->audio_pad, "delayed setting caps");
|
||||
}
|
||||
} else {
|
||||
GST_WARNING_OBJECT (demux->audio_pad, "failed negotiating caps %"
|
||||
GST_PTR_FORMAT, caps);
|
||||
}
|
||||
|
||||
if (caps)
|
||||
gst_caps_unref (caps);
|
||||
|
||||
beach:
|
||||
|
@ -1068,6 +1077,8 @@ gst_flv_demux_parse_tag_audio (GstFlvDemux * demux, GstBuffer * buffer)
|
|||
codec_tag != demux->audio_codec_tag || width != demux->width)) {
|
||||
GST_DEBUG_OBJECT (demux, "audio settings have changed, changing caps");
|
||||
|
||||
gst_buffer_replace (&demux->audio_codec_data, NULL);
|
||||
|
||||
/* Negotiate caps */
|
||||
if (!gst_flv_demux_audio_negotiate (demux, codec_tag, rate, channels,
|
||||
width)) {
|
||||
|
@ -1107,6 +1118,12 @@ gst_flv_demux_parse_tag_audio (GstFlvDemux * demux, GstBuffer * buffer)
|
|||
goto beach;
|
||||
}
|
||||
case 1:
|
||||
if (!demux->audio_codec_data) {
|
||||
GST_ERROR_OBJECT (demux, "got AAC audio packet before codec data");
|
||||
ret = GST_FLOW_OK;
|
||||
gst_buffer_unref (outbuf);
|
||||
goto beach;
|
||||
}
|
||||
/* AAC raw packet */
|
||||
GST_LOG_OBJECT (demux, "got a raw AAC audio packet");
|
||||
break;
|
||||
|
@ -1239,6 +1256,11 @@ gst_flv_demux_video_negotiate (GstFlvDemux * demux, guint32 codec_tag)
|
|||
caps = gst_caps_new_empty_simple ("video/x-vp6-alpha");
|
||||
break;
|
||||
case 7:
|
||||
if (!demux->video_codec_data) {
|
||||
GST_DEBUG_OBJECT (demux, "don't have h264 codec data yet");
|
||||
ret = TRUE;
|
||||
goto done;
|
||||
}
|
||||
caps =
|
||||
gst_caps_new_simple ("video/x-h264", "stream-format", G_TYPE_STRING,
|
||||
"avc", NULL);
|
||||
|
@ -1290,10 +1312,12 @@ gst_flv_demux_video_negotiate (GstFlvDemux * demux, guint32 codec_tag)
|
|||
gst_pad_push_event (demux->video_pad, event);
|
||||
ret = gst_pad_set_caps (demux->video_pad, caps);
|
||||
|
||||
done:
|
||||
if (G_LIKELY (ret)) {
|
||||
/* Store the caps we have set */
|
||||
demux->video_codec_tag = codec_tag;
|
||||
|
||||
if (caps) {
|
||||
codec_name = gst_pb_utils_get_codec_description (caps);
|
||||
|
||||
if (codec_name) {
|
||||
|
@ -1306,11 +1330,15 @@ gst_flv_demux_video_negotiate (GstFlvDemux * demux, guint32 codec_tag)
|
|||
|
||||
GST_DEBUG_OBJECT (demux->video_pad, "successfully negotiated caps %"
|
||||
GST_PTR_FORMAT, caps);
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (demux->video_pad, "delayed setting caps");
|
||||
}
|
||||
} else {
|
||||
GST_WARNING_OBJECT (demux->video_pad, "failed negotiating caps %"
|
||||
GST_PTR_FORMAT, caps);
|
||||
}
|
||||
|
||||
if (caps)
|
||||
gst_caps_unref (caps);
|
||||
|
||||
beach:
|
||||
|
@ -1452,8 +1480,8 @@ gst_flv_demux_parse_tag_video (GstFlvDemux * demux, GstBuffer * buffer)
|
|||
|
||||
/* Check if caps have changed */
|
||||
if (G_UNLIKELY (codec_tag != demux->video_codec_tag || demux->got_par)) {
|
||||
|
||||
GST_DEBUG_OBJECT (demux, "video settings have changed, changing caps");
|
||||
gst_buffer_replace (&demux->video_codec_data, NULL);
|
||||
|
||||
if (!gst_flv_demux_video_negotiate (demux, codec_tag)) {
|
||||
ret = GST_FLOW_ERROR;
|
||||
|
@ -1497,6 +1525,12 @@ gst_flv_demux_parse_tag_video (GstFlvDemux * demux, GstBuffer * buffer)
|
|||
}
|
||||
case 1:
|
||||
/* H.264 NALU packet */
|
||||
if (!demux->video_codec_data) {
|
||||
GST_ERROR_OBJECT (demux, "got H.264 video packet before codec data");
|
||||
ret = GST_FLOW_OK;
|
||||
gst_buffer_unref (outbuf);
|
||||
goto beach;
|
||||
}
|
||||
GST_LOG_OBJECT (demux, "got a H.264 NALU video packet");
|
||||
break;
|
||||
default:
|
||||
|
@ -2357,7 +2391,6 @@ gst_flv_demux_seek_to_prev_keyframe (GstFlvDemux * demux)
|
|||
gst_object_unref (index);
|
||||
}
|
||||
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue