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 | s->first_nal_type = s->nal_unit_type; | 3306 | s->first_nal_type = s->nal_unit_type; |
| 3307 | s->poc = s->sh.poc; | 3307 | s->poc = s->sh.poc; |
| 3308 | 3308 | ||
| 3309 | if (IS_IRAP(s)) | 3309 | if (IS_IRAP(s)) { |
| 3310 | s->no_rasl_output_flag = IS_IDR(s) || IS_BLA(s) || | 3310 | s->no_rasl_output_flag = IS_IDR(s) || IS_BLA(s) || |
| 3311 | (s->nal_unit_type == HEVC_NAL_CRA_NUT && s->last_eos); | 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 | /* 8.3.1 */ | 3323 | /* 8.3.1 */ |
| 3314 | if (s->temporal_id == 0 && | 3324 | if (s->temporal_id == 0 && |
| @@ -3684,6 +3694,12 @@ fail: · 369 unmodified lines | |||
| 3684 | return ret; | 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 | static int decode_nal_units(HEVCContext *s, const uint8_t *buf, int length) | 3703 | static int decode_nal_units(HEVCContext *s, const uint8_t *buf, int length) |
| 3688 | { | 3704 | { |
| 3689 | int i, ret = 0; | 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 | s->last_eos = s->eos; | 3710 | s->last_eos = s->eos; |
| 3695 | s->eos = 0; | 3711 | s->eos = 0; |
| 3696 | s->slice_initialized = 0; | 3712 | s->slice_initialized = 0; |
| 3713 | if (s->last_eos) | ||
| 3714 | decode_reset_recovery_point(s); | ||
| 3697 | 3715 | ||
| 3698 | for (int i = 0; i < FF_ARRAY_ELEMS(s->layers); i++) { | 3716 | for (int i = 0; i < FF_ARRAY_ELEMS(s->layers); i++) { |
| 3699 | HEVCLayerContext *l = &s->layers[i]; | 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 | s->pkt.nals[i].type == HEVC_NAL_EOS_NUT) { | 3733 | s->pkt.nals[i].type == HEVC_NAL_EOS_NUT) { |
| 3716 | if (eos_at_start) { | 3734 | if (eos_at_start) { |
| 3717 | s->last_eos = 1; | 3735 | s->last_eos = 1; |
| 3736 | decode_reset_recovery_point(s); | ||
| 3718 | } else { | 3737 | } else { |
| 3719 | s->eos = 1; | 3738 | s->eos = 1; |
| 3720 | } | 3739 | } |
| @@ -4088,6 +4107,7 @@ static int hevc_update_thread_context(AVCodecContext *dst, · 367 unmodified lines | |||
| 4088 | s->sei.common.alternative_transfer = s0->sei.common.alternative_transfer; | 4107 | s->sei.common.alternative_transfer = s0->sei.common.alternative_transfer; |
| 4089 | s->sei.tdrdi = s0->sei.tdrdi; | 4108 | s->sei.tdrdi = s0->sei.tdrdi; |
| 4090 | s->sei.recovery_point = s0->sei.recovery_point; | 4109 | s->sei.recovery_point = s0->sei.recovery_point; |
| 4110 | s->recovery_poc = s0->recovery_poc; | ||
| 4091 | 4111 | ||
| 4092 | return 0; | 4112 | return 0; |
| 4093 | } | 4113 | } |
| @@ -78,6 +78,10 @@ · 77 unmodified lines | |||
| 78 | (s)->nal_unit_type == HEVC_NAL_BLA_N_LP) | 78 | (s)->nal_unit_type == HEVC_NAL_BLA_N_LP) |
| 79 | #define IS_IRAP(s) ((s)->nal_unit_type >= HEVC_NAL_BLA_W_LP && (s)->nal_unit_type <= HEVC_NAL_RSV_IRAP_VCL23) | 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 | enum RPSType { | 85 | enum RPSType { |
| 82 | ST_CURR_BEF = 0, | 86 | ST_CURR_BEF = 0, |
| 83 | ST_CURR_AFT, | 87 | ST_CURR_AFT, |
| @@ -353,6 +357,7 @@ typedef struct DBParams { · 269 unmodified lines | |||
| 353 | #define HEVC_FRAME_FLAG_SHORT_REF (1 << 1) | 357 | #define HEVC_FRAME_FLAG_SHORT_REF (1 << 1) |
| 354 | #define HEVC_FRAME_FLAG_LONG_REF (1 << 2) | 358 | #define HEVC_FRAME_FLAG_LONG_REF (1 << 2) |
| 355 | #define HEVC_FRAME_FLAG_UNAVAILABLE (1 << 3) | 359 | #define HEVC_FRAME_FLAG_UNAVAILABLE (1 << 3) |
| 360 | #define HEVC_FRAME_FLAG_CORRUPT (1 << 4) | ||
| 356 | 361 | ||
| 357 | typedef struct HEVCFrame { | 362 | typedef struct HEVCFrame { |
| 358 | union { | 363 | union { |
| @@ -523,6 +528,7 @@ typedef struct HEVCContext { · 164 unmodified lines | |||
| 523 | int slice_idx; ///< number of the slice being currently decoded | 528 | int slice_idx; ///< number of the slice being currently decoded |
| 524 | int eos; ///< current packet contains an EOS/EOB NAL | 529 | int eos; ///< current packet contains an EOS/EOB NAL |
| 525 | int last_eos; ///< last packet contains an EOS/EOB NAL | 530 | int last_eos; ///< last packet contains an EOS/EOB NAL |
| 531 | int recovery_poc; | ||
| 526 | 532 | ||
| 527 | // NoRaslOutputFlag associated with the last IRAP frame | 533 | // NoRaslOutputFlag associated with the last IRAP frame |
| 528 | int no_rasl_output_flag; | 534 | int no_rasl_output_flag; |
| @@ -34,6 +34,8 @@ · 33 unmodified lines | |||
| 34 | void ff_hevc_unref_frame(HEVCFrame *frame, int flags) | 34 | void ff_hevc_unref_frame(HEVCFrame *frame, int flags) |
| 35 | { | 35 | { |
| 36 | frame->flags &= ~flags; | 36 | frame->flags &= ~flags; |
| 37 | if (!(frame->flags & ~HEVC_FRAME_FLAG_CORRUPT)) | ||
| 38 | frame->flags = 0; | ||
| 37 | if (!frame->flags) { | 39 | if (!frame->flags) { |
| 38 | ff_progress_frame_unref(&frame->tf); | 40 | ff_progress_frame_unref(&frame->tf); |
| 39 | av_frame_unref(frame->frame_grain); | 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 | HEVCFrame *ref; | 211 | HEVCFrame *ref; |
| 210 | int i; | 212 | int i; |
| 213 | int no_output; | ||
| 211 | 214 | ||
| 212 | /* check that this POC doesn't already exist */ | 215 | /* check that this POC doesn't already exist */ |
| 213 | for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { | 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 | ref->base_layer_frame = (l != &s->layers[0] && s->layers[0].cur_frame) ? | 234 | ref->base_layer_frame = (l != &s->layers[0] && s->layers[0].cur_frame) ? |
| 232 | s->layers[0].cur_frame - s->layers[0].DPB : -1; | 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 | ref->flags = HEVC_FRAME_FLAG_OUTPUT | HEVC_FRAME_FLAG_SHORT_REF; | 241 | ref->flags = HEVC_FRAME_FLAG_OUTPUT | HEVC_FRAME_FLAG_SHORT_REF; |
| 236 | else | 242 | else |
| 237 | ref->flags = HEVC_FRAME_FLAG_SHORT_REF; | 243 | ref->flags = HEVC_FRAME_FLAG_SHORT_REF; |
| @@ -298,6 +304,8 @@ int ff_hevc_output_frames(HEVCContext *s, · 60 unmodified lines | |||
| 298 | int output = !discard && (layers_active_output & (1 << min_layer)); | 304 | int output = !discard && (layers_active_output & (1 << min_layer)); |
| 299 | 305 | ||
| 300 | if (output) { | 306 | if (output) { |
| 307 | if (frame->flags & HEVC_FRAME_FLAG_CORRUPT) | ||
| 308 | f->flags |= AV_FRAME_FLAG_CORRUPT; | ||
| 301 | f->pkt_dts = s->pkt_dts; | 309 | f->pkt_dts = s->pkt_dts; |
| 302 | ret = av_container_fifo_write(s->output_fifo, f, AV_CONTAINER_FIFO_FLAG_REF); | 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 | if (ref == s->cur_frame || list->nb_refs >= HEVC_MAX_REFS) | 502 | if (ref == s->cur_frame || list->nb_refs >= HEVC_MAX_REFS) |
| 495 | return AVERROR_INVALIDDATA; | 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 | if (!ref) { | 519 | if (!ref) { |
| 498 | ref = generate_missing_ref(s, l, poc); | 520 | ref = generate_missing_ref(s, l, poc); |
| 499 | if (!ref) | 521 | if (!ref) |
| @@ -89,6 +89,7 @@ static int decode_nal_sei_recovery_point(HEVCSEI *s, GetBitContext *gb) · 88 unmodified lines | |||
| 89 | rec->recovery_poc_cnt = recovery_poc_cnt; | 89 | rec->recovery_poc_cnt = recovery_poc_cnt; |
| 90 | rec->exact_match_flag = get_bits1(gb); | 90 | rec->exact_match_flag = get_bits1(gb); |
| 91 | rec->broken_link_flag = get_bits1(gb); | 91 | rec->broken_link_flag = get_bits1(gb); |
| 92 | rec->has_recovery_poc = 1; | ||
| 92 | 93 | ||
| 93 | return 0; | 94 | return 0; |
| 94 | } | 95 | } |
| @@ -99,6 +99,7 @@ typedef struct HEVCSEIRecoveryPoint { · 98 unmodified lines | |||
| 99 | int16_t recovery_poc_cnt; | 99 | int16_t recovery_poc_cnt; |
| 100 | uint8_t exact_match_flag; | 100 | uint8_t exact_match_flag; |
| 101 | uint8_t broken_link_flag; | 101 | uint8_t broken_link_flag; |
| 102 | uint8_t has_recovery_poc; | ||
| 102 | } HEVCSEIRecoveryPoint; | 103 | } HEVCSEIRecoveryPoint; |
| 103 | 104 | ||
| 104 | typedef struct HEVCSEI { | 105 | typedef struct HEVCSEI { |