summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHe Junyan <junyan.he@intel.com>2021-08-31 17:16:05 +0800
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>2021-09-15 13:20:28 +0000
commit162026961bff14dbf8198fb556b83a2f655f4c4b (patch)
tree149a5b22cdccc931986b516caf4da7d25b83bab0
parent28eb729b53c8fc4d5fb67994a5f3d7ac84cbce9d (diff)
downloadgstreamer-plugins-bad-162026961bff14dbf8198fb556b83a2f655f4c4b.tar.gz
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>
-rw-r--r--gst-libs/gst/codecs/gsth264decoder.c55
1 files changed, 28 insertions, 27 deletions
diff --git a/gst-libs/gst/codecs/gsth264decoder.c b/gst-libs/gst/codecs/gsth264decoder.c
index e3f7cab31..a1b5c36e4 100644
--- a/gst-libs/gst/codecs/gsth264decoder.c
+++ b/gst-libs/gst/codecs/gsth264decoder.c
@@ -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;
}