Also handle gradual decoding refresh stream.
Showing the changes to libavcodec (5 of 6 files). Show all
Unified · Split
| @@ -3306,9 +3306,19 @@ static int hevc_frame_start(HEVCContext *s, HEVCLayerContext *l, · 3305 unmodified lines | ||
| 3306 | 3306 | s->first_nal_type = s->nal_unit_type; |
| 3307 | 3307 | s->poc = s->sh.poc; |
| 3308 | 3308 | |
| 3309 | − if (IS_IRAP(s)) | |
| 3309 | + if (IS_IRAP(s)) { | |
| 3310 | 3310 | s->no_rasl_output_flag = IS_IDR(s) || IS_BLA(s) || |
| 3311 | 3311 | (s->nal_unit_type == HEVC_NAL_CRA_NUT && s->last_eos); |
| 3312 | + s->recovery_poc = HEVC_RECOVERY_END; | |
| 3313 | + } | |
| 3314 | + | |
| 3315 | + if (s->recovery_poc != HEVC_RECOVERY_END && | |
| 3316 | + s->sei.recovery_point.has_recovery_poc) { | |
| 3317 | + if (s->recovery_poc == HEVC_RECOVERY_UNSPECIFIED) | |
| 3318 | + s->recovery_poc = s->poc + s->sei.recovery_point.recovery_poc_cnt; | |
| 3319 | + else if (s->poc >= s->recovery_poc) | |
| 3320 | + s->recovery_poc = HEVC_RECOVERY_END; | |
| 3321 | + } | |
| 3312 | 3322 | |
| 3313 | 3323 | /* 8.3.1 */ |
| 3314 | 3324 | if (s->temporal_id == 0 && |
| @@ -3684,6 +3694,12 @@ fail: · 369 unmodified lines | ||
| 3684 | 3694 | return ret; |
| 3685 | 3695 | } |
| 3686 | 3696 | |
| 3697 | +static void decode_reset_recovery_point(HEVCContext *s) | |
| 3698 | +{ | |
| 3699 | + s->recovery_poc = HEVC_RECOVERY_UNSPECIFIED; | |
| 3700 | + s->sei.recovery_point.has_recovery_poc = 0; | |
| 3701 | +} | |
| 3702 | + | |
| 3687 | 3703 | static int decode_nal_units(HEVCContext *s, const uint8_t *buf, int length) |
| 3688 | 3704 | { |
| 3689 | 3705 | int i, ret = 0; |
| @@ -3694,6 +3710,8 @@ static int decode_nal_units(HEVCContext *s, const uint8_t *buf, int length) · 4 unmodified lines | ||
| 3694 | 3710 | s->last_eos = s->eos; |
| 3695 | 3711 | s->eos = 0; |
| 3696 | 3712 | s->slice_initialized = 0; |
| 3713 | + if (s->last_eos) | |
| 3714 | + decode_reset_recovery_point(s); | |
| 3697 | 3715 | |
| 3698 | 3716 | for (int i = 0; i < FF_ARRAY_ELEMS(s->layers); i++) { |
| 3699 | 3717 | HEVCLayerContext *l = &s->layers[i]; |
| @@ -3715,6 +3733,7 @@ static int decode_nal_units(HEVCContext *s, const uint8_t *buf, int length) · 15 unmodified lines | ||
| 3715 | 3733 | s->pkt.nals[i].type == HEVC_NAL_EOS_NUT) { |
| 3716 | 3734 | if (eos_at_start) { |
| 3717 | 3735 | s->last_eos = 1; |
| 3736 | + decode_reset_recovery_point(s); | |
| 3718 | 3737 | } else { |
| 3719 | 3738 | s->eos = 1; |
| 3720 | 3739 | } |
| @@ -4088,6 +4107,7 @@ static int hevc_update_thread_context(AVCodecContext *dst, · 367 unmodified lines | ||
| 4088 | 4107 | s->sei.common.alternative_transfer = s0->sei.common.alternative_transfer; |
| 4089 | 4108 | s->sei.tdrdi = s0->sei.tdrdi; |
| 4090 | 4109 | s->sei.recovery_point = s0->sei.recovery_point; |
| 4110 | + s->recovery_poc = s0->recovery_poc; | |
| 4091 | 4111 | |
| 4092 | 4112 | return 0; |
| 4093 | 4113 | } |
| @@ -78,6 +78,10 @@ · 77 unmodified lines | ||
| 78 | 78 | (s)->nal_unit_type == HEVC_NAL_BLA_N_LP) |
| 79 | 79 | #define IS_IRAP(s) ((s)->nal_unit_type >= HEVC_NAL_BLA_W_LP && (s)->nal_unit_type <= HEVC_NAL_RSV_IRAP_VCL23) |
| 80 | 80 | |
| 81 | +#define HEVC_RECOVERY_UNSPECIFIED INT_MAX | |
| 82 | +#define HEVC_RECOVERY_END INT_MIN | |
| 83 | +#define HEVC_IS_RECOVERING(s) ((s)->recovery_poc != HEVC_RECOVERY_UNSPECIFIED && (s)->recovery_poc != HEVC_RECOVERY_END) | |
| 84 | + | |
| 81 | 85 | enum RPSType { |
| 82 | 86 | ST_CURR_BEF = 0, |
| 83 | 87 | ST_CURR_AFT, |
| @@ -353,6 +357,7 @@ typedef struct DBParams { · 269 unmodified lines | ||
| 353 | 357 | #define HEVC_FRAME_FLAG_SHORT_REF (1 << 1) |
| 354 | 358 | #define HEVC_FRAME_FLAG_LONG_REF (1 << 2) |
| 355 | 359 | #define HEVC_FRAME_FLAG_UNAVAILABLE (1 << 3) |
| 360 | +#define HEVC_FRAME_FLAG_CORRUPT (1 << 4) | |
| 356 | 361 | |
| 357 | 362 | typedef struct HEVCFrame { |
| 358 | 363 | union { |
| @@ -523,6 +528,7 @@ typedef struct HEVCContext { · 164 unmodified lines | ||
| 523 | 528 | int slice_idx; ///< number of the slice being currently decoded |
| 524 | 529 | int eos; ///< current packet contains an EOS/EOB NAL |
| 525 | 530 | int last_eos; ///< last packet contains an EOS/EOB NAL |
| 531 | + int recovery_poc; | |
| 526 | 532 | |
| 527 | 533 | // NoRaslOutputFlag associated with the last IRAP frame |
| 528 | 534 | int no_rasl_output_flag; |
| @@ -34,6 +34,8 @@ · 33 unmodified lines | ||
| 34 | 34 | void ff_hevc_unref_frame(HEVCFrame *frame, int flags) |
| 35 | 35 | { |
| 36 | 36 | frame->flags &= ~flags; |
| 37 | + if (!(frame->flags & ~HEVC_FRAME_FLAG_CORRUPT)) | |
| 38 | + frame->flags = 0; | |
| 37 | 39 | if (!frame->flags) { |
| 38 | 40 | ff_progress_frame_unref(&frame->tf); |
| 39 | 41 | av_frame_unref(frame->frame_grain); |
| @@ -208,6 +210,7 @@ int ff_hevc_set_new_ref(HEVCContext *s, HEVCLayerContext *l, int poc) · 168 unmodified lines | ||
| 208 | 210 | { |
| 209 | 211 | HEVCFrame *ref; |
| 210 | 212 | int i; |
| 213 | + int no_output; | |
| 211 | 214 | |
| 212 | 215 | /* check that this POC doesn't already exist */ |
| 213 | 216 | for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { |
| @@ -231,7 +234,10 @@ int ff_hevc_set_new_ref(HEVCContext *s, HEVCLayerContext *l, int poc) · 17 unmodified lines | ||
| 231 | 234 | ref->base_layer_frame = (l != &s->layers[0] && s->layers[0].cur_frame) ? |
| 232 | 235 | s->layers[0].cur_frame - s->layers[0].DPB : -1; |
| 233 | 236 | |
| 234 | − if (s->sh.pic_output_flag) | |
| 237 | + no_output = !IS_IRAP(s) && (s->poc < s->recovery_poc) && | |
| 238 | + !(s->avctx->flags & AV_CODEC_FLAG_OUTPUT_CORRUPT) && | |
| 239 | + !(s->avctx->flags2 & AV_CODEC_FLAG2_SHOW_ALL); | |
| 240 | + if (s->sh.pic_output_flag && !no_output) | |
| 235 | 241 | ref->flags = HEVC_FRAME_FLAG_OUTPUT | HEVC_FRAME_FLAG_SHORT_REF; |
| 236 | 242 | else |
| 237 | 243 | ref->flags = HEVC_FRAME_FLAG_SHORT_REF; |
| @@ -298,6 +304,8 @@ int ff_hevc_output_frames(HEVCContext *s, · 60 unmodified lines | ||
| 298 | 304 | int output = !discard && (layers_active_output & (1 << min_layer)); |
| 299 | 305 | |
| 300 | 306 | if (output) { |
| 307 | + if (frame->flags & HEVC_FRAME_FLAG_CORRUPT) | |
| 308 | + f->flags |= AV_FRAME_FLAG_CORRUPT; | |
| 301 | 309 | f->pkt_dts = s->pkt_dts; |
| 302 | 310 | ret = av_container_fifo_write(s->output_fifo, f, AV_CONTAINER_FIFO_FLAG_REF); |
| 303 | 311 | } |
| @@ -494,6 +502,20 @@ static int add_candidate_ref(HEVCContext *s, HEVCLayerContext *l, · 190 unmodified lines | ||
| 494 | 502 | if (ref == s->cur_frame || list->nb_refs >= HEVC_MAX_REFS) |
| 495 | 503 | return AVERROR_INVALIDDATA; |
| 496 | 504 | |
| 505 | + if (!IS_IRAP(s)) { | |
| 506 | + int ref_corrupt = !ref || ref->flags & (HEVC_FRAME_FLAG_CORRUPT | | |
| 507 | + HEVC_FRAME_FLAG_UNAVAILABLE); | |
| 508 | + int recovering = HEVC_IS_RECOVERING(s); | |
| 509 | + | |
| 510 | + if (ref_corrupt && !recovering) { | |
| 511 | + if (!(s->avctx->flags & AV_CODEC_FLAG_OUTPUT_CORRUPT) && | |
| 512 | + !(s->avctx->flags2 & AV_CODEC_FLAG2_SHOW_ALL)) | |
| 513 | + return AVERROR_INVALIDDATA; | |
| 514 | + | |
| 515 | + s->cur_frame->flags |= HEVC_FRAME_FLAG_CORRUPT; | |
| 516 | + } | |
| 517 | + } | |
| 518 | + | |
| 497 | 519 | if (!ref) { |
| 498 | 520 | ref = generate_missing_ref(s, l, poc); |
| 499 | 521 | if (!ref) |
| @@ -89,6 +89,7 @@ static int decode_nal_sei_recovery_point(HEVCSEI *s, GetBitContext *gb) · 88 unmodified lines | ||
| 89 | 89 | rec->recovery_poc_cnt = recovery_poc_cnt; |
| 90 | 90 | rec->exact_match_flag = get_bits1(gb); |
| 91 | 91 | rec->broken_link_flag = get_bits1(gb); |
| 92 | + rec->has_recovery_poc = 1; | |
| 92 | 93 | |
| 93 | 94 | return 0; |
| 94 | 95 | } |
| @@ -99,6 +99,7 @@ typedef struct HEVCSEIRecoveryPoint { · 98 unmodified lines | ||
| 99 | 99 | int16_t recovery_poc_cnt; |
| 100 | 100 | uint8_t exact_match_flag; |
| 101 | 101 | uint8_t broken_link_flag; |
| 102 | + uint8_t has_recovery_poc; | |
| 102 | 103 | } HEVCSEIRecoveryPoint; |
| 103 | 104 | |
| 104 | 105 | typedef struct HEVCSEI { |