mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 16:50:47 +00:00
codecs: mpeg2decoder: drain() only when significant sequence changes.
There are a lot of info in the mpeg2's sequence(also including ext display_ext and scalable_ext). We need to notify the subclass about its change, but not all the changes should trigger a drain(), which may change the output picture order. For example, the matrix changes in sequence header does not change the decoder context and so no need to trigger a drain(). Fixes: #899 Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1375>
This commit is contained in:
parent
2a17618dcc
commit
d867180b4e
1 changed files with 34 additions and 11 deletions
|
@ -246,6 +246,8 @@ struct _GstMpeg2DecoderPrivate
|
||||||
|
|
||||||
/* some sequence info changed after last new_sequence () */
|
/* some sequence info changed after last new_sequence () */
|
||||||
gboolean seq_changed;
|
gboolean seq_changed;
|
||||||
|
/* whether we need to drain before new_sequence () */
|
||||||
|
gboolean need_to_drain;
|
||||||
GstMpegVideoGop gop;
|
GstMpegVideoGop gop;
|
||||||
GstMpegVideoQuantMatrixExt quant_matrix;
|
GstMpegVideoQuantMatrixExt quant_matrix;
|
||||||
GstMpegVideoPictureHdr pic_hdr;
|
GstMpegVideoPictureHdr pic_hdr;
|
||||||
|
@ -512,8 +514,11 @@ gst_mpeg2_decoder_handle_sequence (GstMpeg2Decoder * decoder,
|
||||||
priv->seq_hdr = seq_hdr;
|
priv->seq_hdr = seq_hdr;
|
||||||
priv->seq_changed = TRUE;
|
priv->seq_changed = TRUE;
|
||||||
|
|
||||||
priv->width = seq_hdr.width;
|
if (priv->width != seq_hdr.width || priv->height != seq_hdr.height) {
|
||||||
priv->height = seq_hdr.height;
|
priv->need_to_drain = TRUE;
|
||||||
|
priv->width = seq_hdr.width;
|
||||||
|
priv->height = seq_hdr.height;
|
||||||
|
}
|
||||||
priv->display_width = priv->width;
|
priv->display_width = priv->width;
|
||||||
priv->display_height = priv->height;
|
priv->display_height = priv->height;
|
||||||
|
|
||||||
|
@ -551,8 +556,6 @@ gst_mpeg2_decoder_handle_sequence_ext (GstMpeg2Decoder * decoder,
|
||||||
priv->seq_ext = seq_ext;
|
priv->seq_ext = seq_ext;
|
||||||
priv->seq_changed = TRUE;
|
priv->seq_changed = TRUE;
|
||||||
|
|
||||||
priv->progressive = seq_ext.progressive;
|
|
||||||
|
|
||||||
if (seq_ext.fps_n_ext && seq_ext.fps_d_ext) {
|
if (seq_ext.fps_n_ext && seq_ext.fps_d_ext) {
|
||||||
guint fps_n = priv->tsg.fps_n;
|
guint fps_n = priv->tsg.fps_n;
|
||||||
guint fps_d = priv->tsg.fps_d;
|
guint fps_d = priv->tsg.fps_d;
|
||||||
|
@ -564,11 +567,20 @@ gst_mpeg2_decoder_handle_sequence_ext (GstMpeg2Decoder * decoder,
|
||||||
|
|
||||||
width = (priv->width & 0x0fff) | ((guint32) seq_ext.horiz_size_ext << 12);
|
width = (priv->width & 0x0fff) | ((guint32) seq_ext.horiz_size_ext << 12);
|
||||||
height = (priv->height & 0x0fff) | ((guint32) seq_ext.vert_size_ext << 12);
|
height = (priv->height & 0x0fff) | ((guint32) seq_ext.vert_size_ext << 12);
|
||||||
GST_DEBUG_OBJECT (decoder, "video resolution %ux%u", width, height);
|
|
||||||
priv->width = width;
|
|
||||||
priv->height = height;
|
|
||||||
|
|
||||||
priv->profile = seq_ext.profile;
|
if (priv->width != width || priv->height != height ||
|
||||||
|
priv->profile != seq_ext.profile ||
|
||||||
|
priv->progressive != seq_ext.progressive) {
|
||||||
|
priv->need_to_drain = TRUE;
|
||||||
|
priv->width = width;
|
||||||
|
priv->height = height;
|
||||||
|
priv->profile = seq_ext.profile;
|
||||||
|
priv->progressive = seq_ext.progressive;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (decoder, "video resolution %ux%u, profile %d,"
|
||||||
|
" progressive %d", priv->width, priv->height, priv->profile,
|
||||||
|
priv->progressive);
|
||||||
|
}
|
||||||
|
|
||||||
priv->state |= GST_MPEG2_DECODER_STATE_GOT_SEQ_EXT;
|
priv->state |= GST_MPEG2_DECODER_STATE_GOT_SEQ_EXT;
|
||||||
|
|
||||||
|
@ -734,15 +746,26 @@ gst_mpeg2_decoder_handle_picture (GstMpeg2Decoder * decoder,
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If need_to_drain, we must have sequence changed. */
|
||||||
|
g_assert (priv->need_to_drain ? priv->seq_changed : TRUE);
|
||||||
|
|
||||||
/* 6.1.1.6: Conversely if no sequence_xxx_extension() occurs between
|
/* 6.1.1.6: Conversely if no sequence_xxx_extension() occurs between
|
||||||
the first sequence_header() and the first picture_header() then
|
the first sequence_header() and the first picture_header() then
|
||||||
sequence_xxx_extension() shall not occur in the bitstream. */
|
sequence_xxx_extension() shall not occur in the bitstream. */
|
||||||
if (priv->seq_changed) {
|
if (priv->seq_changed) {
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
|
|
||||||
ret = gst_mpeg2_decoder_drain (GST_VIDEO_DECODER (decoder));
|
/* There are a lot of info in the mpeg2's sequence(also including ext
|
||||||
if (ret != GST_FLOW_OK)
|
display_ext and scalable_ext). We need to notify the subclass about
|
||||||
return ret;
|
its change, but not all the changes should trigger a drain(), which
|
||||||
|
may change the output picture order. */
|
||||||
|
if (priv->need_to_drain) {
|
||||||
|
ret = gst_mpeg2_decoder_drain (GST_VIDEO_DECODER (decoder));
|
||||||
|
if (ret != GST_FLOW_OK)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
priv->need_to_drain = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (klass->get_preferred_output_delay)
|
if (klass->get_preferred_output_delay)
|
||||||
priv->preferred_output_delay =
|
priv->preferred_output_delay =
|
||||||
|
|
Loading…
Reference in a new issue