X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fhevcdec.c;h=f1934975d56943de90ef9ad837c20b27dece7277;hb=1707dbdf49b22021b0845482806b881093534f2f;hp=a3b5c8cb71e5daf688e24d8637e49522c503430f;hpb=50ae1f7e0ff1fa00236622415039f7e28d919a25;p=ffmpeg diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index a3b5c8cb71e..f1934975d56 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -310,9 +310,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 +356,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 +411,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 +454,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 +502,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 skiped 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 +2785,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 +2931,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 +2963,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 +3042,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 +3077,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 +3180,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; } }