History

Merge commit '8a62d2c28fbacd1ae20c35887a1eecba2be14371'

* commit '8a62d2c28fbacd1ae20c35887a1eecba2be14371': vaapi_encode: Maintain a pool of bitstream output buffers

Hendrik Leppkes committed 10 years ago

Commit 724a71d2 parents c17563c 8a62d2c2 files · +75 −19Browse files

Unified · Split

2 files
  1. libavcodec/vaapi_encode.c +72 −18
  2. libavcodec/vaapi_encode.h +3 −1
libavcodec/vaapi_encode.c+72−18
@@ -178,16 +178,12 @@ static int vaapi_encode_issue(AVCodecContext *avctx, · 177 unmodified lines
178178 pic->recon_surface = (VASurfaceID)(uintptr_t)pic->recon_image->data[3];
179179 av_log(avctx, AV_LOG_DEBUG, "Recon surface is %#x.\n", pic->recon_surface);
180180
181− vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
182− VAEncCodedBufferType,
183− MAX_OUTPUT_BUFFER_SIZE, 1, 0,
184− &pic->output_buffer);
185− if (vas != VA_STATUS_SUCCESS) {
186− av_log(avctx, AV_LOG_ERROR, "Failed to create bitstream "
187− "output buffer: %d (%s).\n", vas, vaErrorStr(vas));
181+ pic->output_buffer_ref = av_buffer_pool_get(ctx->output_buffer_pool);
182+ if (!pic->output_buffer_ref) {
188183 err = AVERROR(ENOMEM);
189184 goto fail;
190185 }
186+ pic->output_buffer = (VABufferID)(uintptr_t)pic->output_buffer_ref->data;
191187 av_log(avctx, AV_LOG_DEBUG, "Output buffer is %#x.\n",
192188 pic->output_buffer);
193189
@@ -438,7 +434,7 @@ static int vaapi_encode_output(AVCodecContext *avctx, · 244 unmodified lines
438434
439435 err = av_new_packet(pkt, buf->size);
440436 if (err < 0)
441− goto fail;
437+ goto fail_mapped;
442438
443439 memcpy(pkt->data, buf->buf, buf->size);
444440 }
@@ -456,35 +452,32 @@ static int vaapi_encode_output(AVCodecContext *avctx, · 11 unmodified lines
456452 goto fail;
457453 }
458454
459− vaDestroyBuffer(ctx->hwctx->display, pic->output_buffer);
455+ av_buffer_unref(&pic->output_buffer_ref);
460456 pic->output_buffer = VA_INVALID_ID;
461457
462458 av_log(avctx, AV_LOG_DEBUG, "Output read for pic %"PRId64"/%"PRId64".\n",
463459 pic->display_order, pic->encode_order);
464460 return 0;
465461
462+fail_mapped:
463+ vaUnmapBuffer(ctx->hwctx->display, pic->output_buffer);
466464 fail:
467− if (pic->output_buffer != VA_INVALID_ID) {
468− vaUnmapBuffer(ctx->hwctx->display, pic->output_buffer);
469− vaDestroyBuffer(ctx->hwctx->display, pic->output_buffer);
470− pic->output_buffer = VA_INVALID_ID;
471− }
465+ av_buffer_unref(&pic->output_buffer_ref);
466+ pic->output_buffer = VA_INVALID_ID;
472467 return err;
473468 }
474469
475470 static int vaapi_encode_discard(AVCodecContext *avctx,
476471 VAAPIEncodePicture *pic)
477472 {
478− VAAPIEncodeContext *ctx = avctx->priv_data;
479−
480473 vaapi_encode_wait(avctx, pic);
481474
482− if (pic->output_buffer != VA_INVALID_ID) {
475+ if (pic->output_buffer_ref) {
483476 av_log(avctx, AV_LOG_DEBUG, "Discard output for pic "
484477 "%"PRId64"/%"PRId64".\n",
485478 pic->display_order, pic->encode_order);
486479
487− vaDestroyBuffer(ctx->hwctx->display, pic->output_buffer);
480+ av_buffer_unref(&pic->output_buffer_ref);
488481 pic->output_buffer = VA_INVALID_ID;
489482 }
490483
@@ -1025,6 +1018,57 @@ fail: · 534 unmodified lines
10251018 return err;
10261019 }
10271020
1021+static void vaapi_encode_free_output_buffer(void *opaque,
1022+ uint8_t *data)
1023+{
1024+ AVCodecContext *avctx = opaque;
1025+ VAAPIEncodeContext *ctx = avctx->priv_data;
1026+ VABufferID buffer_id;
1027+
1028+ buffer_id = (VABufferID)(uintptr_t)data;
1029+
1030+ vaDestroyBuffer(ctx->hwctx->display, buffer_id);
1031+
1032+ av_log(avctx, AV_LOG_DEBUG, "Freed output buffer %#x\n", buffer_id);
1033+}
1034+
1035+static AVBufferRef *vaapi_encode_alloc_output_buffer(void *opaque,
1036+ int size)
1037+{
1038+ AVCodecContext *avctx = opaque;
1039+ VAAPIEncodeContext *ctx = avctx->priv_data;
1040+ VABufferID buffer_id;
1041+ VAStatus vas;
1042+ AVBufferRef *ref;
1043+
1044+ // The output buffer size is fixed, so it needs to be large enough
1045+ // to hold the largest possible compressed frame. We assume here
1046+ // that the uncompressed frame plus some header data is an upper
1047+ // bound on that.
1048+ vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
1049+ VAEncCodedBufferType,
1050+ 3 * ctx->aligned_width * ctx->aligned_height +
1051+ (1 << 16), 1, 0, &buffer_id);
1052+ if (vas != VA_STATUS_SUCCESS) {
1053+ av_log(avctx, AV_LOG_ERROR, "Failed to create bitstream "
1054+ "output buffer: %d (%s).\n", vas, vaErrorStr(vas));
1055+ return NULL;
1056+ }
1057+
1058+ av_log(avctx, AV_LOG_DEBUG, "Allocated output buffer %#x\n", buffer_id);
1059+
1060+ ref = av_buffer_create((uint8_t*)(uintptr_t)buffer_id,
1061+ sizeof(buffer_id),
1062+ &vaapi_encode_free_output_buffer,
1063+ avctx, AV_BUFFER_FLAG_READONLY);
1064+ if (!ref) {
1065+ vaDestroyBuffer(ctx->hwctx->display, buffer_id);
1066+ return NULL;
1067+ }
1068+
1069+ return ref;
1070+}
1071+
10281072 av_cold int ff_vaapi_encode_init(AVCodecContext *avctx,
10291073 const VAAPIEncodeType *type)
10301074 {
@@ -1207,6 +1251,14 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx, · 176 unmodified lines
12071251 }
12081252 }
12091253
1254+ ctx->output_buffer_pool =
1255+ av_buffer_pool_init2(sizeof(VABufferID), avctx,
1256+ &vaapi_encode_alloc_output_buffer, NULL);
1257+ if (!ctx->output_buffer_pool) {
1258+ err = AVERROR(ENOMEM);
1259+ goto fail;
1260+ }
1261+
12101262 // All I are IDR for now.
12111263 ctx->i_per_idr = 0;
12121264 ctx->p_per_i = ((avctx->gop_size + avctx->max_b_frames) /
@@ -1249,6 +1301,8 @@ av_cold int ff_vaapi_encode_close(AVCodecContext *avctx) · 36 unmodified lines
12491301 if (ctx->codec->close)
12501302 ctx->codec->close(avctx);
12511303
1304+ av_buffer_pool_uninit(&ctx->output_buffer_pool);
1305+
12521306 av_freep(&ctx->codec_sequence_params);
12531307 av_freep(&ctx->codec_picture_params);
12541308
libavcodec/vaapi_encode.h+3−1
@@ -39,7 +39,6 @@ enum { · 38 unmodified lines
3939 MAX_PARAM_BUFFERS = 16,
4040 MAX_REORDER_DELAY = 16,
4141 MAX_PARAM_BUFFER_SIZE = 1024,
42− MAX_OUTPUT_BUFFER_SIZE = 1024 * 1024,
4342 };
4443
4544 enum {
@@ -84,6 +83,7 @@ typedef struct VAAPIEncodePicture { · 38 unmodified lines
8483 int nb_param_buffers;
8584 VABufferID param_buffers[MAX_PARAM_BUFFERS];
8685
86+ AVBufferRef *output_buffer_ref;
8787 VABufferID output_buffer;
8888
8989 void *priv_data;
@@ -130,6 +130,8 @@ typedef struct VAAPIEncodeContext { · 40 unmodified lines
130130 AVBufferRef *recon_frames_ref;
131131 AVHWFramesContext *recon_frames;
132132
133+ AVBufferPool *output_buffer_pool;
134+
133135 VAConfigAttrib config_attributes[MAX_CONFIG_ATTRIBUTES];
134136 int nb_config_attributes;
135137

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t