Skip to content

Commit 11ff580

Browse files
committed
vp9: add hwaccel hooks
1 parent 2fde35e commit 11ff580

File tree

2 files changed

+75
-13
lines changed

2 files changed

+75
-13
lines changed

libavcodec/vp9.c

Lines changed: 72 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,15 @@ static const uint8_t bwh_tab[2][N_BS_SIZES][2] = {
167167
}
168168
};
169169

170+
static void vp9_unref_frame(AVCodecContext *ctx, VP9Frame *f)
171+
{
172+
ff_thread_release_buffer(ctx, &f->tf);
173+
av_buffer_unref(&f->extradata);
174+
av_buffer_unref(&f->hwaccel_priv_buf);
175+
f->segmentation_map = NULL;
176+
f->hwaccel_picture_private = NULL;
177+
}
178+
170179
static int vp9_alloc_frame(AVCodecContext *ctx, VP9Frame *f)
171180
{
172181
VP9Context *s = ctx->priv_data;
@@ -176,21 +185,28 @@ static int vp9_alloc_frame(AVCodecContext *ctx, VP9Frame *f)
176185
return ret;
177186
sz = 64 * s->sb_cols * s->sb_rows;
178187
if (!(f->extradata = av_buffer_allocz(sz * (1 + sizeof(struct VP9mvrefPair))))) {
179-
ff_thread_release_buffer(ctx, &f->tf);
180-
return AVERROR(ENOMEM);
188+
goto fail;
181189
}
182190

183191
f->segmentation_map = f->extradata->data;
184192
f->mv = (struct VP9mvrefPair *) (f->extradata->data + sz);
185193

194+
if (ctx->hwaccel) {
195+
const AVHWAccel *hwaccel = ctx->hwaccel;
196+
av_assert0(!f->hwaccel_picture_private);
197+
if (hwaccel->frame_priv_data_size) {
198+
f->hwaccel_priv_buf = av_buffer_allocz(hwaccel->frame_priv_data_size);
199+
if (!f->hwaccel_priv_buf)
200+
goto fail;
201+
f->hwaccel_picture_private = f->hwaccel_priv_buf->data;
202+
}
203+
}
204+
186205
return 0;
187-
}
188206

189-
static void vp9_unref_frame(AVCodecContext *ctx, VP9Frame *f)
190-
{
191-
ff_thread_release_buffer(ctx, &f->tf);
192-
av_buffer_unref(&f->extradata);
193-
f->segmentation_map = NULL;
207+
fail:
208+
vp9_unref_frame(ctx, f);
209+
return AVERROR(ENOMEM);
194210
}
195211

196212
static int vp9_ref_frame(AVCodecContext *ctx, VP9Frame *dst, VP9Frame *src)
@@ -200,30 +216,59 @@ static int vp9_ref_frame(AVCodecContext *ctx, VP9Frame *dst, VP9Frame *src)
200216
if ((res = ff_thread_ref_frame(&dst->tf, &src->tf)) < 0) {
201217
return res;
202218
} else if (!(dst->extradata = av_buffer_ref(src->extradata))) {
203-
vp9_unref_frame(ctx, dst);
204-
return AVERROR(ENOMEM);
219+
goto fail;
205220
}
206221

207222
dst->segmentation_map = src->segmentation_map;
208223
dst->mv = src->mv;
209224
dst->uses_2pass = src->uses_2pass;
210225

226+
if (src->hwaccel_picture_private) {
227+
dst->hwaccel_priv_buf = av_buffer_ref(src->hwaccel_priv_buf);
228+
if (!dst->hwaccel_priv_buf)
229+
goto fail;
230+
dst->hwaccel_picture_private = dst->hwaccel_priv_buf->data;
231+
}
232+
211233
return 0;
234+
235+
fail:
236+
vp9_unref_frame(ctx, dst);
237+
return AVERROR(ENOMEM);
212238
}
213239

214240
static int update_size(AVCodecContext *ctx, int w, int h, enum AVPixelFormat fmt)
215241
{
242+
#define HWACCEL_MAX (CONFIG_VP9_DXVA2_HWACCEL + CONFIG_VP9_D3D11VA_HWACCEL)
243+
enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmtp = pix_fmts;
216244
VP9Context *s = ctx->priv_data;
217245
uint8_t *p;
218246
int bytesperpixel = s->bytesperpixel;
219247

220248
av_assert0(w > 0 && h > 0);
221249

222-
if (s->intra_pred_data[0] && w == ctx->width && h == ctx->height && ctx->pix_fmt == fmt)
250+
if (s->intra_pred_data[0] && w == ctx->width && h == ctx->height && (ctx->pix_fmt == fmt || (ctx->hwaccel && ctx->sw_pix_fmt == fmt)))
223251
return 0;
224252

225-
ctx->width = w;
226-
ctx->height = h;
253+
ctx->coded_width = ctx->width = w;
254+
ctx->coded_height = ctx->height = h;
255+
256+
if (fmt == AV_PIX_FMT_YUV420P) {
257+
#if CONFIG_VP9_DXVA2_HWACCEL
258+
*fmtp++ = AV_PIX_FMT_DXVA2_VLD;
259+
#endif
260+
#if CONFIG_VP9_D3D11VA_HWACCEL
261+
*fmtp++ = AV_PIX_FMT_D3D11VA_VLD;
262+
#endif
263+
}
264+
265+
*fmtp++ = fmt;
266+
*fmtp = AV_PIX_FMT_NONE;
267+
268+
fmt = ff_thread_get_format(ctx, pix_fmts);
269+
if (fmt < 0)
270+
return fmt;
271+
227272
ctx->pix_fmt = fmt;
228273
s->sb_cols = (w + 63) >> 6;
229274
s->sb_rows = (h + 63) >> 6;
@@ -3978,6 +4023,19 @@ static int vp9_decode_frame(AVCodecContext *ctx, void *frame,
39784023
return res;
39794024
}
39804025

4026+
if (ctx->hwaccel) {
4027+
res = ctx->hwaccel->start_frame(ctx, NULL, 0);
4028+
if (res < 0)
4029+
return res;
4030+
res = ctx->hwaccel->decode_slice(ctx, pkt->data, pkt->size);
4031+
if (res < 0)
4032+
return res;
4033+
res = ctx->hwaccel->end_frame(ctx);
4034+
if (res < 0)
4035+
return res;
4036+
goto finish;
4037+
}
4038+
39814039
// main tile decode loop
39824040
bytesperpixel = s->bytesperpixel;
39834041
memset(s->above_partition_ctx, 0, s->cols);
@@ -4147,6 +4205,7 @@ static int vp9_decode_frame(AVCodecContext *ctx, void *frame,
41474205
} while (s->pass++ == 1);
41484206
ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0);
41494207

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

libavcodec/vp9.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,9 @@ typedef struct VP9Frame {
129129
uint8_t *segmentation_map;
130130
struct VP9mvrefPair *mv;
131131
int uses_2pass;
132+
133+
AVBufferRef *hwaccel_priv_buf;
134+
void *hwaccel_picture_private;
132135
} VP9Frame;
133136

134137
typedef struct VP9BitstreamHeader {

0 commit comments

Comments
 (0)