mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-18 15:51:11 +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/4745>
This commit is contained in:
parent
781606c976
commit
da02436193
5 changed files with 33 additions and 3 deletions
|
@ -948,6 +948,7 @@ validate.test.mse.segment_future_past_nomse.segment_future_past_nomse
|
|||
validate.test.nle.urisource.play
|
||||
validate.test.playbin.check_active_stream
|
||||
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.rtp.h264.payloader_fail_nego_force_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) ||
|
||||
packet->b_o_s ||
|
||||
(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 */
|
||||
goto done;
|
||||
}
|
||||
|
@ -818,9 +821,11 @@ gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet,
|
|||
if (delta_unit)
|
||||
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
|
||||
|
||||
/* set header flag for buffers that are also in the streamheaders */
|
||||
if (is_header)
|
||||
/* set header flag for buffers that are also in the streamheaders or when explicitely requested (VP8). */
|
||||
if (is_header || pad->need_header_flag) {
|
||||
pad->need_header_flag = FALSE;
|
||||
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
|
||||
}
|
||||
|
||||
if (packet->packet != NULL) {
|
||||
/* copy packet in buffer */
|
||||
|
|
|
@ -102,6 +102,8 @@ struct _GstOggPad
|
|||
|
||||
GList *continued;
|
||||
|
||||
gboolean need_header_flag;
|
||||
|
||||
gboolean discont;
|
||||
GstFlowReturn last_ret; /* last return of _pad_push() */
|
||||
gboolean is_eos;
|
||||
|
|
|
@ -761,6 +761,22 @@ is_keyframe_vp8 (GstOggStream * pad, gint64 granulepos)
|
|||
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
|
||||
granulepos_to_granule_vp8 (GstOggStream * pad, gint64 gpos)
|
||||
{
|
||||
|
@ -2576,7 +2592,7 @@ const GstOggMap mappers[] = {
|
|||
granulepos_to_granule_vp8,
|
||||
granule_to_granulepos_vp8,
|
||||
is_keyframe_vp8,
|
||||
NULL,
|
||||
is_packet_keyframe_vp8,
|
||||
is_header_vp8,
|
||||
packet_duration_vp8,
|
||||
granulepos_to_key_granule_vp8,
|
||||
|
|
Loading…
Reference in a new issue