@@ -76,6 +76,9 @@ typedef struct VP9Frame {
7676 uint8_t * segmentation_map ;
7777 struct VP9mvrefPair * mv ;
7878 int uses_2pass ;
79+
80+ AVBufferRef * hwaccel_priv_buf ;
81+ void * hwaccel_picture_private ;
7982} VP9Frame ;
8083
8184struct VP9Filter {
@@ -265,6 +268,15 @@ static const uint8_t bwh_tab[2][N_BS_SIZES][2] = {
265268 }
266269};
267270
271+ static void vp9_unref_frame (AVCodecContext * ctx , VP9Frame * f )
272+ {
273+ ff_thread_release_buffer (ctx , & f -> tf );
274+ av_buffer_unref (& f -> extradata );
275+ av_buffer_unref (& f -> hwaccel_priv_buf );
276+ f -> segmentation_map = NULL ;
277+ f -> hwaccel_picture_private = NULL ;
278+ }
279+
268280static int vp9_alloc_frame (AVCodecContext * ctx , VP9Frame * f )
269281{
270282 VP9Context * s = ctx -> priv_data ;
@@ -274,21 +286,27 @@ static int vp9_alloc_frame(AVCodecContext *ctx, VP9Frame *f)
274286 return ret ;
275287 sz = 64 * s -> sb_cols * s -> sb_rows ;
276288 if (!(f -> extradata = av_buffer_allocz (sz * (1 + sizeof (struct VP9mvrefPair ))))) {
277- ff_thread_release_buffer (ctx , & f -> tf );
278- return AVERROR (ENOMEM );
289+ goto fail ;
279290 }
280291
281292 f -> segmentation_map = f -> extradata -> data ;
282293 f -> mv = (struct VP9mvrefPair * ) (f -> extradata -> data + sz );
283294
284- return 0 ;
285- }
295+ if (ctx -> hwaccel ) {
296+ const AVHWAccel * hwaccel = ctx -> hwaccel ;
297+ av_assert0 (!f -> hwaccel_picture_private );
298+ if (hwaccel -> frame_priv_data_size ) {
299+ f -> hwaccel_priv_buf = av_buffer_allocz (hwaccel -> frame_priv_data_size );
300+ if (!f -> hwaccel_priv_buf )
301+ goto fail ;
302+ f -> hwaccel_picture_private = f -> hwaccel_priv_buf -> data ;
303+ }
304+ }
286305
287- static void vp9_unref_frame (AVCodecContext * ctx , VP9Frame * f )
288- {
289- ff_thread_release_buffer (ctx , & f -> tf );
290- av_buffer_unref (& f -> extradata );
291- f -> segmentation_map = NULL ;
306+ return 0 ;
307+ fail :
308+ vp9_unref_frame (ctx , f );
309+ return AVERROR (ENOMEM );
292310}
293311
294312static 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)
298316 if ((res = ff_thread_ref_frame (& dst -> tf , & src -> tf )) < 0 ) {
299317 return res ;
300318 } else if (!(dst -> extradata = av_buffer_ref (src -> extradata ))) {
301- vp9_unref_frame (ctx , dst );
302- return AVERROR (ENOMEM );
319+ goto fail ;
303320 }
304321
305322 dst -> segmentation_map = src -> segmentation_map ;
306323 dst -> mv = src -> mv ;
307324 dst -> uses_2pass = src -> uses_2pass ;
308325
326+ if (src -> hwaccel_picture_private ) {
327+ dst -> hwaccel_priv_buf = av_buffer_ref (src -> hwaccel_priv_buf );
328+ if (!dst -> hwaccel_priv_buf )
329+ goto fail ;
330+ dst -> hwaccel_picture_private = dst -> hwaccel_priv_buf -> data ;
331+ }
332+
309333 return 0 ;
334+ fail :
335+ vp9_unref_frame (ctx , dst );
336+ return AVERROR (ENOMEM );
310337}
311338
312339static int update_size (AVCodecContext * ctx , int w , int h , enum AVPixelFormat fmt )
@@ -4072,6 +4099,19 @@ static int vp9_decode_frame(AVCodecContext *ctx, void *frame,
40724099 return res ;
40734100 }
40744101
4102+ if (ctx -> hwaccel ) {
4103+ res = ctx -> hwaccel -> start_frame (ctx , NULL , 0 );
4104+ if (res < 0 )
4105+ return res ;
4106+ res = ctx -> hwaccel -> decode_slice (ctx , data , size );
4107+ if (res < 0 )
4108+ return res ;
4109+ res = ctx -> hwaccel -> end_frame (ctx );
4110+ if (res < 0 )
4111+ return res ;
4112+ goto finish ;
4113+ }
4114+
40754115 // main tile decode loop
40764116 bytesperpixel = s -> bytesperpixel ;
40774117 memset (s -> above_partition_ctx , 0 , s -> cols );
@@ -4241,6 +4281,7 @@ static int vp9_decode_frame(AVCodecContext *ctx, void *frame,
42414281 } while (s -> pass ++ == 1 );
42424282 ff_thread_report_progress (& s -> frames [CUR_FRAME ].tf , INT_MAX , 0 );
42434283
4284+ finish :
42444285 // ref frame setup
42454286 for (i = 0 ; i < 8 ; i ++ ) {
42464287 if (s -> refs [i ].f -> data [0 ])
0 commit comments