Hi, 2014-09-03 18:30 GMT+02:00 Rémi Denis-Courmont <[email protected]>: > This allows the application to fallback to another hwaccel, or more > likely, to software decoding. > --- > libavcodec/utils.c | 46 ++++++++++++++++++++++++++++++++++++---------- > 1 file changed, 36 insertions(+), 10 deletions(-) > > diff --git a/libavcodec/utils.c b/libavcodec/utils.c > index c5fa50d..317e90f 100644 > --- a/libavcodec/utils.c > +++ b/libavcodec/utils.c > @@ -902,11 +902,26 @@ static AVHWAccel *find_hwaccel(enum AVCodecID codec_id, > int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt) > { > const AVPixFmtDescriptor *desc; > - enum AVPixelFormat ret = avctx->get_format(avctx, fmt); > + enum AVPixelFormat *choices; > + enum AVPixelFormat ret; > + unsigned n = 0; > + > + while (fmt[n] != AV_PIX_FMT_NONE) > + ++n; > + > + choices = av_malloc(++n * sizeof(*choices)); > + if (choices == NULL) > + return AV_PIX_FMT_NONE; > + > + memcpy(choices, fmt, n * sizeof(*choices)); > +retry: > + ret = avctx->get_format(avctx, choices); > > desc = av_pix_fmt_desc_get(ret); > - if (!desc) > + if (!desc) { > + av_freep(&choices); > return AV_PIX_FMT_NONE; > + } > > if (avctx->hwaccel && avctx->hwaccel->uninit) > avctx->hwaccel->uninit(avctx); > @@ -915,32 +930,43 @@ int ff_get_format(AVCodecContext *avctx, const enum > AVPixelFormat *fmt) > > if (desc->flags & AV_PIX_FMT_FLAG_HWACCEL) { > AVHWAccel *hwaccel; > - int err; > + int err = 0; > > hwaccel = find_hwaccel(avctx->codec_id, ret); > if (!hwaccel) { > av_log(avctx, AV_LOG_ERROR, > "Could not find an AVHWAccel for the pixel format: %s", > desc->name); > - return AV_PIX_FMT_NONE; > + err = AVERROR(ENOENT); > } > > - if (hwaccel->priv_data_size) { > + if (err == 0 && hwaccel->priv_data_size) { > avctx->internal->hwaccel_priv_data = > av_mallocz(hwaccel->priv_data_size); > if (!avctx->internal->hwaccel_priv_data) > - return AV_PIX_FMT_NONE; > + err = AVERROR(ENOMEM); > } > > - if (hwaccel->init) { > + if (err == 0 && hwaccel->init) { > err = hwaccel->init(avctx); > - if (err < 0) { > + if (err < 0) > av_freep(&avctx->internal->hwaccel_priv_data); > - return AV_PIX_FMT_NONE; > - } > + } > + > + if (err < 0) { > + /* Remove failed hwaccel from choices and reiterate */ > + for (n = 0; fmt[n] != ret; n++) > + av_assert0(fmt[n] != AV_PIX_FMT_NONE); > + > + do > + choices[n] = fmt[n + 1]; > + while (choices[n] != AV_PIX_FMT_NONE); > + > + goto retry; > } > avctx->hwaccel = hwaccel; > }
My eyes are small, I didn't sleep well but I don't think this part is correct. s/fmt/choices/ or you risk to fail on second iteration by getting a random index based off fmt[] instead of choices[]? > > + av_freep(&choices); > return ret; > } > > -- > 1.8.1.5 > > _______________________________________________ > libav-devel mailing list > [email protected] > https://lists.libav.org/mailman/listinfo/libav-devel Regards, -- Gwenole Beauchesne Intel Corporation SAS / 2 rue de Paris, 92196 Meudon Cedex, France Registration Number (RCS): Nanterre B 302 456 199 _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
