|
|
@@ -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 { |
|
|
@@ -266,6 +269,14 @@ 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->hwaccel_picture_private = NULL; |
|
|
} |
|
|
|
|
|
static int vp9_alloc_frame(AVCodecContext *ctx, VP9Frame *f) |
|
|
{ |
|
|
VP9Context *s = ctx->priv_data; |
|
|
@@ -275,20 +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); |
|
|
return 0; |
|
|
fail: |
|
|
vp9_unref_frame(ctx, f); |
|
|
return AVERROR(ENOMEM); |
|
|
} |
|
|
|
|
|
static int vp9_ref_frame(AVCodecContext *ctx, VP9Frame *dst, VP9Frame *src) |
|
|
@@ -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) |
|
|
@@ -4056,6 +4083,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); |
|
|
@@ -4225,6 +4265,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]) |
|
|
|