diff mbox series

[FFmpeg-devel,06/10] avcodec/evc_parse: split off deriving PoC

Message ID 20230617220015.12669-3-jamrial@gmail.com
State Accepted
Commit ff7a4cdf04fcd0bc8deab540fe83f789fcf99301
Headers show
Series [FFmpeg-devel,1/3] avcodec/evc_frame_merge: use av_fast_realloc() | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 fail Make fate failed
andriy/make_x86 success Make finished
andriy/make_fate_x86 fail Make fate failed

Commit Message

James Almer June 17, 2023, 10 p.m. UTC
Signed-off-by: James Almer <jamrial@gmail.com>
---
 libavcodec/evc_parse.c | 142 +++++++++++++++++++++--------------------
 libavcodec/evc_parse.h |   5 ++
 2 files changed, 79 insertions(+), 68 deletions(-)
diff mbox series

Patch

diff --git a/libavcodec/evc_parse.c b/libavcodec/evc_parse.c
index 1fe58c8050..262ef5aa39 100644
--- a/libavcodec/evc_parse.c
+++ b/libavcodec/evc_parse.c
@@ -187,6 +187,77 @@  static int evc_parse_slice_header(EVCParserContext *ctx, EVCParserSliceHeader *s
     return 0;
 }
 
+int ff_evc_derive_poc(const EVCParamSets *ps, const EVCParserSliceHeader *sh,
+                      EVCParserPoc *poc, enum EVCNALUnitType nalu_type, int tid)
+{
+    const EVCParserPPS *pps = ps->pps[sh->slice_pic_parameter_set_id];
+    const EVCParserSPS *sps;
+
+    if (!pps)
+        return AVERROR_INVALIDDATA;
+
+    sps = ps->sps[pps->pps_seq_parameter_set_id];
+    if (!sps)
+        return AVERROR_INVALIDDATA;
+
+    if (sps->sps_pocs_flag) {
+        int PicOrderCntMsb = 0;
+        poc->prevPicOrderCntVal = poc->PicOrderCntVal;
+
+        if (nalu_type == EVC_IDR_NUT)
+            PicOrderCntMsb = 0;
+        else {
+            int MaxPicOrderCntLsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
+            int prevPicOrderCntLsb = poc->PicOrderCntVal & (MaxPicOrderCntLsb - 1);
+            int prevPicOrderCntMsb = poc->PicOrderCntVal - prevPicOrderCntLsb;
+
+            if ((sh->slice_pic_order_cnt_lsb < prevPicOrderCntLsb) &&
+                ((prevPicOrderCntLsb - sh->slice_pic_order_cnt_lsb) >= (MaxPicOrderCntLsb / 2)))
+                PicOrderCntMsb = prevPicOrderCntMsb + MaxPicOrderCntLsb;
+            else if ((sh->slice_pic_order_cnt_lsb > prevPicOrderCntLsb) &&
+                     ((sh->slice_pic_order_cnt_lsb - prevPicOrderCntLsb) > (MaxPicOrderCntLsb / 2)))
+                PicOrderCntMsb = prevPicOrderCntMsb - MaxPicOrderCntLsb;
+            else
+                PicOrderCntMsb = prevPicOrderCntMsb;
+        }
+        poc->PicOrderCntVal = PicOrderCntMsb + sh->slice_pic_order_cnt_lsb;
+    } else {
+        if (nalu_type == EVC_IDR_NUT) {
+            poc->PicOrderCntVal = 0;
+            poc->DocOffset = -1;
+        } else {
+            int SubGopLength = (int)pow(2.0, sps->log2_sub_gop_length);
+            if (tid == 0) {
+                poc->PicOrderCntVal = poc->prevPicOrderCntVal + SubGopLength;
+                poc->DocOffset = 0;
+                poc->prevPicOrderCntVal = poc->PicOrderCntVal;
+            } else {
+                int ExpectedTemporalId;
+                int PocOffset;
+                int prevDocOffset = poc->DocOffset;
+
+                poc->DocOffset = (prevDocOffset + 1) % SubGopLength;
+                if (poc->DocOffset == 0) {
+                    poc->prevPicOrderCntVal += SubGopLength;
+                    ExpectedTemporalId = 0;
+                } else
+                    ExpectedTemporalId = 1 + (int)log2(poc->DocOffset);
+                while (tid != ExpectedTemporalId) {
+                    poc->DocOffset = (poc->DocOffset + 1) % SubGopLength;
+                    if (poc->DocOffset == 0)
+                        ExpectedTemporalId = 0;
+                    else
+                        ExpectedTemporalId = 1 + (int)log2(poc->DocOffset);
+                }
+                PocOffset = (int)(SubGopLength * ((2.0 * poc->DocOffset + 1) / (int)pow(2.0, tid) - 2));
+                poc->PicOrderCntVal = poc->prevPicOrderCntVal + PocOffset;
+            }
+        }
+    }
+
+    return 0;
+}
+
 int ff_evc_parse_nal_unit(EVCParserContext *ctx, const uint8_t *buf, int buf_size, void *logctx)
 {
     int nalu_type, nalu_size;
@@ -299,8 +370,6 @@  int ff_evc_parse_nal_unit(EVCParserContext *ctx, const uint8_t *buf, int buf_siz
     case EVC_IDR_NUT:   // Coded slice of a IDR or non-IDR picture
     case EVC_NOIDR_NUT: {
         EVCParserSliceHeader sh;
-        const EVCParserSPS *sps;
-        const EVCParserPPS *pps;
         int ret;
 
         ret = evc_parse_slice_header(ctx, &sh, data, nalu_size);
@@ -331,72 +400,9 @@  int ff_evc_parse_nal_unit(EVCParserContext *ctx, const uint8_t *buf, int buf_siz
 
         // POC (picture order count of the current picture) derivation
         // @see ISO/IEC 23094-1:2020(E) 8.3.1 Decoding process for picture order count
-        pps = ctx->ps.pps[sh.slice_pic_parameter_set_id];
-        sps = ctx->ps.sps[pps->pps_seq_parameter_set_id];
-        av_assert0(sps && pps);
-
-        if (sps->sps_pocs_flag) {
-
-            int PicOrderCntMsb = 0;
-            ctx->poc.prevPicOrderCntVal = ctx->poc.PicOrderCntVal;
-
-            if (nalu_type == EVC_IDR_NUT)
-                PicOrderCntMsb = 0;
-            else {
-                int MaxPicOrderCntLsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
-
-                int prevPicOrderCntLsb = ctx->poc.PicOrderCntVal & (MaxPicOrderCntLsb - 1);
-                int prevPicOrderCntMsb = ctx->poc.PicOrderCntVal - prevPicOrderCntLsb;
-
-
-                if ((sh.slice_pic_order_cnt_lsb < prevPicOrderCntLsb) &&
-                    ((prevPicOrderCntLsb - sh.slice_pic_order_cnt_lsb) >= (MaxPicOrderCntLsb / 2)))
-
-                    PicOrderCntMsb = prevPicOrderCntMsb + MaxPicOrderCntLsb;
-
-                else if ((sh.slice_pic_order_cnt_lsb > prevPicOrderCntLsb) &&
-                         ((sh.slice_pic_order_cnt_lsb - prevPicOrderCntLsb) > (MaxPicOrderCntLsb / 2)))
-
-                    PicOrderCntMsb = prevPicOrderCntMsb - MaxPicOrderCntLsb;
-
-                else
-                    PicOrderCntMsb = prevPicOrderCntMsb;
-            }
-            ctx->poc.PicOrderCntVal = PicOrderCntMsb + sh.slice_pic_order_cnt_lsb;
-
-        } else {
-            if (nalu_type == EVC_IDR_NUT) {
-                ctx->poc.PicOrderCntVal = 0;
-                ctx->poc.DocOffset = -1;
-            } else {
-                int SubGopLength = (int)pow(2.0, sps->log2_sub_gop_length);
-                if (tid == 0) {
-                    ctx->poc.PicOrderCntVal = ctx->poc.prevPicOrderCntVal + SubGopLength;
-                    ctx->poc.DocOffset = 0;
-                    ctx->poc.prevPicOrderCntVal = ctx->poc.PicOrderCntVal;
-                } else {
-                    int ExpectedTemporalId;
-                    int PocOffset;
-                    int prevDocOffset = ctx->poc.DocOffset;
-
-                    ctx->poc.DocOffset = (prevDocOffset + 1) % SubGopLength;
-                    if (ctx->poc.DocOffset == 0) {
-                        ctx->poc.prevPicOrderCntVal += SubGopLength;
-                        ExpectedTemporalId = 0;
-                    } else
-                        ExpectedTemporalId = 1 + (int)log2(ctx->poc.DocOffset);
-                    while (tid != ExpectedTemporalId) {
-                        ctx->poc.DocOffset = (ctx->poc.DocOffset + 1) % SubGopLength;
-                        if (ctx->poc.DocOffset == 0)
-                            ExpectedTemporalId = 0;
-                        else
-                            ExpectedTemporalId = 1 + (int)log2(ctx->poc.DocOffset);
-                    }
-                    PocOffset = (int)(SubGopLength * ((2.0 * ctx->poc.DocOffset + 1) / (int)pow(2.0, tid) - 2));
-                    ctx->poc.PicOrderCntVal = ctx->poc.prevPicOrderCntVal + PocOffset;
-                }
-            }
-        }
+        ret = ff_evc_derive_poc(&ctx->ps, &sh, &ctx->poc, nalu_type, tid);
+        if (ret < 0)
+            return ret;
 
         ctx->output_picture_number = ctx->poc.PicOrderCntVal;
         ctx->key_frame = (nalu_type == EVC_IDR_NUT) ? 1 : 0;
diff --git a/libavcodec/evc_parse.h b/libavcodec/evc_parse.h
index 2748f8dfbf..97825efcd5 100644
--- a/libavcodec/evc_parse.h
+++ b/libavcodec/evc_parse.h
@@ -159,4 +159,9 @@  int ff_evc_get_temporal_id(const uint8_t *bits, int bits_size, void *logctx);
 
 int ff_evc_parse_nal_unit(EVCParserContext *ctx, const uint8_t *buf, int buf_size, void *logctx);
 
+// POC (picture order count of the current picture) derivation
+// @see ISO/IEC 23094-1:2020(E) 8.3.1 Decoding process for picture order count
+int ff_evc_derive_poc(const EVCParamSets *ps, const EVCParserSliceHeader *sh,
+                      EVCParserPoc *poc, enum EVCNALUnitType nalu_type, int tid);
+
 #endif /* AVCODEC_EVC_PARSE_H */