summaryrefslogtreecommitdiff
path: root/gst-libs
diff options
context:
space:
mode:
authorMengkejiergeli Ba <mengkejiergeli.ba@intel.com>2021-08-20 13:28:51 +0800
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>2021-08-27 15:27:31 +0000
commit702e69e8417822e1cfefc8e2f6515c358ecb7bd4 (patch)
treebdda658dc46d052f57adb37549393ac7ce664633 /gst-libs
parentfd1e75900db48fc008899c5712a39ca16a0681b0 (diff)
downloadgstreamer-plugins-bad-702e69e8417822e1cfefc8e2f6515c358ecb7bd4.tar.gz
codecs: av1dec: Fix to output frame with highest spatial layer
During the output process, if there are multiple frames in a TU (i.e. multi-spatial layers case), only one frame with the highest spatial layer id should be selected according to av1 spec. The highest spatial layer id is obtained from idc value of the operating point. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2475>
Diffstat (limited to 'gst-libs')
-rw-r--r--gst-libs/gst/codecs/gstav1decoder.c28
1 files changed, 25 insertions, 3 deletions
diff --git a/gst-libs/gst/codecs/gstav1decoder.c b/gst-libs/gst/codecs/gstav1decoder.c
index 68578e0b4..7f7b4141f 100644
--- a/gst-libs/gst/codecs/gstav1decoder.c
+++ b/gst-libs/gst/codecs/gstav1decoder.c
@@ -52,6 +52,18 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstAV1Decoder, gst_av1_decoder,
GST_DEBUG_CATEGORY_INIT (gst_av1_decoder_debug, "av1decoder", 0,
"AV1 Video Decoder"));
+static gint
+_floor_log2 (guint32 x)
+{
+ gint s = 0;
+
+ while (x != 0) {
+ x = x >> 1;
+ s++;
+ }
+ return s - 1;
+}
+
static gboolean gst_av1_decoder_start (GstVideoDecoder * decoder);
static gboolean gst_av1_decoder_stop (GstVideoDecoder * decoder);
static gboolean gst_av1_decoder_set_format (GstVideoDecoder * decoder,
@@ -591,9 +603,19 @@ out:
if (ret == GST_FLOW_OK) {
if (priv->current_picture->frame_hdr.show_frame ||
priv->current_picture->frame_hdr.show_existing_frame) {
- g_assert (klass->output_picture);
- /* transfer ownership of frame and picture */
- ret = klass->output_picture (self, frame, priv->current_picture);
+ /* Only output one frame with the highest spatial id from each TU
+ * when there are multiple spatial layers.
+ */
+ if (priv->parser->state.operating_point_idc &&
+ obu.header.obu_spatial_id <
+ _floor_log2 (priv->parser->state.operating_point_idc >> 8)) {
+ gst_av1_picture_unref (priv->current_picture);
+ gst_video_decoder_release_frame (decoder, frame);
+ } else {
+ g_assert (klass->output_picture);
+ /* transfer ownership of frame and picture */
+ ret = klass->output_picture (self, frame, priv->current_picture);
+ }
} else {
GST_LOG_OBJECT (self, "Decode only picture %p", priv->current_picture);
GST_VIDEO_CODEC_FRAME_SET_DECODE_ONLY (frame);