X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fdecode.c;h=a32ff2fcd395c877e62eec10c3b8107d6102cc85;hb=b2f32d60eeaf883bb7d9e1b8cc2fb9a983d08f72;hp=ea2168ad0cc70c7c34b76b59444dfc594230b575;hpb=d28eb0e34d80f12b779c7b6befc5b350ffcdf476;p=ffmpeg diff --git a/libavcodec/decode.c b/libavcodec/decode.c index ea2168ad0cc..a32ff2fcd39 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -36,6 +36,7 @@ #include "libavutil/imgutils.h" #include "libavutil/internal.h" #include "libavutil/intmath.h" +#include "libavutil/opt.h" #include "avcodec.h" #include "bytestream.h" @@ -181,7 +182,7 @@ static int unrefcount_frame(AVCodecInternal *avci, AVFrame *frame) return 0; } -static int bsfs_init(AVCodecContext *avctx) +int ff_decode_bsfs_init(AVCodecContext *avctx) { AVCodecInternal *avci = avctx->internal; DecodeFilterContext *s = &avci->filter; @@ -195,27 +196,33 @@ static int bsfs_init(AVCodecContext *avctx) while (bsfs_str && *bsfs_str) { AVBSFContext **tmp; const AVBitStreamFilter *filter; - char *bsf; + char *bsf, *bsf_options_str, *bsf_name; bsf = av_get_token(&bsfs_str, ","); if (!bsf) { ret = AVERROR(ENOMEM); goto fail; } + bsf_name = av_strtok(bsf, "=", &bsf_options_str); + if (!bsf_name) { + av_freep(&bsf); + ret = AVERROR(ENOMEM); + goto fail; + } - filter = av_bsf_get_by_name(bsf); + filter = av_bsf_get_by_name(bsf_name); if (!filter) { av_log(avctx, AV_LOG_ERROR, "A non-existing bitstream filter %s " "requested by a decoder. This is a bug, please report it.\n", - bsf); - ret = AVERROR_BUG; + bsf_name); av_freep(&bsf); + ret = AVERROR_BUG; goto fail; } - av_freep(&bsf); tmp = av_realloc_array(s->bsfs, s->nb_bsfs + 1, sizeof(*s->bsfs)); if (!tmp) { + av_freep(&bsf); ret = AVERROR(ENOMEM); goto fail; } @@ -223,8 +230,10 @@ static int bsfs_init(AVCodecContext *avctx) s->nb_bsfs++; ret = av_bsf_alloc(filter, &s->bsfs[s->nb_bsfs - 1]); - if (ret < 0) + if (ret < 0) { + av_freep(&bsf); goto fail; + } if (s->nb_bsfs == 1) { /* We do not currently have an API for passing the input timebase into decoders, @@ -238,12 +247,38 @@ static int bsfs_init(AVCodecContext *avctx) ret = avcodec_parameters_copy(s->bsfs[s->nb_bsfs - 1]->par_in, s->bsfs[s->nb_bsfs - 2]->par_out); } - if (ret < 0) + if (ret < 0) { + av_freep(&bsf); goto fail; + } + + if (bsf_options_str && filter->priv_class) { + const AVOption *opt = av_opt_next(s->bsfs[s->nb_bsfs - 1]->priv_data, NULL); + const char * shorthand[2] = {NULL}; + + if (opt) + shorthand[0] = opt->name; + + ret = av_opt_set_from_string(s->bsfs[s->nb_bsfs - 1]->priv_data, bsf_options_str, shorthand, "=", ":"); + if (ret < 0) { + if (ret != AVERROR(ENOMEM)) { + av_log(avctx, AV_LOG_ERROR, "Invalid options for bitstream filter %s " + "requested by the decoder. This is a bug, please report it.\n", + bsf_name); + ret = AVERROR_BUG; + } + av_freep(&bsf); + goto fail; + } + } + av_freep(&bsf); ret = av_bsf_init(s->bsfs[s->nb_bsfs - 1]); if (ret < 0) goto fail; + + if (*bsfs_str) + bsfs_str++; } return 0; @@ -653,10 +688,6 @@ int attribute_align_arg avcodec_send_packet(AVCodecContext *avctx, const AVPacke if (avpkt && !avpkt->size && avpkt->data) return AVERROR(EINVAL); - ret = bsfs_init(avctx); - if (ret < 0) - return ret; - av_packet_unref(avci->buffer_pkt); if (avpkt && (avpkt->data || avpkt->side_data_elems)) { ret = av_packet_ref(avci->buffer_pkt, avpkt); @@ -716,10 +747,6 @@ int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *fr if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec)) return AVERROR(EINVAL); - ret = bsfs_init(avctx); - if (ret < 0) - return ret; - if (avci->buffer_frame->buf[0]) { av_frame_move_ref(frame, avci->buffer_frame); } else { @@ -1057,7 +1084,8 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, sub->format = 1; for (i = 0; i < sub->num_rects; i++) { - if (sub->rects[i]->ass && !utf8_check(sub->rects[i]->ass)) { + if (avctx->sub_charenc_mode != FF_SUB_CHARENC_MODE_IGNORE && + sub->rects[i]->ass && !utf8_check(sub->rects[i]->ass)) { av_log(avctx, AV_LOG_ERROR, "Invalid UTF-8 in decoded subtitles text; " "maybe missing -sub_charenc option\n"); @@ -1350,6 +1378,7 @@ int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt) if (i == n) { av_log(avctx, AV_LOG_ERROR, "Invalid return from get_format(): " "%s not in possible list.\n", desc->name); + ret = AV_PIX_FMT_NONE; break; } @@ -1468,7 +1497,7 @@ static int update_frame_pool(AVCodecContext *avctx, AVFrame *frame) tmpsize = av_image_fill_pointers(data, avctx->pix_fmt, h, NULL, linesize); if (tmpsize < 0) - return -1; + return tmpsize; for (i = 0; i < 3 && data[i + 1]; i++) size[i] = data[i + 1] - data[i]; @@ -1613,7 +1642,7 @@ static int video_get_buffer(AVCodecContext *s, AVFrame *pic) pic->linesize[i] = 0; } if (desc->flags & AV_PIX_FMT_FLAG_PAL || - desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) + ((desc->flags & FF_PSEUDOPAL) && pic->data[1])) avpriv_set_systematic_pal2((uint32_t *)pic->data[1], pic->format); if (s->debug & FF_DEBUG_BUFFERS) @@ -1778,12 +1807,11 @@ static void validate_avframe_allocation(AVCodecContext *avctx, AVFrame *frame) int flags = desc ? desc->flags : 0; if (num_planes == 1 && (flags & AV_PIX_FMT_FLAG_PAL)) num_planes = 2; + if ((flags & FF_PSEUDOPAL) && frame->data[1]) + num_planes = 2; for (i = 0; i < num_planes; i++) { av_assert0(frame->data[i]); } - // For now do not enforce anything for palette of pseudopal formats - if (num_planes == 1 && (flags & AV_PIX_FMT_FLAG_PSEUDOPAL)) - num_planes = 2; // For formats without data like hwaccel allow unused pointers to be non-NULL. for (i = num_planes; num_planes > 0 && i < FF_ARRAY_ELEMS(frame->data); i++) { if (frame->data[i]) @@ -1837,7 +1865,7 @@ static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags) int ret; if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { - if ((ret = av_image_check_size2(avctx->width, avctx->height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx)) < 0 || avctx->pix_fmt<0) { + if ((ret = av_image_check_size2(FFALIGN(avctx->width, STRIDE_ALIGN), avctx->height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx)) < 0 || avctx->pix_fmt<0) { av_log(avctx, AV_LOG_ERROR, "video_get_buffer: image parameters invalid\n"); return AVERROR(EINVAL); } @@ -1943,6 +1971,14 @@ int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame) return ret; } +static void bsfs_flush(AVCodecContext *avctx) +{ + DecodeFilterContext *s = &avctx->internal->filter; + + for (int i = 0; i < s->nb_bsfs; i++) + av_bsf_flush(s->bsfs[i]); +} + void avcodec_flush_buffers(AVCodecContext *avctx) { avctx->internal->draining = 0; @@ -1963,7 +1999,7 @@ void avcodec_flush_buffers(AVCodecContext *avctx) avctx->pts_correction_last_pts = avctx->pts_correction_last_dts = INT64_MIN; - ff_decode_bsfs_uninit(avctx); + bsfs_flush(avctx); if (!avctx->refcounted_frames) av_frame_unref(avctx->internal->to_free);