[FFmpeg-cvslog] avcodec/evc_parse: split off deriving PoC
James Almer
git at videolan.org
Mon Jun 19 21:51:36 EEST 2023
ffmpeg | branch: master | James Almer <jamrial at gmail.com> | Sat Jun 17 17:18:04 2023 -0300| [ff7a4cdf04fcd0bc8deab540fe83f789fcf99301] | committer: James Almer
avcodec/evc_parse: split off deriving PoC
Signed-off-by: James Almer <jamrial at gmail.com>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=ff7a4cdf04fcd0bc8deab540fe83f789fcf99301
---
libavcodec/evc_parse.c | 142 ++++++++++++++++++++++++++-----------------------
libavcodec/evc_parse.h | 5 ++
2 files changed, 79 insertions(+), 68 deletions(-)
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 */
More information about the ffmpeg-cvslog
mailing list