codecs: Signal required DPB size for AV1,MPEG2,VP8, and VP9 via new_sequence()

Make all codecs consistent so that subclass can know additional DPB
size requirement depending on render-delay configuration regardless
of codec. Note that render-delay feature is not implemented for AV1
yet but it's planned.

Also, consider new_sequence() is mandatory requirement, not optional

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2343>
This commit is contained in:
Seungha Yang 2022-04-28 04:25:05 +09:00 committed by GStreamer Marge Bot
parent 2eee3f4ca4
commit 6a4c42c03f
21 changed files with 67 additions and 42 deletions

View file

@ -273,7 +273,8 @@ gst_av1_decoder_process_sequence (GstAV1Decoder * self, GstAV1OBU * obu)
priv->max_width, priv->max_height, seq_header.max_frame_width_minus_1 + 1,
seq_header.max_frame_height_minus_1 + 1);
ret = klass->new_sequence (self, &seq_header);
/* TODO: Implement render delay */
ret = klass->new_sequence (self, &seq_header, GST_AV1_TOTAL_REFS_PER_FRAME);
if (ret != GST_FLOW_OK) {
GST_ERROR_OBJECT (self, "subclass does not want accept new sequence");
return ret;

View file

@ -70,13 +70,16 @@ struct _GstAV1DecoderClass
* GstAV1DecoderClass::new_sequence:
* @decoder: a #GstAV1Decoder
* @seq_hdr: a #GstAV1SequenceHeaderOBU
* @max_dpb_size: the size of dpb including preferred output delay
* by subclass reported via get_preferred_output_delay method.
*
* Notifies subclass of SPS update
*
* Since: 1.20
*/
GstFlowReturn (*new_sequence) (GstAV1Decoder * decoder,
const GstAV1SequenceHeaderOBU * seq_hdr);
const GstAV1SequenceHeaderOBU * seq_hdr,
gint max_dpb_size);
/**
* GstAV1DecoderClass::new_picture:
* @decoder: a #GstAV1Decoder

View file

@ -741,6 +741,8 @@ gst_mpeg2_decoder_handle_picture (GstMpeg2Decoder * decoder,
GstMpegVideoPictureHdr pic_hdr = { 0, };
GstMpeg2DecoderClass *klass = GST_MPEG2_DECODER_GET_CLASS (decoder);
g_assert (klass->new_sequence);
if (!_is_valid_state (decoder, GST_MPEG2_DECODER_STATE_VALID_SEQ_HEADERS)) {
GST_ERROR_OBJECT (decoder, "no sequence before parsing picture header");
return GST_FLOW_ERROR;
@ -767,26 +769,29 @@ gst_mpeg2_decoder_handle_picture (GstMpeg2Decoder * decoder,
priv->need_to_drain = FALSE;
}
if (klass->get_preferred_output_delay)
if (klass->get_preferred_output_delay) {
priv->preferred_output_delay =
klass->get_preferred_output_delay (decoder, priv->is_live);
} else {
priv->preferred_output_delay = 0;
}
priv->seq_changed = FALSE;
if (klass->new_sequence) {
ret = klass->new_sequence (decoder, &priv->seq_hdr,
_seq_ext_is_valid (&priv->seq_ext) ? &priv->seq_ext : NULL,
_seq_display_ext_is_valid (&priv->seq_display_ext) ?
&priv->seq_display_ext : NULL,
_seq_scalable_ext_is_valid (&priv->seq_scalable_ext) ?
&priv->seq_scalable_ext : NULL);
&priv->seq_scalable_ext : NULL,
/* previous/next 2 pictures */
2 + priv->preferred_output_delay);
if (ret != GST_FLOW_OK) {
GST_WARNING_OBJECT (decoder, "new sequence error");
return ret;
}
}
}
priv->state &= (GST_MPEG2_DECODER_STATE_GOT_SEQ_HDR |
GST_MPEG2_DECODER_STATE_GOT_SEQ_EXT);

View file

@ -73,6 +73,8 @@ struct _GstMpeg2DecoderClass
* @decoder: a #GstMpeg2Decoder
* @seq: a #GstMpegVideoSequenceHdr
* @seq_ext: a #GstMpegVideoSequenceExt
* @max_dpb_size: the size of dpb including preferred output delay
* by subclass reported via get_preferred_output_delay method.
*
* Notifies subclass of SPS update
*
@ -82,7 +84,8 @@ struct _GstMpeg2DecoderClass
const GstMpegVideoSequenceHdr * seq,
const GstMpegVideoSequenceExt * seq_ext,
const GstMpegVideoSequenceDisplayExt * seq_display_ext,
const GstMpegVideoSequenceScalableExt * seq_scalable_ext);
const GstMpegVideoSequenceScalableExt * seq_scalable_ext,
gint max_dpb_size);
/**
* GstMpeg2DecoderClass::new_picture:

View file

@ -178,14 +178,18 @@ gst_vp8_decoder_check_codec_change (GstVp8Decoder * self,
priv->had_sequence = TRUE;
if (klass->get_preferred_output_delay)
if (klass->get_preferred_output_delay) {
priv->preferred_output_delay =
klass->get_preferred_output_delay (self, priv->is_live);
else
} else {
priv->preferred_output_delay = 0;
}
if (klass->new_sequence)
ret = klass->new_sequence (self, frame_hdr);
g_assert (klass->new_sequence);
ret = klass->new_sequence (self, frame_hdr,
/* last/golden/alt 3 pictures */
3 + priv->preferred_output_delay);
}
return ret;

