mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-29 13:11:06 +00:00
oggdemux: vp8: Detect keyframe packets
decodebin3 drops data on video streams until a keyframe or header is detected, so for Ogg/VP8 we now need to correctly flag and signal keyframes downstream. The first buffer pushed from each src pad also has the HEADER flag set. Fixes playback of https://github.com/web-platform-tests/wpt/raw/master/media/test.ogv in playbin3. Fixes #1418 Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4725>
This commit is contained in:
parent
cd4b84b60b
commit
a7b09098b9
6 changed files with 34 additions and 4 deletions
|
@ -1 +1 @@
|
||||||
Subproject commit 7d39b42f64f0e1f4e131266a2b4a72087ef6427b
|
Subproject commit ea0342a6bf6e27320b4aaec75019ab31ca9c3c6a
|
|
@ -948,6 +948,7 @@ validate.test.mse.segment_future_past_nomse
|
||||||
validate.test.nle.urisource.play
|
validate.test.nle.urisource.play
|
||||||
validate.test.playbin.check_active_stream
|
validate.test.playbin.check_active_stream
|
||||||
validate.test.playbin3.ignore_raw_audio_from_demuxer
|
validate.test.playbin3.ignore_raw_audio_from_demuxer
|
||||||
|
validate.test.playbin3.ogv_vp8
|
||||||
validate.test.playbin3.sourcebin_check_mixed_static_and_dyanmic_pads
|
validate.test.playbin3.sourcebin_check_mixed_static_and_dyanmic_pads
|
||||||
validate.test.rtp.h264.payloader_fail_nego_force_profile
|
validate.test.rtp.h264.payloader_fail_nego_force_profile
|
||||||
validate.test.rtp.h264.payloader_nego_profile
|
validate.test.rtp.h264.payloader_nego_profile
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
set-globals, media_dir="$(test_dir)/../../../medias/"
|
||||||
|
meta,
|
||||||
|
args = {
|
||||||
|
"playbin3 uri=file://$(media_dir)/defaults/ogg/wpt-test-ogg-vp8.ogv name=playbin video-sink=\"$(videosink) name=videosink\" audio-sink=\"$(audiosink)\"",
|
||||||
|
},
|
||||||
|
scenario=play_5s
|
|
@ -580,6 +580,9 @@ gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet,
|
||||||
if ((packet->bytes >= 7 && memcmp (packet->packet, "OVP80\2 ", 7) == 0) ||
|
if ((packet->bytes >= 7 && memcmp (packet->packet, "OVP80\2 ", 7) == 0) ||
|
||||||
packet->b_o_s ||
|
packet->b_o_s ||
|
||||||
(packet->bytes >= 5 && memcmp (packet->packet, "OVP80", 5) == 0)) {
|
(packet->bytes >= 5 && memcmp (packet->packet, "OVP80", 5) == 0)) {
|
||||||
|
/* Request the first packet being pushed downstream to have the header
|
||||||
|
flag set, unblocking the keyframe_waiter_probe in decodebin3. */
|
||||||
|
pad->need_header_flag = TRUE;
|
||||||
/* We don't push header packets for VP8 */
|
/* We don't push header packets for VP8 */
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
@ -818,9 +821,11 @@ gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet,
|
||||||
if (delta_unit)
|
if (delta_unit)
|
||||||
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
|
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
|
||||||
|
|
||||||
/* set header flag for buffers that are also in the streamheaders */
|
/* set header flag for buffers that are also in the streamheaders or when explicitely requested (VP8). */
|
||||||
if (is_header)
|
if (is_header || pad->need_header_flag) {
|
||||||
|
pad->need_header_flag = FALSE;
|
||||||
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
|
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
|
||||||
|
}
|
||||||
|
|
||||||
if (packet->packet != NULL) {
|
if (packet->packet != NULL) {
|
||||||
/* copy packet in buffer */
|
/* copy packet in buffer */
|
||||||
|
|
|
@ -102,6 +102,8 @@ struct _GstOggPad
|
||||||
|
|
||||||
GList *continued;
|
GList *continued;
|
||||||
|
|
||||||
|
gboolean need_header_flag;
|
||||||
|
|
||||||
gboolean discont;
|
gboolean discont;
|
||||||
GstFlowReturn last_ret; /* last return of _pad_push() */
|
GstFlowReturn last_ret; /* last return of _pad_push() */
|
||||||
gboolean is_eos;
|
gboolean is_eos;
|
||||||
|
|
|
@ -761,6 +761,22 @@ is_keyframe_vp8 (GstOggStream * pad, gint64 granulepos)
|
||||||
return ((gpos & 0x07ffffff) == 0);
|
return ((gpos & 0x07ffffff) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
is_packet_keyframe_vp8 (GstOggStream * pad, ogg_packet * packet)
|
||||||
|
{
|
||||||
|
guint32 hdr;
|
||||||
|
gboolean is_kf = FALSE;
|
||||||
|
|
||||||
|
if (packet->bytes < 3) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdr = GST_READ_UINT24_LE (packet->packet);
|
||||||
|
|
||||||
|
is_kf = (hdr & 0x1);
|
||||||
|
return is_kf;
|
||||||
|
}
|
||||||
|
|
||||||
static gint64
|
static gint64
|
||||||
granulepos_to_granule_vp8 (GstOggStream * pad, gint64 gpos)
|
granulepos_to_granule_vp8 (GstOggStream * pad, gint64 gpos)
|
||||||
{
|
{
|
||||||
|
@ -2576,7 +2592,7 @@ const GstOggMap mappers[] = {
|
||||||
granulepos_to_granule_vp8,
|
granulepos_to_granule_vp8,
|
||||||
granule_to_granulepos_vp8,
|
granule_to_granulepos_vp8,
|
||||||
is_keyframe_vp8,
|
is_keyframe_vp8,
|
||||||
NULL,
|
is_packet_keyframe_vp8,
|
||||||
is_header_vp8,
|
is_header_vp8,
|
||||||
packet_duration_vp8,
|
packet_duration_vp8,
|
||||||
granulepos_to_key_granule_vp8,
|
granulepos_to_key_granule_vp8,
|
||||||
|
|
Loading…
Reference in a new issue