mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-27 10:40:34 +00:00
codecs: h264dec: Check bumping again after inserting current picture.
In order to get the lowest latency, we can add another bumping check after inserting the current picture into the DPB immediately. That can avoid waiting for another decoding circle of the next frame and so the latency is lower. Fix: #1628 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2501>
This commit is contained in:
parent
28eb729b53
commit
162026961b
1 changed files with 28 additions and 27 deletions
|
@ -900,6 +900,26 @@ add_picture_to_dpb (GstH264Decoder * self, GstH264Picture * picture)
|
|||
gst_h264_dpb_add (priv->dpb, picture);
|
||||
}
|
||||
|
||||
static void
|
||||
_bump_dpb (GstH264Decoder * self, GstH264DpbBumpMode bump_level,
|
||||
GstH264Picture * current_picture)
|
||||
{
|
||||
GstH264DecoderPrivate *priv = self->priv;
|
||||
|
||||
while (gst_h264_dpb_needs_bump (priv->dpb, current_picture, bump_level)) {
|
||||
GstH264Picture *to_output;
|
||||
|
||||
to_output = gst_h264_dpb_bump (priv->dpb, FALSE);
|
||||
|
||||
if (!to_output) {
|
||||
GST_WARNING_OBJECT (self, "Bumping is needed but no picture to output");
|
||||
break;
|
||||
}
|
||||
|
||||
gst_h264_decoder_do_output_picture (self, to_output);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_h264_decoder_handle_frame_num_gap (GstH264Decoder * self, gint frame_num)
|
||||
{
|
||||
|
@ -964,19 +984,7 @@ gst_h264_decoder_handle_frame_num_gap (GstH264Decoder * self, gint frame_num)
|
|||
|
||||
gst_h264_dpb_delete_unused (priv->dpb);
|
||||
|
||||
while (gst_h264_dpb_needs_bump (priv->dpb, picture,
|
||||
GST_H264_DPB_BUMP_NORMAL_LATENCY)) {
|
||||
GstH264Picture *to_output;
|
||||
|
||||
to_output = gst_h264_dpb_bump (priv->dpb, FALSE);
|
||||
|
||||
if (!to_output) {
|
||||
GST_WARNING_OBJECT (self, "Bumping is needed but no picture to output");
|
||||
break;
|
||||
}
|
||||
|
||||
gst_h264_decoder_do_output_picture (self, to_output);
|
||||
}
|
||||
_bump_dpb (self, GST_H264_DPB_BUMP_NORMAL_LATENCY, picture);
|
||||
|
||||
/* the picture is short term ref, add to DPB. */
|
||||
if (gst_h264_dpb_get_interlaced (priv->dpb)) {
|
||||
|
@ -2051,7 +2059,7 @@ gst_h264_decoder_finish_picture (GstH264Decoder * self,
|
|||
GstVideoDecoder *decoder = GST_VIDEO_DECODER (self);
|
||||
GstH264DecoderPrivate *priv = self->priv;
|
||||
gboolean ret = TRUE;
|
||||
GstH264DpbBumpMode bump_level;
|
||||
GstH264DpbBumpMode bump_level = get_bump_level (self);
|
||||
|
||||
/* Finish processing the picture.
|
||||
* Start by storing previous picture data for later use */
|
||||
|
@ -2091,19 +2099,7 @@ gst_h264_decoder_finish_picture (GstH264Decoder * self,
|
|||
gst_h264_decoder_drain_internal (self);
|
||||
}
|
||||
|
||||
bump_level = get_bump_level (self);
|
||||
while (gst_h264_dpb_needs_bump (priv->dpb, picture, bump_level)) {
|
||||
GstH264Picture *to_output;
|
||||
|
||||
to_output = gst_h264_dpb_bump (priv->dpb, FALSE);
|
||||
|
||||
if (!to_output) {
|
||||
GST_WARNING_OBJECT (self, "Bumping is needed but no picture to output");
|
||||
break;
|
||||
}
|
||||
|
||||
gst_h264_decoder_do_output_picture (self, to_output);
|
||||
}
|
||||
_bump_dpb (self, bump_level, picture);
|
||||
|
||||
/* Add a ref to avoid the case of directly outputed and destroyed. */
|
||||
gst_h264_picture_ref (picture);
|
||||
|
@ -2153,6 +2149,11 @@ gst_h264_decoder_finish_picture (GstH264Decoder * self,
|
|||
|
||||
gst_h264_picture_unref (picture);
|
||||
|
||||
/* For the live mode, we try to bump here to avoid waiting
|
||||
for another decoding circle. */
|
||||
if (priv->is_live && priv->compliance != GST_H264_DECODER_COMPLIANCE_STRICT)
|
||||
_bump_dpb (self, bump_level, NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue