Message ID | 5ca902bc-99cc-2866-ec9a-068ac356924d@gmail.com |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel] libavcodec/hevcdec: detect non-conformant missing refs | expand |
Context | Check | Description |
---|---|---|
andriy/make_x86 | success | Make finished |
andriy/make_fate_x86 | success | Make fate finished |
andriy/make_aarch64_jetson | success | Make finished |
andriy/make_fate_aarch64_jetson | success | Make fate finished |
andriy/make_armv7_RPi4 | success | Make finished |
andriy/make_fate_armv7_RPi4 | success | Make fate finished |
Quoting Xiaolei Yu (2022-04-05 08:49:24) > > For cases which prefer rejecting broken bitstreams. > --- > libavcodec/hevc_refs.c | 15 ++++++++++++--- > 1 file changed, 12 insertions(+), 3 deletions(-) > > diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c > index fe18ca2b1d..7ea70e301b 100644 > --- a/libavcodec/hevc_refs.c > +++ b/libavcodec/hevc_refs.c > @@ -426,7 +426,7 @@ static HEVCFrame *generate_missing_ref(HEVCContext *s, int poc) > > /* add a reference with the given poc to the list and mark it as used in DPB */ > static int add_candidate_ref(HEVCContext *s, RefPicList *list, > - int poc, int ref_flag, uint8_t use_msb) > + int poc, int ref_flag, uint8_t use_msb, int maybe_missing) allow_missing would be clearer IMO > { > HEVCFrame *ref = find_ref_idx(s, poc, use_msb); > > @@ -434,6 +434,9 @@ static int add_candidate_ref(HEVCContext *s, RefPicList *list, > return AVERROR_INVALIDDATA; > > if (!ref) { > + if ((s->avctx->err_recognition & AV_EF_COMPLIANT) && !maybe_missing) a log message would be nice, so one can easily tell where exactly the error comes from
On 4/5/22 17:10, Anton Khirnov wrote: > Quoting Xiaolei Yu (2022-04-05 08:49:24) >> >> For cases which prefer rejecting broken bitstreams. >> --- >> libavcodec/hevc_refs.c | 15 ++++++++++++--- >> 1 file changed, 12 insertions(+), 3 deletions(-) >> >> diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c >> index fe18ca2b1d..7ea70e301b 100644 >> --- a/libavcodec/hevc_refs.c >> +++ b/libavcodec/hevc_refs.cfind_ref_idx( >> @@ -426,7 +426,7 @@ static HEVCFrame *generate_missing_ref(HEVCContext *s, int poc) >> >> /* add a reference with the given poc to the list and mark it as used in DPB */ >> static int add_candidate_ref(HEVCContext *s, RefPicList *list, >> - int poc, int ref_flag, uint8_t use_msb) >> + int poc, int ref_flag, uint8_t use_msb, int maybe_missing) > > allow_missing would be clearer IMO > done >> { >> HEVCFrame *ref = find_ref_idx(s, poc, use_msb); >> >> @@ -434,6 +434,9 @@ static int add_candidate_ref(HEVCContext *s, RefPicList *list, >> return AVERROR_INVALIDDATA; >> >> if (!ref) { >> + if ((s->avctx->err_recognition & AV_EF_COMPLIANT) && !maybe_missing) > > a log message would be nice, so one can easily tell where exactly the > error comes from > Moved the log message from find_ref_idx to where the missing refs are to be generated.
diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c index fe18ca2b1d..7ea70e301b 100644 --- a/libavcodec/hevc_refs.c +++ b/libavcodec/hevc_refs.c @@ -426,7 +426,7 @@ static HEVCFrame *generate_missing_ref(HEVCContext *s, int poc) /* add a reference with the given poc to the list and mark it as used in DPB */ static int add_candidate_ref(HEVCContext *s, RefPicList *list, - int poc, int ref_flag, uint8_t use_msb) + int poc, int ref_flag, uint8_t use_msb, int maybe_missing) { HEVCFrame *ref = find_ref_idx(s, poc, use_msb); @@ -434,6 +434,9 @@ static int add_candidate_ref(HEVCContext *s, RefPicList *list, return AVERROR_INVALIDDATA; if (!ref) { + if ((s->avctx->err_recognition & AV_EF_COMPLIANT) && !maybe_missing) + return AVERROR_INVALIDDATA; + ref = generate_missing_ref(s, poc); if (!ref) return AVERROR(ENOMEM); @@ -476,6 +479,7 @@ int ff_hevc_frame_rps(HEVCContext *s) for (i = 0; i < short_rps->num_delta_pocs; i++) { int poc = s->poc + short_rps->delta_poc[i]; int list; + int maybe_missing; if (!short_rps->used[i]) list = ST_FOLL; @@ -484,7 +488,10 @@ int ff_hevc_frame_rps(HEVCContext *s) else list = ST_CURR_AFT; - ret = add_candidate_ref(s, &rps[list], poc, HEVC_FRAME_FLAG_SHORT_REF, 1); + maybe_missing = list != ST_CURR_BEF && list != ST_CURR_AFT; + + ret = add_candidate_ref(s, &rps[list], poc, HEVC_FRAME_FLAG_SHORT_REF, 1, + maybe_missing); if (ret < 0) goto fail; } @@ -493,8 +500,10 @@ int ff_hevc_frame_rps(HEVCContext *s) for (i = 0; i < long_rps->nb_refs; i++) { int poc = long_rps->poc[i]; int list = long_rps->used[i] ? LT_CURR : LT_FOLL; + int maybe_missing = list != LT_CURR; - ret = add_candidate_ref(s, &rps[list], poc, HEVC_FRAME_FLAG_LONG_REF, long_rps->poc_msb_present[i]); + ret = add_candidate_ref(s, &rps[list], poc, HEVC_FRAME_FLAG_LONG_REF, long_rps->poc_msb_present[i], + maybe_missing); if (ret < 0) goto fail; }