Skip to content

Commit

Permalink
avcodec/vp9: Add hwaccel hooks for VP9
Browse files Browse the repository at this point in the history
  • Loading branch information
philipl authored and BtbN committed Oct 12, 2015
1 parent cf28490 commit 0d50fb0
Showing 1 changed file with 52 additions and 11 deletions.
63 changes: 52 additions & 11 deletions libavcodec/vp9.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ typedef struct VP9Frame {
uint8_t *segmentation_map;
struct VP9mvrefPair *mv;
int uses_2pass;

AVBufferRef *hwaccel_priv_buf;
void *hwaccel_picture_private;
} VP9Frame;

struct VP9Filter {
Expand Down Expand Up @@ -265,6 +268,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;
Expand All @@ -274,21 +286,27 @@ 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);

return 0;
}
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;
}
}

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;
return 0;
fail:
vp9_unref_frame(ctx, f);
return AVERROR(ENOMEM);
}

static int vp9_ref_frame(AVCodecContext *ctx, VP9Frame *dst, VP9Frame *src)
Expand All @@ -298,15 +316,24 @@ 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, enum AVPixelFormat fmt)
Expand Down Expand Up @@ -4072,6 +4099,19 @@ static int vp9_decode_frame(AVCodecContext *ctx, void *frame,
return res;
}

if (ctx->hwaccel) {
res = ctx->hwaccel->start_frame(ctx, NULL, 0);
if (res < 0)
return res;
res = ctx->hwaccel->decode_slice(ctx, data, size);
if (res < 0)
return res;
res = ctx->hwaccel->end_frame(ctx);
if (res < 0)
return res;
goto finish;
}

// main tile decode loop
bytesperpixel = s->bytesperpixel;
memset(s->above_partition_ctx, 0, s->cols);
Expand Down Expand Up @@ -4241,6 +4281,7 @@ static int vp9_decode_frame(AVCodecContext *ctx, void *frame,
} while (s->pass++ == 1);
ff_thread_report_progress(&s->frames[CUR_FRAME].tf, INT_MAX, 0);

finish:
// ref frame setup
for (i = 0; i < 8; i++) {
if (s->refs[i].f->data[0])
Expand Down

0 comments on commit 0d50fb0

Please sign in to comment.