[FFmpeg-devel] [PATCH 1/2] vp9: add hwaccel hooks
Ronald S. Bultje
rsbultje at gmail.com
Thu Dec 3 17:19:18 CET 2015
Hi,
On Thu, Dec 3, 2015 at 6:13 AM, Hendrik Leppkes <h.leppkes at gmail.com> wrote:
> On Thu, Dec 3, 2015 at 11:13 AM, Hendrik Leppkes <h.leppkes at gmail.com>
> wrote:
> > ---
> > libavcodec/vp9.c | 128
> +++++++++++++++++++++++++++++++++++++++----------------
> > libavcodec/vp9.h | 3 ++
> > 2 files changed, 94 insertions(+), 37 deletions(-)
> >
> > diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
> > index d8888c0..87e80d8 100644
> > --- a/libavcodec/vp9.c
> > +++ b/libavcodec/vp9.c
> > @@ -168,6 +168,15 @@ static const uint8_t bwh_tab[2][N_BS_SIZES][2] = {
> > }
> > };
> >
> > +static void vp9_unref_frame(AVCodecContext *ctx, VP9Frame *f)
> > +{
> > + ff_thread_release_buffer(ctx, &f->tf);
> > + av_buffer_unref(&f->extradata);
> > + av_buffer_unref(&f->hwaccel_priv_buf);
> > + f->segmentation_map = NULL;
> > + f->hwaccel_picture_private = NULL;
> > +}
> > +
> > static int vp9_alloc_frame(AVCodecContext *ctx, VP9Frame *f)
> > {
> > VP9Context *s = ctx->priv_data;
> > @@ -177,21 +186,28 @@ static int vp9_alloc_frame(AVCodecContext *ctx,
> VP9Frame *f)
> > return ret;
> > sz = 64 * s->sb_cols * s->sb_rows;
> > if (!(f->extradata = av_buffer_allocz(sz * (1 + sizeof(struct
> VP9mvrefPair))))) {
> > - ff_thread_release_buffer(ctx, &f->tf);
> > - return AVERROR(ENOMEM);
> > + goto fail;
> > }
> >
> > f->segmentation_map = f->extradata->data;
> > f->mv = (struct VP9mvrefPair *) (f->extradata->data + sz);
> >
> > + if (ctx->hwaccel) {
> > + const AVHWAccel *hwaccel = ctx->hwaccel;
> > + av_assert0(!f->hwaccel_picture_private);
> > + if (hwaccel->frame_priv_data_size) {
> > + f->hwaccel_priv_buf =
> av_buffer_allocz(hwaccel->frame_priv_data_size);
> > + if (!f->hwaccel_priv_buf)
> > + goto fail;
> > + f->hwaccel_picture_private = f->hwaccel_priv_buf->data;
> > + }
> > + }
> > +
> > return 0;
> > -}
> >
> > -static void vp9_unref_frame(AVCodecContext *ctx, VP9Frame *f)
> > -{
> > - ff_thread_release_buffer(ctx, &f->tf);
> > - av_buffer_unref(&f->extradata);
> > - f->segmentation_map = NULL;
> > +fail:
> > + vp9_unref_frame(ctx, f);
> > + return AVERROR(ENOMEM);
> > }
> >
> > static int vp9_ref_frame(AVCodecContext *ctx, VP9Frame *dst, VP9Frame
> *src)
> > @@ -201,19 +217,31 @@ static int vp9_ref_frame(AVCodecContext *ctx,
> VP9Frame *dst, VP9Frame *src)
> > if ((res = ff_thread_ref_frame(&dst->tf, &src->tf)) < 0) {
> > return res;
> > } else if (!(dst->extradata = av_buffer_ref(src->extradata))) {
> > - vp9_unref_frame(ctx, dst);
> > - return AVERROR(ENOMEM);
> > + goto fail;
> > }
> >
> > dst->segmentation_map = src->segmentation_map;
> > dst->mv = src->mv;
> > dst->uses_2pass = src->uses_2pass;
> >
> > + if (src->hwaccel_picture_private) {
> > + dst->hwaccel_priv_buf = av_buffer_ref(src->hwaccel_priv_buf);
> > + if (!dst->hwaccel_priv_buf)
> > + goto fail;
> > + dst->hwaccel_picture_private = dst->hwaccel_priv_buf->data;
> > + }
> > +
> > return 0;
> > +
> > +fail:
> > + vp9_unref_frame(ctx, dst);
> > + return AVERROR(ENOMEM);
> > }
> >
> > static int update_size(AVCodecContext *ctx, int w, int h)
> > {
> > +#define HWACCEL_MAX (0)
> > + enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmtp = pix_fmts;
> > VP9Context *s = ctx->priv_data;
> > uint8_t *p;
> > int bytesperpixel = s->bytesperpixel, res;
> > @@ -225,7 +253,16 @@ static int update_size(AVCodecContext *ctx, int w,
> int h)
> >
> > if ((res = ff_set_dimensions(ctx, w, h)) < 0)
> > return res;
> > - s->last_fmt = ctx->pix_fmt = s->pix_fmt;
> > + s->last_fmt = s->pix_fmt;
> > +
> > + *fmtp++ = s->pix_fmt;
> > + *fmtp = AV_PIX_FMT_NONE;
> > +
> > + res = ff_thread_get_format(ctx, pix_fmts);
> > + if (res < 0)
> > + return res;
> > +
> > + ctx->pix_fmt = res;
>
> I should probably move setting s->last_fmt below the get_format call
> to avoid re-introducing the bug of state de-syncing when some other
> error occured.
The state is in s->pix_fmt, not s->last_fmt. s->last_fmt is just "the
previous state" to compare the current state to. If your point is that the
state may be "nothing" on failure, then maybe we should set s->last_fmt to
AV_PIX_FMT_NONE on error (and on init) to make sure it is reinit'ed again...
Ronald
More information about the ffmpeg-devel
mailing list