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

Reply via email to