Merge commit '8a62d2c28f
'
* commit '8a62d2c28f
':
vaapi_encode: Maintain a pool of bitstream output buffers
Merged-by: Hendrik Leppkes <h.leppkes@gmail.com>
This commit is contained in:
commit
724a71dced
2 changed files with 75 additions and 19 deletions
|
@ -178,16 +178,12 @@ static int vaapi_encode_issue(AVCodecContext *avctx,
|
||||||
pic->recon_surface = (VASurfaceID)(uintptr_t)pic->recon_image->data[3];
|
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);
|
av_log(avctx, AV_LOG_DEBUG, "Recon surface is %#x.\n", pic->recon_surface);
|
||||||
|
|
||||||
vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
|
pic->output_buffer_ref = av_buffer_pool_get(ctx->output_buffer_pool);
|
||||||
VAEncCodedBufferType,
|
if (!pic->output_buffer_ref) {
|
||||||
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));
|
|
||||||
err = AVERROR(ENOMEM);
|
err = AVERROR(ENOMEM);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
pic->output_buffer = (VABufferID)(uintptr_t)pic->output_buffer_ref->data;
|
||||||
av_log(avctx, AV_LOG_DEBUG, "Output buffer is %#x.\n",
|
av_log(avctx, AV_LOG_DEBUG, "Output buffer is %#x.\n",
|
||||||
pic->output_buffer);
|
pic->output_buffer);
|
||||||
|
|
||||||
|
@ -438,7 +434,7 @@ static int vaapi_encode_output(AVCodecContext *avctx,
|
||||||
|
|
||||||
err = av_new_packet(pkt, buf->size);
|
err = av_new_packet(pkt, buf->size);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto fail;
|
goto fail_mapped;
|
||||||
|
|
||||||
memcpy(pkt->data, buf->buf, buf->size);
|
memcpy(pkt->data, buf->buf, buf->size);
|
||||||
}
|
}
|
||||||
|
@ -456,35 +452,32 @@ static int vaapi_encode_output(AVCodecContext *avctx,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
vaDestroyBuffer(ctx->hwctx->display, pic->output_buffer);
|
av_buffer_unref(&pic->output_buffer_ref);
|
||||||
pic->output_buffer = VA_INVALID_ID;
|
pic->output_buffer = VA_INVALID_ID;
|
||||||
|
|
||||||
av_log(avctx, AV_LOG_DEBUG, "Output read for pic %"PRId64"/%"PRId64".\n",
|
av_log(avctx, AV_LOG_DEBUG, "Output read for pic %"PRId64"/%"PRId64".\n",
|
||||||
pic->display_order, pic->encode_order);
|
pic->display_order, pic->encode_order);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
fail_mapped:
|
||||||
|
vaUnmapBuffer(ctx->hwctx->display, pic->output_buffer);
|
||||||
fail:
|
fail:
|
||||||
if (pic->output_buffer != VA_INVALID_ID) {
|
av_buffer_unref(&pic->output_buffer_ref);
|
||||||
vaUnmapBuffer(ctx->hwctx->display, pic->output_buffer);
|
pic->output_buffer = VA_INVALID_ID;
|
||||||
vaDestroyBuffer(ctx->hwctx->display, pic->output_buffer);
|
|
||||||
pic->output_buffer = VA_INVALID_ID;
|
|
||||||
}
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vaapi_encode_discard(AVCodecContext *avctx,
|
static int vaapi_encode_discard(AVCodecContext *avctx,
|
||||||
VAAPIEncodePicture *pic)
|
VAAPIEncodePicture *pic)
|
||||||
{
|
{
|
||||||
VAAPIEncodeContext *ctx = avctx->priv_data;
|
|
||||||
|
|
||||||
vaapi_encode_wait(avctx, pic);
|
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 "
|
av_log(avctx, AV_LOG_DEBUG, "Discard output for pic "
|
||||||
"%"PRId64"/%"PRId64".\n",
|
"%"PRId64"/%"PRId64".\n",
|
||||||
pic->display_order, pic->encode_order);
|
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;
|
pic->output_buffer = VA_INVALID_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1025,6 +1018,57 @@ fail:
|
||||||
return err;
|
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,
|
av_cold int ff_vaapi_encode_init(AVCodecContext *avctx,
|
||||||
const VAAPIEncodeType *type)
|
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.
|
// All I are IDR for now.
|
||||||
ctx->i_per_idr = 0;
|
ctx->i_per_idr = 0;
|
||||||
ctx->p_per_i = ((avctx->gop_size + avctx->max_b_frames) /
|
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)
|
if (ctx->codec->close)
|
||||||
ctx->codec->close(avctx);
|
ctx->codec->close(avctx);
|
||||||
|
|
||||||
|
av_buffer_pool_uninit(&ctx->output_buffer_pool);
|
||||||
|
|
||||||
av_freep(&ctx->codec_sequence_params);
|
av_freep(&ctx->codec_sequence_params);
|
||||||
av_freep(&ctx->codec_picture_params);
|
av_freep(&ctx->codec_picture_params);
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,6 @@ enum {
|
||||||
MAX_PARAM_BUFFERS = 16,
|
MAX_PARAM_BUFFERS = 16,
|
||||||
MAX_REORDER_DELAY = 16,
|
MAX_REORDER_DELAY = 16,
|
||||||
MAX_PARAM_BUFFER_SIZE = 1024,
|
MAX_PARAM_BUFFER_SIZE = 1024,
|
||||||
MAX_OUTPUT_BUFFER_SIZE = 1024 * 1024,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -84,6 +83,7 @@ typedef struct VAAPIEncodePicture {
|
||||||
int nb_param_buffers;
|
int nb_param_buffers;
|
||||||
VABufferID param_buffers[MAX_PARAM_BUFFERS];
|
VABufferID param_buffers[MAX_PARAM_BUFFERS];
|
||||||
|
|
||||||
|
AVBufferRef *output_buffer_ref;
|
||||||
VABufferID output_buffer;
|
VABufferID output_buffer;
|
||||||
|
|
||||||
void *priv_data;
|
void *priv_data;
|
||||||
|
@ -130,6 +130,8 @@ typedef struct VAAPIEncodeContext {
|
||||||
AVBufferRef *recon_frames_ref;
|
AVBufferRef *recon_frames_ref;
|
||||||
AVHWFramesContext *recon_frames;
|
AVHWFramesContext *recon_frames;
|
||||||
|
|
||||||
|
AVBufferPool *output_buffer_pool;
|
||||||
|
|
||||||
VAConfigAttrib config_attributes[MAX_CONFIG_ATTRIBUTES];
|
VAConfigAttrib config_attributes[MAX_CONFIG_ATTRIBUTES];
|
||||||
int nb_config_attributes;
|
int nb_config_attributes;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue