avcodec/evc_parse: split off deriving PoC

Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
James Almer 2023-06-17 17:18:04 -03:00
parent f7e0af5edc
commit ff7a4cdf04
2 changed files with 79 additions and 68 deletions

View File

@ -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;

View File

@ -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 */