static int lavc_va_GetFrame(struct AVCodecContext *ctx, AVFrame *frame, int flags) { decoder_t *dec = ctx->opaque; decoder_sys_t *sys = dec->p_sys; vlc_va_t *va = sys->p_va; if (vlc_va_Setup(va, &ctx->hwaccel_context, &dec->fmt_out.video.i_chroma, ctx->coded_width, ctx->coded_height)) { msg_Err(dec, "hardware acceleration setup failed"); return -1; } if (vlc_va_Get(va, &frame->opaque, &frame->data[0])) { msg_Err(dec, "hardware acceleration picture allocation failed"); return -1; } /* data[0] must be non-NULL for libavcodec internal checks. * data[3] actually contains the format-specific surface handle. */ frame->data[3] = frame->data[0]; frame->buf[0] = av_buffer_create(frame->data[0], 0, va->release, frame->opaque, 0); if (unlikely(frame->buf[0] == NULL)) { vlc_va_Release(va, frame->opaque, frame->data[0]); return -1; } assert(frame->data[0] != NULL); (void) flags; return 0; }
static void ffmpeg_ReleaseFrameBuf( struct AVCodecContext *p_context, AVFrame *p_ff_pic ) { decoder_t *p_dec = (decoder_t *)p_context->opaque; decoder_sys_t *p_sys = p_dec->p_sys; if( p_sys->p_va ) { vlc_va_Release( p_sys->p_va, p_ff_pic ); } else if( !p_ff_pic->opaque ) { /* We can end up here without the AVFrame being allocated by * avcodec_default_get_buffer() if VA is used and the frame is * released when the decoder is closed */ if( p_ff_pic->type == FF_BUFFER_TYPE_INTERNAL ) avcodec_default_release_buffer( p_context, p_ff_pic ); } else { picture_t *p_pic = (picture_t*)p_ff_pic->opaque; decoder_UnlinkPicture( p_dec, p_pic ); } for( int i = 0; i < 4; i++ ) p_ff_pic->data[i] = NULL; }