@ -178,16 +178,12 @@ static int vaapi_encode_issue(AVCodecContext *avctx,
pic - > recon_surface = ( VASurfaceID ) ( uintptr_t ) pic - > recon_image - > data [ 3 ] ;
av_log ( avctx , AV_LOG_DEBUG , " Recon surface is %#x. \n " , pic - > recon_surface ) ;
vas = vaCreateBuffer ( ctx - > hwctx - > display , ctx - > va_context ,
VAEncCodedBufferType ,
MAX_OUTPUT_BUFFER_SIZE , 1 , 0 ,
& pic - > output_buffer ) ;
if ( vas ! = VA_STATUS_SUCCESS ) {
av_log ( avctx , AV_LOG_ERROR , " Failed to create bitstream "
" output buffer: %d (%s). \n " , vas , vaErrorStr ( vas ) ) ;
pic - > output_buffer_ref = av_buffer_pool_get ( ctx - > output_buffer_pool ) ;
if ( ! pic - > output_buffer_ref ) {
err = AVERROR ( ENOMEM ) ;
goto fail ;
}
pic - > output_buffer = ( VABufferID ) ( uintptr_t ) pic - > output_buffer_ref - > data ;
av_log ( avctx , AV_LOG_DEBUG , " Output buffer is %#x. \n " ,
pic - > output_buffer ) ;
@ -438,7 +434,7 @@ static int vaapi_encode_output(AVCodecContext *avctx,
err = av_new_packet ( pkt , buf - > size ) ;
if ( err < 0 )
goto fail ;
goto fail_mapped ;
memcpy ( pkt - > data , buf - > buf , buf - > size ) ;
}
@ -456,35 +452,32 @@ static int vaapi_encode_output(AVCodecContext *avctx,
goto fail ;
}
vaDestroyBuffer ( ctx - > hwctx - > display , pic - > output_buffer ) ;
av_buffer_unref ( & pic - > output_buffer_ref ) ;
pic - > output_buffer = VA_INVALID_ID ;
av_log ( avctx , AV_LOG_DEBUG , " Output read for pic % " PRId64 " /% " PRId64 " . \n " ,
pic - > display_order , pic - > encode_order ) ;
return 0 ;
fail_mapped :
vaUnmapBuffer ( ctx - > hwctx - > display , pic - > output_buffer ) ;
fail :
if ( pic - > output_buffer ! = VA_INVALID_ID ) {
vaUnmapBuffer ( ctx - > hwctx - > display , pic - > output_buffer ) ;
vaDestroyBuffer ( ctx - > hwctx - > display , pic - > output_buffer ) ;
pic - > output_buffer = VA_INVALID_ID ;
}
av_buffer_unref ( & pic - > output_buffer_ref ) ;
pic - > output_buffer = VA_INVALID_ID ;
return err ;
}
static int vaapi_encode_discard ( AVCodecContext * avctx ,
VAAPIEncodePicture * pic )
{
VAAPIEncodeContext * ctx = avctx - > priv_data ;
vaapi_encode_wait ( avctx , pic ) ;
if ( pic - > output_buffer ! = VA_INVALID_ID ) {
if ( pic - > output_buffer_ref ) {
av_log ( avctx , AV_LOG_DEBUG , " Discard output for pic "
" % " PRId64 " /% " PRId64 " . \n " ,
pic - > display_order , pic - > encode_order ) ;
vaDestroyBuffer ( ctx - > hwctx - > display , pic - > output_buffer ) ;
av_buffer_unref ( & pic - > output_buffer_ref ) ;
pic - > output_buffer = VA_INVALID_ID ;
}
@ -1025,6 +1018,57 @@ fail:
return err ;
}
static void vaapi_encode_free_output_buffer ( void * opaque ,
uint8_t * data )
{
AVCodecContext * avctx = opaque ;
VAAPIEncodeContext * ctx = avctx - > priv_data ;
VABufferID buffer_id ;
buffer_id = ( VABufferID ) ( uintptr_t ) data ;
vaDestroyBuffer ( ctx - > hwctx - > display , buffer_id ) ;
av_log ( avctx , AV_LOG_DEBUG , " Freed output buffer %#x \n " , buffer_id ) ;
}
static AVBufferRef * vaapi_encode_alloc_output_buffer ( void * opaque ,
int size )
{
AVCodecContext * avctx = opaque ;
VAAPIEncodeContext * ctx = avctx - > priv_data ;
VABufferID buffer_id ;
VAStatus vas ;
AVBufferRef * ref ;
// The output buffer size is fixed, so it needs to be large enough
// to hold the largest possible compressed frame. We assume here
// that the uncompressed frame plus some header data is an upper
// bound on that.
vas = vaCreateBuffer ( ctx - > hwctx - > display , ctx - > va_context ,
VAEncCodedBufferType ,
3 * ctx - > aligned_width * ctx - > aligned_height +
( 1 < < 16 ) , 1 , 0 , & buffer_id ) ;
if ( vas ! = VA_STATUS_SUCCESS ) {
av_log ( avctx , AV_LOG_ERROR , " Failed to create bitstream "
" output buffer: %d (%s). \n " , vas , vaErrorStr ( vas ) ) ;
return NULL ;
}
av_log ( avctx , AV_LOG_DEBUG , " Allocated output buffer %#x \n " , buffer_id ) ;
ref = av_buffer_create ( ( uint8_t * ) ( uintptr_t ) buffer_id ,
sizeof ( buffer_id ) ,
& vaapi_encode_free_output_buffer ,
avctx , AV_BUFFER_FLAG_READONLY ) ;
if ( ! ref ) {
vaDestroyBuffer ( ctx - > hwctx - > display , buffer_id ) ;
return NULL ;
}
return ref ;
}
av_cold int ff_vaapi_encode_init ( AVCodecContext * avctx ,
const VAAPIEncodeType * type )
{
@ -1207,6 +1251,14 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx,
}
}
ctx - > output_buffer_pool =
av_buffer_pool_init2 ( sizeof ( VABufferID ) , avctx ,
& vaapi_encode_alloc_output_buffer , NULL ) ;
if ( ! ctx - > output_buffer_pool ) {
err = AVERROR ( ENOMEM ) ;
goto fail ;
}
// All I are IDR for now.
ctx - > i_per_idr = 0 ;
ctx - > p_per_i = ( ( avctx - > gop_size + avctx - > max_b_frames ) /
@ -1249,6 +1301,8 @@ av_cold int ff_vaapi_encode_close(AVCodecContext *avctx)
if ( ctx - > codec - > close )
ctx - > codec - > close ( avctx ) ;
av_buffer_pool_uninit ( & ctx - > output_buffer_pool ) ;
av_freep ( & ctx - > codec_sequence_params ) ;
av_freep ( & ctx - > codec_picture_params ) ;