mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-02-17 12:27:18 +00:00
avcodec/evc_parse: split off deriving PoC
Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
parent
f7e0af5edc
commit
ff7a4cdf04
@ -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;
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user