On Mon, 24 Mar 2014 10:34:02 +0100 Luca Barbato <[email protected]> wrote:
> On 24/03/14 10:20, Hendrik Leppkes wrote: > > On Mon, Mar 24, 2014 at 10:12 AM, Luca Barbato <[email protected]> wrote: > >> On 24/03/14 10:07, Hendrik Leppkes wrote: > >>> On Mon, Mar 24, 2014 at 3:01 AM, Luca Barbato <[email protected]> wrote: > >>>> From: Anton Khirnov <[email protected]> > >>>> > >>>> --- > >>>> libavcodec/avcodec.h | 23 +++++++++++++++++++++++ > >>>> libavcodec/internal.h | 5 +++++ > >>>> libavcodec/utils.c | 34 ++++++++++++++++++++++++++++++---- > >>>> 3 files changed, 58 insertions(+), 4 deletions(-) > >>>> > >>>> diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h > >>>> index 264305d..a1d0ae5 100644 > >>>> --- a/libavcodec/avcodec.h > >>>> +++ b/libavcodec/avcodec.h > >>>> @@ -2945,6 +2945,29 @@ typedef struct AVHWAccel { > >>>> * AVCodecContext.release_buffer(). > >>>> */ > >>>> int frame_priv_data_size; > >>>> + > >>>> + /** > >>>> + * Initialize the hwaccel private data. > >>>> + * > >>>> + * This will be called from ff_get_format(), after hwaccel and > >>>> + * hwaccel_context are set and the hwaccel private data in > >>>> AVCodecInternal > >>>> + * is allocated. > >>>> + */ > >>>> + int (*init)(AVCodecContext *avctx); > >>>> + > >>>> + /** > >>>> + * Uninitialize the hwaccel private data. > >>>> + * > >>>> + * This will be called from get_format() or avcodec_close(), after > >>>> hwaccel > >>>> + * and hwaccel_context are already uninitialized. > >>>> + */ > >>>> + int (*uninit)(AVCodecContext *avctx); > >>>> + > >>>> + /** > >>>> + * Size of the private data to allocate in > >>>> + * AVCodecInternal.hwaccel_priv_data. > >>>> + */ > >>>> + int priv_data_size; > >>>> } AVHWAccel; > >>>> > >>>> /** > >>>> diff --git a/libavcodec/internal.h b/libavcodec/internal.h > >>>> index 64765a2..17de2d5 100644 > >>>> --- a/libavcodec/internal.h > >>>> +++ b/libavcodec/internal.h > >>>> @@ -95,6 +95,11 @@ typedef struct AVCodecInternal { > >>>> * packet into every function. > >>>> */ > >>>> AVPacket *pkt; > >>>> + > >>>> + /** > >>>> + * hwaccel-specific private data > >>>> + */ > >>>> + void *hwaccel_priv_data; > >>>> } AVCodecInternal; > >>>> > >>>> struct AVCodecDefault { > >>>> diff --git a/libavcodec/utils.c b/libavcodec/utils.c > >>>> index e52d915..5ca7534 100644 > >>>> --- a/libavcodec/utils.c > >>>> +++ b/libavcodec/utils.c > >>>> @@ -858,16 +858,37 @@ int ff_get_format(AVCodecContext *avctx, const > >>>> enum AVPixelFormat *fmt) > >>>> if (!desc) > >>>> return AV_PIX_FMT_NONE; > >>>> > >>>> + if (avctx->hwaccel && avctx->hwaccel->uninit) > >>>> + avctx->hwaccel->uninit(avctx); > >>>> + av_freep(&avctx->internal->hwaccel_priv_data); > >>>> + avctx->hwaccel = NULL; > >>>> + > >>>> if (desc->flags & AV_PIX_FMT_FLAG_HWACCEL) { > >>>> - avctx->hwaccel = find_hwaccel(avctx->codec_id, ret); > >>>> - if (!avctx->hwaccel) { > >>>> + AVHWAccel *hwaccel; > >>>> + int err; > >>>> + > >>>> + 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; > >>>> } > >>>> - } else { > >>>> - avctx->hwaccel = NULL; > >>>> + > >>>> + if (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; > >>>> + } > >>>> + > >>>> + if (hwaccel->init) { > >>>> + err = hwaccel->init(avctx); > >>>> + if (err < 0) { > >>>> + av_freep(&avctx->internal->hwaccel_priv_data); > >>>> + return AV_PIX_FMT_NONE; > >>>> + } > >>>> + } > >>>> + avctx->hwaccel = hwaccel; > >>>> } > >>>> > >>> > >>> The seems to unconditionally call uninit/init everytime get_format is > >>> called, is this really required? AFAIK its called more often then > >>> really required. > >>> Maybe check if you actually switch a hwaccel on or off, instead of > >>> just re-initing it all the time? > >> > >> The get_format should be called only when there is a dimension/format > >> change. > >> > > > > "should" is fine, but in my experience it isn't. > > I'll look at the codepath to make sure =) From what I saw in the past > days it is called that way but I hadn't checked exactly that. In practice, it's called when the decoder is flushed, i.e. on seeking. And yes, this is a bit of a bother. Freeing all hardware surfaces and reallocating them etc. makes seeking quite a bit slower this way. _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
