diff mbox series

[FFmpeg-devel,7/7] lavc/hevc: update reference list for SCC

Message ID 1594311460-10498-8-git-send-email-linjie.fu@intel.com
State New
Headers show
Series HEVC native support for Screen content coding | expand

Checks

Context Check Description
andriy/default pending
andriy/make success Make finished
andriy/make_fate success Make fate finished

Commit Message

Fu, Linjie July 9, 2020, 4:17 p.m. UTC
Screen Content Coding allows P slice in an IDR frame, and would add
frames themselves to the short term rps in RefList0 (8-10 in spec),
hence some previous restricts are not suitable any more.

[Request for comments].

Signed-off-by: Linjie Fu <linjie.justin.fu@gmail.com>
---
 libavcodec/hevc_refs.c | 21 +++++++++++++++++++--
 libavcodec/hevcdec.c   |  5 +++--
 2 files changed, 22 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c
index 4f6d985..13a7bf6 100644
--- a/libavcodec/hevc_refs.c
+++ b/libavcodec/hevc_refs.c
@@ -301,7 +301,7 @@  int ff_hevc_slice_rpl(HEVCContext *s)
         return ret;
 
     if (!(s->rps[ST_CURR_BEF].nb_refs + s->rps[ST_CURR_AFT].nb_refs +
-          s->rps[LT_CURR].nb_refs)) {
+          s->rps[LT_CURR].nb_refs) && !s->ps.pps->pps_curr_pic_ref_enabled_flag) {
         av_log(s->avctx, AV_LOG_ERROR, "Zero refs in the frame RPS.\n");
         return AVERROR_INVALIDDATA;
     }
@@ -328,6 +328,12 @@  int ff_hevc_slice_rpl(HEVCContext *s)
                     rpl_tmp.nb_refs++;
                 }
             }
+
+            if (s->ps.pps->pps_curr_pic_ref_enabled_flag) {
+                rpl_tmp.ref[rpl_tmp.nb_refs]            = s->ref;
+                rpl_tmp.isLongTerm[rpl_tmp.nb_refs]     = 0;
+                rpl_tmp.nb_refs++;
+            }
         }
 
         /* reorder the references if necessary */
@@ -423,7 +429,8 @@  static int add_candidate_ref(HEVCContext *s, RefPicList *list,
 {
     HEVCFrame *ref = find_ref_idx(s, poc, use_msb);
 
-    if (ref == s->ref || list->nb_refs >= HEVC_MAX_REFS)
+    if ((ref == s->ref && !s->ps.pps->pps_curr_pic_ref_enabled_flag) ||
+        list->nb_refs >= HEVC_MAX_REFS)
         return AVERROR_INVALIDDATA;
 
     if (!ref) {
@@ -482,6 +489,12 @@  int ff_hevc_frame_rps(HEVCContext *s)
             goto fail;
     }
 
+    if (s->ps.pps->pps_curr_pic_ref_enabled_flag) {
+        ret = add_candidate_ref(s, &rps[ST_FOLL], s->poc, HEVC_FRAME_FLAG_SHORT_REF, 1);
+        if (ret < 0)
+            goto fail;
+    }
+
     /* add the long refs */
     for (i = 0; i < long_rps->nb_refs; i++) {
         int poc  = long_rps->poc[i];
@@ -518,5 +531,9 @@  int ff_hevc_frame_nb_refs(const HEVCContext *s)
         for (i = 0; i < long_rps->nb_refs; i++)
             ret += !!long_rps->used[i];
     }
+
+    if (s->ps.pps->pps_curr_pic_ref_enabled_flag)
+        ret++;
+
     return ret;
 }
diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
index fc8a77d..d7a10c4 100644
--- a/libavcodec/hevcdec.c
+++ b/libavcodec/hevcdec.c
@@ -617,7 +617,8 @@  static int hls_slice_header(HEVCContext *s)
                    sh->slice_type);
             return AVERROR_INVALIDDATA;
         }
-        if (IS_IRAP(s) && sh->slice_type != HEVC_SLICE_I) {
+        if (IS_IRAP(s) && sh->slice_type != HEVC_SLICE_I &&
+            s->ps.sps->ptl.general_ptl.profile_idc != FF_PROFILE_HEVC_SCC) {
             av_log(s->avctx, AV_LOG_ERROR, "Inter slices in an IRAP frame.\n");
             return AVERROR_INVALIDDATA;
         }
@@ -729,7 +730,7 @@  static int hls_slice_header(HEVCContext *s)
             sh->rpl_modification_flag[0] = 0;
             sh->rpl_modification_flag[1] = 0;
             nb_refs = ff_hevc_frame_nb_refs(s);
-            if (!nb_refs) {
+            if (!nb_refs && !s->ps.pps->pps_curr_pic_ref_enabled_flag) {
                 av_log(s->avctx, AV_LOG_ERROR, "Zero refs for a frame with P or B slices.\n");
                 return AVERROR_INVALIDDATA;
             }