X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fhevcdec.c;h=8f1c162aceeb53e3028d16b87998b1ed92386af0;hb=a5d29812ec364ad4b83b5c2dba281f1b559a518b;hp=a3b5c8cb71e5daf688e24d8637e49522c503430f;hpb=185aa5e896e15ae96145609944bfc6bbb239bc64;p=ffmpeg diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index a3b5c8cb71e..8f1c162acee 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -182,6 +182,8 @@ static int pred_weight_table(HEVCContext *s, GetBitContext *gb) for (i = 0; i < s->sh.nb_refs[L0]; i++) { if (luma_weight_l0_flag[i]) { int delta_luma_weight_l0 = get_se_golomb(gb); + if ((int8_t)delta_luma_weight_l0 != delta_luma_weight_l0) + return AVERROR_INVALIDDATA; s->sh.luma_weight_l0[i] = (1 << s->sh.luma_log2_weight_denom) + delta_luma_weight_l0; s->sh.luma_offset_l0[i] = get_se_golomb(gb); } @@ -224,6 +226,8 @@ static int pred_weight_table(HEVCContext *s, GetBitContext *gb) for (i = 0; i < s->sh.nb_refs[L1]; i++) { if (luma_weight_l1_flag[i]) { int delta_luma_weight_l1 = get_se_golomb(gb); + if ((int8_t)delta_luma_weight_l1 != delta_luma_weight_l1) + return AVERROR_INVALIDDATA; s->sh.luma_weight_l1[i] = (1 << s->sh.luma_log2_weight_denom) + delta_luma_weight_l1; s->sh.luma_offset_l1[i] = get_se_golomb(gb); } @@ -310,9 +314,10 @@ static int decode_lt_rps(HEVCContext *s, LongTermRPS *rps, GetBitContext *gb) return 0; } -static void export_stream_params(AVCodecContext *avctx, const HEVCParamSets *ps, - const HEVCSPS *sps) +static void export_stream_params(HEVCContext *s, const HEVCSPS *sps) { + AVCodecContext *avctx = s->avctx; + const HEVCParamSets *ps = &s->ps; const HEVCVPS *vps = (const HEVCVPS*)ps->vps_list[sps->vps_id]->data; const HEVCWindow *ow = &sps->output_window; unsigned int num = 0, den = 0; @@ -355,6 +360,12 @@ static void export_stream_params(AVCodecContext *avctx, const HEVCParamSets *ps, if (num != 0 && den != 0) av_reduce(&avctx->framerate.den, &avctx->framerate.num, num, den, 1 << 30); + + if (s->sei.alternative_transfer.present && + av_color_transfer_name(s->sei.alternative_transfer.preferred_transfer_characteristics) && + s->sei.alternative_transfer.preferred_transfer_characteristics != AVCOL_TRC_UNSPECIFIED) { + avctx->color_trc = s->sei.alternative_transfer.preferred_transfer_characteristics; + } } static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) @@ -404,11 +415,21 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) #if CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL *fmt++ = AV_PIX_FMT_VIDEOTOOLBOX; #endif +#if CONFIG_HEVC_NVDEC_HWACCEL + *fmt++ = AV_PIX_FMT_CUDA; +#endif + break; + case AV_PIX_FMT_YUV444P: +#if CONFIG_HEVC_VDPAU_HWACCEL + *fmt++ = AV_PIX_FMT_VDPAU; +#endif #if CONFIG_HEVC_NVDEC_HWACCEL *fmt++ = AV_PIX_FMT_CUDA; #endif break; case AV_PIX_FMT_YUV420P12: + case AV_PIX_FMT_YUV444P10: + case AV_PIX_FMT_YUV444P12: #if CONFIG_HEVC_NVDEC_HWACCEL *fmt++ = AV_PIX_FMT_CUDA; #endif @@ -437,7 +458,7 @@ static int set_sps(HEVCContext *s, const HEVCSPS *sps, if (ret < 0) goto fail; - export_stream_params(s->avctx, &s->ps, sps); + export_stream_params(s, sps); s->avctx->pix_fmt = pix_fmt; @@ -485,6 +506,11 @@ static int hls_slice_header(HEVCContext *s) // Coded parameters sh->first_slice_in_pic_flag = get_bits1(gb); + if (s->ref && sh->first_slice_in_pic_flag) { + av_log(s->avctx, AV_LOG_ERROR, "Two slices reporting being the first in the same frame.\n"); + return 1; // This slice will be skipped later, do not corrupt state + } + if ((IS_IDR(s) || IS_BLA(s)) && sh->first_slice_in_pic_flag) { s->seq_decode = (s->seq_decode + 1) & 0xff; s->max_ra = INT_MAX; @@ -2763,12 +2789,6 @@ static int set_side_data(HEVCContext *s) s->avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS; } - if (s->sei.alternative_transfer.present && - av_color_transfer_name(s->sei.alternative_transfer.preferred_transfer_characteristics) && - s->sei.alternative_transfer.preferred_transfer_characteristics != AVCOL_TRC_UNSPECIFIED) { - s->avctx->color_trc = out->color_trc = s->sei.alternative_transfer.preferred_transfer_characteristics; - } - return 0; } @@ -2915,6 +2935,11 @@ static int decode_nal_unit(HEVCContext *s, const H2645NAL *nal) ret = hls_slice_header(s); if (ret < 0) return ret; + if (ret == 1) { + ret = AVERROR_INVALIDDATA; + goto fail; + } + if ( (s->avctx->skip_frame >= AVDISCARD_BIDIR && s->sh.slice_type == HEVC_SLICE_B) || @@ -2942,6 +2967,7 @@ static int decode_nal_unit(HEVCContext *s, const H2645NAL *nal) s->max_ra = INT_MIN; } + s->overlap ++; ret = hevc_frame_start(s); if (ret < 0) return ret; @@ -3020,11 +3046,12 @@ static int decode_nal_units(HEVCContext *s, const uint8_t *buf, int length) s->ref = NULL; s->last_eos = s->eos; s->eos = 0; + s->overlap = 0; /* split the input packet into NAL units, so we know the upper bound on the * number of slices in the frame */ ret = ff_h2645_packet_split(&s->pkt, buf, length, s->avctx, s->is_nalff, - s->nal_length_size, s->avctx->codec_id, 1); + s->nal_length_size, s->avctx->codec_id, 1, 0); if (ret < 0) { av_log(s->avctx, AV_LOG_ERROR, "Error splitting the input into NAL units.\n"); @@ -3054,6 +3081,8 @@ static int decode_nal_units(HEVCContext *s, const uint8_t *buf, int length) continue; ret = decode_nal_unit(s, nal); + if (ret >= 0 && s->overlap > 2) + ret = AVERROR_INVALIDDATA; if (ret < 0) { av_log(s->avctx, AV_LOG_WARNING, "Error parsing NAL unit #%d.\n", i); @@ -3155,7 +3184,7 @@ static int hevc_decode_extradata(HEVCContext *s, uint8_t *buf, int length, int f for (i = 0; i < FF_ARRAY_ELEMS(s->ps.sps_list); i++) { if (first && s->ps.sps_list[i]) { const HEVCSPS *sps = (const HEVCSPS*)s->ps.sps_list[i]->data; - export_stream_params(s->avctx, &s->ps, sps); + export_stream_params(s, sps); break; } } @@ -3307,6 +3336,8 @@ static av_cold int hevc_decode_free(AVCodecContext *avctx) ff_h2645_packet_uninit(&s->pkt); + ff_hevc_reset_sei(&s->sei); + return 0; } @@ -3500,6 +3531,7 @@ static void hevc_decode_flush(AVCodecContext *avctx) { HEVCContext *s = avctx->priv_data; ff_hevc_flush_dpb(s); + ff_hevc_reset_sei(&s->sei); s->max_ra = INT_MAX; s->eos = 1; }