View file

@ -89,7 +89,8 @@ struct _GstVp8DecoderClass
GstVideoDecoderClass parent_class;
GstFlowReturn (*new_sequence) (GstVp8Decoder * decoder,
const GstVp8FrameHdr * frame_hdr);
const GstVp8FrameHdr * frame_hdr,
gint max_dpb_size);
/**
* GstVp8DecoderClass:new_picture:

View file

@ -216,6 +216,8 @@ gst_vp9_decoder_check_codec_change (GstVp9Decoder * self,
GstVp9DecoderClass *klass = GST_VP9_DECODER_GET_CLASS (self);
GstFlowReturn ret = GST_FLOW_OK;
g_assert (klass->new_sequence);
if (priv->had_sequence && !gst_vp9_decoder_is_format_change (self, frame_hdr)) {
return GST_FLOW_OK;
}
@ -243,8 +245,8 @@ gst_vp9_decoder_check_codec_change (GstVp9Decoder * self,
priv->preferred_output_delay = 0;
}
if (klass->new_sequence)
ret = klass->new_sequence (self, frame_hdr);
ret = klass->new_sequence (self, frame_hdr,
GST_VP9_REF_FRAMES + priv->preferred_output_delay);
if (ret != GST_FLOW_OK)
priv->had_sequence = FALSE;

View file

@ -67,6 +67,10 @@ struct _GstVp9DecoderClass
/**
* GstVp9DecoderClass::new_sequence:
* @decoder: a #GstVp9Decoder
* @frame_hdr: a #GstVp9FrameHeader
* @max_dpb_size: the size of dpb including preferred output delay
* by subclass reported via get_preferred_output_delay method.
*
* Notifies subclass of video sequence update such as resolution, bitdepth,
* profile.
@ -74,7 +78,8 @@ struct _GstVp9DecoderClass
* Since: 1.18
*/
GstFlowReturn (*new_sequence) (GstVp9Decoder * decoder,
const GstVp9FrameHeader *frame_hdr);
const GstVp9FrameHeader *frame_hdr,
gint max_dpb_size);
/**
* GstVp9DecoderClass::new_picture:

View file

@ -423,7 +423,7 @@ static gboolean gst_d3d11_av1_dec_sink_event (GstVideoDecoder * decoder,
/* GstAV1Decoder */
static GstFlowReturn gst_d3d11_av1_dec_new_sequence (GstAV1Decoder * decoder,
const GstAV1SequenceHeaderOBU * seq_hdr);
const GstAV1SequenceHeaderOBU * seq_hdr, gint max_dpb_size);
static GstFlowReturn gst_d3d11_av1_dec_new_picture (GstAV1Decoder * decoder,
GstVideoCodecFrame * frame, GstAV1Picture * picture);
static GstAV1Picture *gst_d3d11_av1_dec_duplicate_picture (GstAV1Decoder *
@ -630,7 +630,7 @@ gst_d3d11_av1_dec_sink_event (GstVideoDecoder * decoder, GstEvent * event)
static GstFlowReturn
gst_d3d11_av1_dec_new_sequence (GstAV1Decoder * decoder,
const GstAV1SequenceHeaderOBU * seq_hdr)
const GstAV1SequenceHeaderOBU * seq_hdr, gint max_dpb_size)
{
GstD3D11AV1Dec *self = GST_D3D11_AV1_DEC (decoder);
GstD3D11AV1DecInner *inner = self->inner;

View file

@ -120,7 +120,8 @@ static GstFlowReturn gst_d3d11_mpeg2_dec_new_sequence (GstMpeg2Decoder *
decoder, const GstMpegVideoSequenceHdr * seq,
const GstMpegVideoSequenceExt * seq_ext,
const GstMpegVideoSequenceDisplayExt * seq_display_ext,
const GstMpegVideoSequenceScalableExt * seq_scalable_ext);
const GstMpegVideoSequenceScalableExt * seq_scalable_ext,
gint max_dpb_size);
static GstFlowReturn gst_d3d11_mpeg2_dec_new_picture (GstMpeg2Decoder * decoder,
GstVideoCodecFrame * frame, GstMpeg2Picture * picture);
static GstFlowReturn
@ -332,7 +333,7 @@ gst_d3d11_mpeg2_dec_new_sequence (GstMpeg2Decoder * decoder,
const GstMpegVideoSequenceHdr * seq,
const GstMpegVideoSequenceExt * seq_ext,
const GstMpegVideoSequenceDisplayExt * seq_display_ext,
const GstMpegVideoSequenceScalableExt * seq_scalable_ext)
const GstMpegVideoSequenceScalableExt * seq_scalable_ext, gint max_dpb_size)
{
GstD3D11Mpeg2Dec *self = GST_D3D11_MPEG2_DEC (decoder);
GstD3D11Mpeg2DecInner *inner = self->inner;

View file

@ -111,7 +111,7 @@ static gboolean gst_d3d11_vp8_sink_event (GstVideoDecoder * decoder,
/* GstVp8Decoder */
static GstFlowReturn gst_d3d11_vp8_dec_new_sequence (GstVp8Decoder * decoder,
const GstVp8FrameHdr * frame_hdr);
const GstVp8FrameHdr * frame_hdr, gint max_dpb_size);
static GstFlowReturn gst_d3d11_vp8_dec_new_picture (GstVp8Decoder * decoder,
GstVideoCodecFrame * frame, GstVp8Picture * picture);
static GstFlowReturn gst_d3d11_vp8_dec_start_picture (GstVp8Decoder * decoder,
@ -313,7 +313,7 @@ gst_d3d11_vp8_sink_event (GstVideoDecoder * decoder, GstEvent * event)
static GstFlowReturn
gst_d3d11_vp8_dec_new_sequence (GstVp8Decoder * decoder,
const GstVp8FrameHdr * frame_hdr)
const GstVp8FrameHdr * frame_hdr, gint max_dpb_size)
{
GstD3D11Vp8Dec *self = GST_D3D11_VP8_DEC (decoder);
GstD3D11Vp8DecInner *inner = self->inner;

View file

@ -143,7 +143,7 @@ static gboolean gst_d3d11_vp9_dec_sink_event (GstVideoDecoder * decoder,
/* GstVp9Decoder */
static GstFlowReturn gst_d3d11_vp9_dec_new_sequence (GstVp9Decoder * decoder,
const GstVp9FrameHeader * frame_hdr);
const GstVp9FrameHeader * frame_hdr, gint max_dpb_size);
static GstFlowReturn gst_d3d11_vp9_dec_new_picture (GstVp9Decoder * decoder,
GstVideoCodecFrame * frame, GstVp9Picture * picture);
static GstVp9Picture *gst_d3d11_vp9_dec_duplicate_picture (GstVp9Decoder *
@ -361,7 +361,7 @@ gst_d3d11_vp9_dec_sink_event (GstVideoDecoder * decoder, GstEvent * event)
static GstFlowReturn
gst_d3d11_vp9_dec_new_sequence (GstVp9Decoder * decoder,
const GstVp9FrameHeader * frame_hdr)
const GstVp9FrameHeader * frame_hdr, gint max_dpb_size)
{
GstD3D11Vp9Dec *self = GST_D3D11_VP9_DEC (decoder);
GstD3D11Vp9DecInner *inner = self->inner;

View file

@ -74,7 +74,7 @@ static gboolean gst_nv_vp8_dec_src_query (GstVideoDecoder * decoder,
/* GstVp8Decoder */
static GstFlowReturn gst_nv_vp8_dec_new_sequence (GstVp8Decoder * decoder,
const GstVp8FrameHdr * frame_hdr);
const GstVp8FrameHdr * frame_hdr, gint max_dpb_size);
static GstFlowReturn gst_nv_vp8_dec_new_picture (GstVp8Decoder * decoder,
GstVideoCodecFrame * frame, GstVp8Picture * picture);
static GstFlowReturn gst_nv_vp8_dec_decode_picture (GstVp8Decoder * decoder,
@ -232,7 +232,7 @@ gst_nv_vp8_dec_src_query (GstVideoDecoder * decoder, GstQuery * query)
static GstFlowReturn
gst_nv_vp8_dec_new_sequence (GstVp8Decoder * decoder,
const GstVp8FrameHdr * frame_hdr)
const GstVp8FrameHdr * frame_hdr, gint max_dpb_size)
{
GstNvVp8Dec *self = GST_NV_VP8_DEC (decoder);
gboolean modified = FALSE;

View file

@ -75,7 +75,7 @@ static gboolean gst_nv_vp9_dec_src_query (GstVideoDecoder * decoder,
/* GstVp9Decoder */
static GstFlowReturn gst_nv_vp9_dec_new_sequence (GstVp9Decoder * decoder,
const GstVp9FrameHeader * frame_hdr);
const GstVp9FrameHeader * frame_hdr, gint max_dpb_size);
static GstFlowReturn gst_nv_vp9_dec_new_picture (GstVp9Decoder * decoder,
GstVideoCodecFrame * frame, GstVp9Picture * picture);
static GstVp9Picture *gst_nv_vp9_dec_duplicate_picture (GstVp9Decoder *
@ -242,7 +242,7 @@ gst_nv_vp9_dec_src_query (GstVideoDecoder * decoder, GstQuery * query)
static GstFlowReturn
gst_nv_vp9_dec_new_sequence (GstVp9Decoder * decoder,
const GstVp9FrameHeader * frame_hdr)
const GstVp9FrameHeader * frame_hdr, gint max_dpb_size)
{
GstNvVp9Dec *self = GST_NV_VP9_DEC (decoder);
GstVideoFormat out_format = GST_VIDEO_FORMAT_UNKNOWN;

View file

@ -360,7 +360,7 @@ gst_v4l2_codec_mpeg2_dec_new_sequence (GstMpeg2Decoder * decoder,
const GstMpegVideoSequenceHdr * seq,
const GstMpegVideoSequenceExt * seq_ext,
const GstMpegVideoSequenceDisplayExt * seq_display_ext,
const GstMpegVideoSequenceScalableExt * seq_scalable_ext)
const GstMpegVideoSequenceScalableExt * seq_scalable_ext, gint max_dpb_size)
{
GstV4l2CodecMpeg2Dec *self = GST_V4L2_CODEC_MPEG2_DEC (decoder);
gboolean negotiation_needed = FALSE;

View file

@ -450,7 +450,7 @@ gst_v4l2_codec_vp8_dec_fill_references (GstV4l2CodecVp8Dec * self)
static GstFlowReturn
gst_v4l2_codec_vp8_dec_new_sequence (GstVp8Decoder * decoder,
const GstVp8FrameHdr * frame_hdr)
const GstVp8FrameHdr * frame_hdr, gint max_dpb_size)
{
GstV4l2CodecVp8Dec *self = GST_V4L2_CODEC_VP8_DEC (decoder);
gboolean negotiation_needed = FALSE;

View file

@ -580,7 +580,7 @@ gst_v4l2_codec_vp9_dec_decide_allocation (GstVideoDecoder * decoder,
static GstFlowReturn
gst_v4l2_codec_vp9_dec_new_sequence (GstVp9Decoder * decoder,
const GstVp9FrameHeader * frame_hdr)
const GstVp9FrameHeader * frame_hdr, gint max_dpb_size)
{
GstV4l2CodecVp9Dec *self = GST_V4L2_CODEC_VP9_DEC (decoder);
gboolean negotiation_needed = FALSE;

View file

@ -247,7 +247,7 @@ gst_va_av1_dec_getcaps (GstVideoDecoder * decoder, GstCaps * filter)
static GstFlowReturn
gst_va_av1_dec_new_sequence (GstAV1Decoder * decoder,
const GstAV1SequenceHeaderOBU * seq_hdr)
const GstAV1SequenceHeaderOBU * seq_hdr, gint max_dpb_size)
{
GstVaAV1Dec *self = GST_VA_AV1_DEC (decoder);
GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);

View file

@ -220,7 +220,7 @@ gst_va_mpeg2_dec_new_sequence (GstMpeg2Decoder * decoder,
const GstMpegVideoSequenceHdr * seq,
const GstMpegVideoSequenceExt * seq_ext,
const GstMpegVideoSequenceDisplayExt * seq_display_ext,
const GstMpegVideoSequenceScalableExt * seq_scalable_ext)
const GstMpegVideoSequenceScalableExt * seq_scalable_ext, gint max_dpb_size)
{
GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
GstVaMpeg2Dec *self = GST_VA_MPEG2_DEC (decoder);

View file

@ -143,7 +143,7 @@ _get_profile (GstVaVp8Dec * self, const GstVp8FrameHdr * frame_hdr)
static GstFlowReturn
gst_va_vp8_dec_new_sequence (GstVp8Decoder * decoder,
const GstVp8FrameHdr * frame_hdr)
const GstVp8FrameHdr * frame_hdr, gint max_dpb_size)
{
GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
GstVaVp8Dec *self = GST_VA_VP8_DEC (decoder);

View file

@ -145,7 +145,7 @@ _get_profile (GstVaVp9Dec * self, GstVP9Profile profile)
static GstFlowReturn
gst_va_vp9_new_sequence (GstVp9Decoder * decoder,
const GstVp9FrameHeader * frame_hdr)
const GstVp9FrameHeader * frame_hdr, gint max_dpb_size)
{
GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
GstVaVp9Dec *self = GST_VA_VP9_DEC (decoder);