You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2422 lines
82KB

  1. /*
  2. * This file is part of FFmpeg.
  3. *
  4. * FFmpeg is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2.1 of the License, or (at your option) any later version.
  8. *
  9. * FFmpeg is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public
  15. * License along with FFmpeg; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. #include <inttypes.h>
  19. #include <string.h>
  20. #include "libavutil/avassert.h"
  21. #include "libavutil/common.h"
  22. #include "libavutil/log.h"
  23. #include "libavutil/pixdesc.h"
  24. #include "vaapi_encode.h"
  25. #include "encode.h"
  26. #include "avcodec.h"
  27. const AVCodecHWConfigInternal *ff_vaapi_encode_hw_configs[] = {
  28. HW_CONFIG_ENCODER_FRAMES(VAAPI, VAAPI),
  29. NULL,
  30. };
  31. static const char * const picture_type_name[] = { "IDR", "I", "P", "B" };
  32. static int vaapi_encode_make_packed_header(AVCodecContext *avctx,
  33. VAAPIEncodePicture *pic,
  34. int type, char *data, size_t bit_len)
  35. {
  36. VAAPIEncodeContext *ctx = avctx->priv_data;
  37. VAStatus vas;
  38. VABufferID param_buffer, data_buffer;
  39. VABufferID *tmp;
  40. VAEncPackedHeaderParameterBuffer params = {
  41. .type = type,
  42. .bit_length = bit_len,
  43. .has_emulation_bytes = 1,
  44. };
  45. tmp = av_realloc_array(pic->param_buffers, sizeof(*tmp), pic->nb_param_buffers + 2);
  46. if (!tmp)
  47. return AVERROR(ENOMEM);
  48. pic->param_buffers = tmp;
  49. vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
  50. VAEncPackedHeaderParameterBufferType,
  51. sizeof(params), 1, &params, &param_buffer);
  52. if (vas != VA_STATUS_SUCCESS) {
  53. av_log(avctx, AV_LOG_ERROR, "Failed to create parameter buffer "
  54. "for packed header (type %d): %d (%s).\n",
  55. type, vas, vaErrorStr(vas));
  56. return AVERROR(EIO);
  57. }
  58. pic->param_buffers[pic->nb_param_buffers++] = param_buffer;
  59. vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
  60. VAEncPackedHeaderDataBufferType,
  61. (bit_len + 7) / 8, 1, data, &data_buffer);
  62. if (vas != VA_STATUS_SUCCESS) {
  63. av_log(avctx, AV_LOG_ERROR, "Failed to create data buffer "
  64. "for packed header (type %d): %d (%s).\n",
  65. type, vas, vaErrorStr(vas));
  66. return AVERROR(EIO);
  67. }
  68. pic->param_buffers[pic->nb_param_buffers++] = data_buffer;
  69. av_log(avctx, AV_LOG_DEBUG, "Packed header buffer (%d) is %#x/%#x "
  70. "(%zu bits).\n", type, param_buffer, data_buffer, bit_len);
  71. return 0;
  72. }
  73. static int vaapi_encode_make_param_buffer(AVCodecContext *avctx,
  74. VAAPIEncodePicture *pic,
  75. int type, char *data, size_t len)
  76. {
  77. VAAPIEncodeContext *ctx = avctx->priv_data;
  78. VAStatus vas;
  79. VABufferID *tmp;
  80. VABufferID buffer;
  81. tmp = av_realloc_array(pic->param_buffers, sizeof(*tmp), pic->nb_param_buffers + 1);
  82. if (!tmp)
  83. return AVERROR(ENOMEM);
  84. pic->param_buffers = tmp;
  85. vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
  86. type, len, 1, data, &buffer);
  87. if (vas != VA_STATUS_SUCCESS) {
  88. av_log(avctx, AV_LOG_ERROR, "Failed to create parameter buffer "
  89. "(type %d): %d (%s).\n", type, vas, vaErrorStr(vas));
  90. return AVERROR(EIO);
  91. }
  92. pic->param_buffers[pic->nb_param_buffers++] = buffer;
  93. av_log(avctx, AV_LOG_DEBUG, "Param buffer (%d) is %#x.\n",
  94. type, buffer);
  95. return 0;
  96. }
  97. static int vaapi_encode_make_misc_param_buffer(AVCodecContext *avctx,
  98. VAAPIEncodePicture *pic,
  99. int type,
  100. const void *data, size_t len)
  101. {
  102. // Construct the buffer on the stack - 1KB is much larger than any
  103. // current misc parameter buffer type (the largest is EncQuality at
  104. // 224 bytes).
  105. uint8_t buffer[1024];
  106. VAEncMiscParameterBuffer header = {
  107. .type = type,
  108. };
  109. size_t buffer_size = sizeof(header) + len;
  110. av_assert0(buffer_size <= sizeof(buffer));
  111. memcpy(buffer, &header, sizeof(header));
  112. memcpy(buffer + sizeof(header), data, len);
  113. return vaapi_encode_make_param_buffer(avctx, pic,
  114. VAEncMiscParameterBufferType,
  115. buffer, buffer_size);
  116. }
  117. static int vaapi_encode_wait(AVCodecContext *avctx,
  118. VAAPIEncodePicture *pic)
  119. {
  120. VAAPIEncodeContext *ctx = avctx->priv_data;
  121. VAStatus vas;
  122. av_assert0(pic->encode_issued);
  123. if (pic->encode_complete) {
  124. // Already waited for this picture.
  125. return 0;
  126. }
  127. av_log(avctx, AV_LOG_DEBUG, "Sync to pic %"PRId64"/%"PRId64" "
  128. "(input surface %#x).\n", pic->display_order,
  129. pic->encode_order, pic->input_surface);
  130. vas = vaSyncSurface(ctx->hwctx->display, pic->input_surface);
  131. if (vas != VA_STATUS_SUCCESS) {
  132. av_log(avctx, AV_LOG_ERROR, "Failed to sync to picture completion: "
  133. "%d (%s).\n", vas, vaErrorStr(vas));
  134. return AVERROR(EIO);
  135. }
  136. // Input is definitely finished with now.
  137. av_frame_free(&pic->input_image);
  138. pic->encode_complete = 1;
  139. return 0;
  140. }
  141. static int vaapi_encode_issue(AVCodecContext *avctx,
  142. VAAPIEncodePicture *pic)
  143. {
  144. VAAPIEncodeContext *ctx = avctx->priv_data;
  145. VAAPIEncodeSlice *slice;
  146. VAStatus vas;
  147. int err, i;
  148. char data[MAX_PARAM_BUFFER_SIZE];
  149. size_t bit_len;
  150. av_unused AVFrameSideData *sd;
  151. av_log(avctx, AV_LOG_DEBUG, "Issuing encode for pic %"PRId64"/%"PRId64" "
  152. "as type %s.\n", pic->display_order, pic->encode_order,
  153. picture_type_name[pic->type]);
  154. if (pic->nb_refs == 0) {
  155. av_log(avctx, AV_LOG_DEBUG, "No reference pictures.\n");
  156. } else {
  157. av_log(avctx, AV_LOG_DEBUG, "Refers to:");
  158. for (i = 0; i < pic->nb_refs; i++) {
  159. av_log(avctx, AV_LOG_DEBUG, " %"PRId64"/%"PRId64,
  160. pic->refs[i]->display_order, pic->refs[i]->encode_order);
  161. }
  162. av_log(avctx, AV_LOG_DEBUG, ".\n");
  163. }
  164. av_assert0(!pic->encode_issued);
  165. for (i = 0; i < pic->nb_refs; i++) {
  166. av_assert0(pic->refs[i]);
  167. av_assert0(pic->refs[i]->encode_issued);
  168. }
  169. av_log(avctx, AV_LOG_DEBUG, "Input surface is %#x.\n", pic->input_surface);
  170. pic->recon_image = av_frame_alloc();
  171. if (!pic->recon_image) {
  172. err = AVERROR(ENOMEM);
  173. goto fail;
  174. }
  175. err = av_hwframe_get_buffer(ctx->recon_frames_ref, pic->recon_image, 0);
  176. if (err < 0) {
  177. err = AVERROR(ENOMEM);
  178. goto fail;
  179. }
  180. pic->recon_surface = (VASurfaceID)(uintptr_t)pic->recon_image->data[3];
  181. av_log(avctx, AV_LOG_DEBUG, "Recon surface is %#x.\n", pic->recon_surface);
  182. pic->output_buffer_ref = av_buffer_pool_get(ctx->output_buffer_pool);
  183. if (!pic->output_buffer_ref) {
  184. err = AVERROR(ENOMEM);
  185. goto fail;
  186. }
  187. pic->output_buffer = (VABufferID)(uintptr_t)pic->output_buffer_ref->data;
  188. av_log(avctx, AV_LOG_DEBUG, "Output buffer is %#x.\n",
  189. pic->output_buffer);
  190. if (ctx->codec->picture_params_size > 0) {
  191. pic->codec_picture_params = av_malloc(ctx->codec->picture_params_size);
  192. if (!pic->codec_picture_params)
  193. goto fail;
  194. memcpy(pic->codec_picture_params, ctx->codec_picture_params,
  195. ctx->codec->picture_params_size);
  196. } else {
  197. av_assert0(!ctx->codec_picture_params);
  198. }
  199. pic->nb_param_buffers = 0;
  200. if (pic->type == PICTURE_TYPE_IDR && ctx->codec->init_sequence_params) {
  201. err = vaapi_encode_make_param_buffer(avctx, pic,
  202. VAEncSequenceParameterBufferType,
  203. ctx->codec_sequence_params,
  204. ctx->codec->sequence_params_size);
  205. if (err < 0)
  206. goto fail;
  207. }
  208. if (pic->type == PICTURE_TYPE_IDR) {
  209. for (i = 0; i < ctx->nb_global_params; i++) {
  210. err = vaapi_encode_make_misc_param_buffer(avctx, pic,
  211. ctx->global_params_type[i],
  212. ctx->global_params[i],
  213. ctx->global_params_size[i]);
  214. if (err < 0)
  215. goto fail;
  216. }
  217. }
  218. if (ctx->codec->init_picture_params) {
  219. err = ctx->codec->init_picture_params(avctx, pic);
  220. if (err < 0) {
  221. av_log(avctx, AV_LOG_ERROR, "Failed to initialise picture "
  222. "parameters: %d.\n", err);
  223. goto fail;
  224. }
  225. err = vaapi_encode_make_param_buffer(avctx, pic,
  226. VAEncPictureParameterBufferType,
  227. pic->codec_picture_params,
  228. ctx->codec->picture_params_size);
  229. if (err < 0)
  230. goto fail;
  231. }
  232. if (pic->type == PICTURE_TYPE_IDR) {
  233. if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
  234. ctx->codec->write_sequence_header) {
  235. bit_len = 8 * sizeof(data);
  236. err = ctx->codec->write_sequence_header(avctx, data, &bit_len);
  237. if (err < 0) {
  238. av_log(avctx, AV_LOG_ERROR, "Failed to write per-sequence "
  239. "header: %d.\n", err);
  240. goto fail;
  241. }
  242. err = vaapi_encode_make_packed_header(avctx, pic,
  243. ctx->codec->sequence_header_type,
  244. data, bit_len);
  245. if (err < 0)
  246. goto fail;
  247. }
  248. }
  249. if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_PICTURE &&
  250. ctx->codec->write_picture_header) {
  251. bit_len = 8 * sizeof(data);
  252. err = ctx->codec->write_picture_header(avctx, pic, data, &bit_len);
  253. if (err < 0) {
  254. av_log(avctx, AV_LOG_ERROR, "Failed to write per-picture "
  255. "header: %d.\n", err);
  256. goto fail;
  257. }
  258. err = vaapi_encode_make_packed_header(avctx, pic,
  259. ctx->codec->picture_header_type,
  260. data, bit_len);
  261. if (err < 0)
  262. goto fail;
  263. }
  264. if (ctx->codec->write_extra_buffer) {
  265. for (i = 0;; i++) {
  266. size_t len = sizeof(data);
  267. int type;
  268. err = ctx->codec->write_extra_buffer(avctx, pic, i, &type,
  269. data, &len);
  270. if (err == AVERROR_EOF)
  271. break;
  272. if (err < 0) {
  273. av_log(avctx, AV_LOG_ERROR, "Failed to write extra "
  274. "buffer %d: %d.\n", i, err);
  275. goto fail;
  276. }
  277. err = vaapi_encode_make_param_buffer(avctx, pic, type,
  278. data, len);
  279. if (err < 0)
  280. goto fail;
  281. }
  282. }
  283. if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_MISC &&
  284. ctx->codec->write_extra_header) {
  285. for (i = 0;; i++) {
  286. int type;
  287. bit_len = 8 * sizeof(data);
  288. err = ctx->codec->write_extra_header(avctx, pic, i, &type,
  289. data, &bit_len);
  290. if (err == AVERROR_EOF)
  291. break;
  292. if (err < 0) {
  293. av_log(avctx, AV_LOG_ERROR, "Failed to write extra "
  294. "header %d: %d.\n", i, err);
  295. goto fail;
  296. }
  297. err = vaapi_encode_make_packed_header(avctx, pic, type,
  298. data, bit_len);
  299. if (err < 0)
  300. goto fail;
  301. }
  302. }
  303. if (pic->nb_slices == 0)
  304. pic->nb_slices = ctx->nb_slices;
  305. if (pic->nb_slices > 0) {
  306. int rounding;
  307. pic->slices = av_mallocz_array(pic->nb_slices, sizeof(*pic->slices));
  308. if (!pic->slices) {
  309. err = AVERROR(ENOMEM);
  310. goto fail;
  311. }
  312. for (i = 0; i < pic->nb_slices; i++)
  313. pic->slices[i].row_size = ctx->slice_size;
  314. rounding = ctx->slice_block_rows - ctx->nb_slices * ctx->slice_size;
  315. if (rounding > 0) {
  316. // Place rounding error at top and bottom of frame.
  317. av_assert0(rounding < pic->nb_slices);
  318. // Some Intel drivers contain a bug where the encoder will fail
  319. // if the last slice is smaller than the one before it. Since
  320. // that's straightforward to avoid here, just do so.
  321. if (rounding <= 2) {
  322. for (i = 0; i < rounding; i++)
  323. ++pic->slices[i].row_size;
  324. } else {
  325. for (i = 0; i < (rounding + 1) / 2; i++)
  326. ++pic->slices[pic->nb_slices - i - 1].row_size;
  327. for (i = 0; i < rounding / 2; i++)
  328. ++pic->slices[i].row_size;
  329. }
  330. } else if (rounding < 0) {
  331. // Remove rounding error from last slice only.
  332. av_assert0(rounding < ctx->slice_size);
  333. pic->slices[pic->nb_slices - 1].row_size += rounding;
  334. }
  335. }
  336. for (i = 0; i < pic->nb_slices; i++) {
  337. slice = &pic->slices[i];
  338. slice->index = i;
  339. if (i == 0) {
  340. slice->row_start = 0;
  341. slice->block_start = 0;
  342. } else {
  343. const VAAPIEncodeSlice *prev = &pic->slices[i - 1];
  344. slice->row_start = prev->row_start + prev->row_size;
  345. slice->block_start = prev->block_start + prev->block_size;
  346. }
  347. slice->block_size = slice->row_size * ctx->slice_block_cols;
  348. av_log(avctx, AV_LOG_DEBUG, "Slice %d: %d-%d (%d rows), "
  349. "%d-%d (%d blocks).\n", i, slice->row_start,
  350. slice->row_start + slice->row_size - 1, slice->row_size,
  351. slice->block_start, slice->block_start + slice->block_size - 1,
  352. slice->block_size);
  353. if (ctx->codec->slice_params_size > 0) {
  354. slice->codec_slice_params = av_mallocz(ctx->codec->slice_params_size);
  355. if (!slice->codec_slice_params) {
  356. err = AVERROR(ENOMEM);
  357. goto fail;
  358. }
  359. }
  360. if (ctx->codec->init_slice_params) {
  361. err = ctx->codec->init_slice_params(avctx, pic, slice);
  362. if (err < 0) {
  363. av_log(avctx, AV_LOG_ERROR, "Failed to initialise slice "
  364. "parameters: %d.\n", err);
  365. goto fail;
  366. }
  367. }
  368. if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SLICE &&
  369. ctx->codec->write_slice_header) {
  370. bit_len = 8 * sizeof(data);
  371. err = ctx->codec->write_slice_header(avctx, pic, slice,
  372. data, &bit_len);
  373. if (err < 0) {
  374. av_log(avctx, AV_LOG_ERROR, "Failed to write per-slice "
  375. "header: %d.\n", err);
  376. goto fail;
  377. }
  378. err = vaapi_encode_make_packed_header(avctx, pic,
  379. ctx->codec->slice_header_type,
  380. data, bit_len);
  381. if (err < 0)
  382. goto fail;
  383. }
  384. if (ctx->codec->init_slice_params) {
  385. err = vaapi_encode_make_param_buffer(avctx, pic,
  386. VAEncSliceParameterBufferType,
  387. slice->codec_slice_params,
  388. ctx->codec->slice_params_size);
  389. if (err < 0)
  390. goto fail;
  391. }
  392. }
  393. #if VA_CHECK_VERSION(1, 0, 0)
  394. sd = av_frame_get_side_data(pic->input_image,
  395. AV_FRAME_DATA_REGIONS_OF_INTEREST);
  396. if (sd && ctx->roi_allowed) {
  397. const AVRegionOfInterest *roi;
  398. uint32_t roi_size;
  399. VAEncMiscParameterBufferROI param_roi;
  400. int nb_roi, i, v;
  401. roi = (const AVRegionOfInterest*)sd->data;
  402. roi_size = roi->self_size;
  403. av_assert0(roi_size && sd->size % roi_size == 0);
  404. nb_roi = sd->size / roi_size;
  405. if (nb_roi > ctx->roi_max_regions) {
  406. if (!ctx->roi_warned) {
  407. av_log(avctx, AV_LOG_WARNING, "More ROIs set than "
  408. "supported by driver (%d > %d).\n",
  409. nb_roi, ctx->roi_max_regions);
  410. ctx->roi_warned = 1;
  411. }
  412. nb_roi = ctx->roi_max_regions;
  413. }
  414. pic->roi = av_mallocz_array(nb_roi, sizeof(*pic->roi));
  415. if (!pic->roi) {
  416. err = AVERROR(ENOMEM);
  417. goto fail;
  418. }
  419. // For overlapping regions, the first in the array takes priority.
  420. for (i = 0; i < nb_roi; i++) {
  421. roi = (const AVRegionOfInterest*)(sd->data + roi_size * i);
  422. av_assert0(roi->qoffset.den != 0);
  423. v = roi->qoffset.num * ctx->roi_quant_range / roi->qoffset.den;
  424. av_log(avctx, AV_LOG_DEBUG, "ROI: (%d,%d)-(%d,%d) -> %+d.\n",
  425. roi->top, roi->left, roi->bottom, roi->right, v);
  426. pic->roi[i] = (VAEncROI) {
  427. .roi_rectangle = {
  428. .x = roi->left,
  429. .y = roi->top,
  430. .width = roi->right - roi->left,
  431. .height = roi->bottom - roi->top,
  432. },
  433. .roi_value = av_clip_int8(v),
  434. };
  435. }
  436. param_roi = (VAEncMiscParameterBufferROI) {
  437. .num_roi = nb_roi,
  438. .max_delta_qp = INT8_MAX,
  439. .min_delta_qp = INT8_MIN,
  440. .roi = pic->roi,
  441. .roi_flags.bits.roi_value_is_qp_delta = 1,
  442. };
  443. err = vaapi_encode_make_misc_param_buffer(avctx, pic,
  444. VAEncMiscParameterTypeROI,
  445. &param_roi,
  446. sizeof(param_roi));
  447. if (err < 0)
  448. goto fail;
  449. }
  450. #endif
  451. vas = vaBeginPicture(ctx->hwctx->display, ctx->va_context,
  452. pic->input_surface);
  453. if (vas != VA_STATUS_SUCCESS) {
  454. av_log(avctx, AV_LOG_ERROR, "Failed to begin picture encode issue: "
  455. "%d (%s).\n", vas, vaErrorStr(vas));
  456. err = AVERROR(EIO);
  457. goto fail_with_picture;
  458. }
  459. vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context,
  460. pic->param_buffers, pic->nb_param_buffers);
  461. if (vas != VA_STATUS_SUCCESS) {
  462. av_log(avctx, AV_LOG_ERROR, "Failed to upload encode parameters: "
  463. "%d (%s).\n", vas, vaErrorStr(vas));
  464. err = AVERROR(EIO);
  465. goto fail_with_picture;
  466. }
  467. vas = vaEndPicture(ctx->hwctx->display, ctx->va_context);
  468. if (vas != VA_STATUS_SUCCESS) {
  469. av_log(avctx, AV_LOG_ERROR, "Failed to end picture encode issue: "
  470. "%d (%s).\n", vas, vaErrorStr(vas));
  471. err = AVERROR(EIO);
  472. // vaRenderPicture() has been called here, so we should not destroy
  473. // the parameter buffers unless separate destruction is required.
  474. if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks &
  475. AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS)
  476. goto fail;
  477. else
  478. goto fail_at_end;
  479. }
  480. if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks &
  481. AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS) {
  482. for (i = 0; i < pic->nb_param_buffers; i++) {
  483. vas = vaDestroyBuffer(ctx->hwctx->display,
  484. pic->param_buffers[i]);
  485. if (vas != VA_STATUS_SUCCESS) {
  486. av_log(avctx, AV_LOG_ERROR, "Failed to destroy "
  487. "param buffer %#x: %d (%s).\n",
  488. pic->param_buffers[i], vas, vaErrorStr(vas));
  489. // And ignore.
  490. }
  491. }
  492. }
  493. pic->encode_issued = 1;
  494. return 0;
  495. fail_with_picture:
  496. vaEndPicture(ctx->hwctx->display, ctx->va_context);
  497. fail:
  498. for(i = 0; i < pic->nb_param_buffers; i++)
  499. vaDestroyBuffer(ctx->hwctx->display, pic->param_buffers[i]);
  500. for (i = 0; i < pic->nb_slices; i++) {
  501. if (pic->slices) {
  502. av_freep(&pic->slices[i].priv_data);
  503. av_freep(&pic->slices[i].codec_slice_params);
  504. }
  505. }
  506. fail_at_end:
  507. av_freep(&pic->codec_picture_params);
  508. av_freep(&pic->param_buffers);
  509. av_freep(&pic->slices);
  510. av_freep(&pic->roi);
  511. av_frame_free(&pic->recon_image);
  512. av_buffer_unref(&pic->output_buffer_ref);
  513. pic->output_buffer = VA_INVALID_ID;
  514. return err;
  515. }
  516. static int vaapi_encode_output(AVCodecContext *avctx,
  517. VAAPIEncodePicture *pic, AVPacket *pkt)
  518. {
  519. VAAPIEncodeContext *ctx = avctx->priv_data;
  520. VACodedBufferSegment *buf_list, *buf;
  521. VAStatus vas;
  522. int total_size = 0;
  523. uint8_t *ptr;
  524. int err;
  525. err = vaapi_encode_wait(avctx, pic);
  526. if (err < 0)
  527. return err;
  528. buf_list = NULL;
  529. vas = vaMapBuffer(ctx->hwctx->display, pic->output_buffer,
  530. (void**)&buf_list);
  531. if (vas != VA_STATUS_SUCCESS) {
  532. av_log(avctx, AV_LOG_ERROR, "Failed to map output buffers: "
  533. "%d (%s).\n", vas, vaErrorStr(vas));
  534. err = AVERROR(EIO);
  535. goto fail;
  536. }
  537. for (buf = buf_list; buf; buf = buf->next)
  538. total_size += buf->size;
  539. err = av_new_packet(pkt, total_size);
  540. ptr = pkt->data;
  541. if (err < 0)
  542. goto fail_mapped;
  543. for (buf = buf_list; buf; buf = buf->next) {
  544. av_log(avctx, AV_LOG_DEBUG, "Output buffer: %u bytes "
  545. "(status %08x).\n", buf->size, buf->status);
  546. memcpy(ptr, buf->buf, buf->size);
  547. ptr += buf->size;
  548. }
  549. if (pic->type == PICTURE_TYPE_IDR)
  550. pkt->flags |= AV_PKT_FLAG_KEY;
  551. pkt->pts = pic->pts;
  552. vas = vaUnmapBuffer(ctx->hwctx->display, pic->output_buffer);
  553. if (vas != VA_STATUS_SUCCESS) {
  554. av_log(avctx, AV_LOG_ERROR, "Failed to unmap output buffers: "
  555. "%d (%s).\n", vas, vaErrorStr(vas));
  556. err = AVERROR(EIO);
  557. goto fail;
  558. }
  559. av_buffer_unref(&pic->output_buffer_ref);
  560. pic->output_buffer = VA_INVALID_ID;
  561. av_log(avctx, AV_LOG_DEBUG, "Output read for pic %"PRId64"/%"PRId64".\n",
  562. pic->display_order, pic->encode_order);
  563. return 0;
  564. fail_mapped:
  565. vaUnmapBuffer(ctx->hwctx->display, pic->output_buffer);
  566. fail:
  567. av_buffer_unref(&pic->output_buffer_ref);
  568. pic->output_buffer = VA_INVALID_ID;
  569. return err;
  570. }
  571. static int vaapi_encode_discard(AVCodecContext *avctx,
  572. VAAPIEncodePicture *pic)
  573. {
  574. vaapi_encode_wait(avctx, pic);
  575. if (pic->output_buffer_ref) {
  576. av_log(avctx, AV_LOG_DEBUG, "Discard output for pic "
  577. "%"PRId64"/%"PRId64".\n",
  578. pic->display_order, pic->encode_order);
  579. av_buffer_unref(&pic->output_buffer_ref);
  580. pic->output_buffer = VA_INVALID_ID;
  581. }
  582. return 0;
  583. }
  584. static VAAPIEncodePicture *vaapi_encode_alloc(AVCodecContext *avctx)
  585. {
  586. VAAPIEncodeContext *ctx = avctx->priv_data;
  587. VAAPIEncodePicture *pic;
  588. pic = av_mallocz(sizeof(*pic));
  589. if (!pic)
  590. return NULL;
  591. if (ctx->codec->picture_priv_data_size > 0) {
  592. pic->priv_data = av_mallocz(ctx->codec->picture_priv_data_size);
  593. if (!pic->priv_data) {
  594. av_freep(&pic);
  595. return NULL;
  596. }
  597. }
  598. pic->input_surface = VA_INVALID_ID;
  599. pic->recon_surface = VA_INVALID_ID;
  600. pic->output_buffer = VA_INVALID_ID;
  601. return pic;
  602. }
  603. static int vaapi_encode_free(AVCodecContext *avctx,
  604. VAAPIEncodePicture *pic)
  605. {
  606. int i;
  607. if (pic->encode_issued)
  608. vaapi_encode_discard(avctx, pic);
  609. for (i = 0; i < pic->nb_slices; i++) {
  610. if (pic->slices) {
  611. av_freep(&pic->slices[i].priv_data);
  612. av_freep(&pic->slices[i].codec_slice_params);
  613. }
  614. }
  615. av_freep(&pic->codec_picture_params);
  616. av_frame_free(&pic->input_image);
  617. av_frame_free(&pic->recon_image);
  618. av_freep(&pic->param_buffers);
  619. av_freep(&pic->slices);
  620. // Output buffer should already be destroyed.
  621. av_assert0(pic->output_buffer == VA_INVALID_ID);
  622. av_freep(&pic->priv_data);
  623. av_freep(&pic->codec_picture_params);
  624. av_freep(&pic->roi);
  625. av_free(pic);
  626. return 0;
  627. }
  628. static void vaapi_encode_add_ref(AVCodecContext *avctx,
  629. VAAPIEncodePicture *pic,
  630. VAAPIEncodePicture *target,
  631. int is_ref, int in_dpb, int prev)
  632. {
  633. int refs = 0;
  634. if (is_ref) {
  635. av_assert0(pic != target);
  636. av_assert0(pic->nb_refs < MAX_PICTURE_REFERENCES);
  637. pic->refs[pic->nb_refs++] = target;
  638. ++refs;
  639. }
  640. if (in_dpb) {
  641. av_assert0(pic->nb_dpb_pics < MAX_DPB_SIZE);
  642. pic->dpb[pic->nb_dpb_pics++] = target;
  643. ++refs;
  644. }
  645. if (prev) {
  646. av_assert0(!pic->prev);
  647. pic->prev = target;
  648. ++refs;
  649. }
  650. target->ref_count[0] += refs;
  651. target->ref_count[1] += refs;
  652. }
  653. static void vaapi_encode_remove_refs(AVCodecContext *avctx,
  654. VAAPIEncodePicture *pic,
  655. int level)
  656. {
  657. int i;
  658. if (pic->ref_removed[level])
  659. return;
  660. for (i = 0; i < pic->nb_refs; i++) {
  661. av_assert0(pic->refs[i]);
  662. --pic->refs[i]->ref_count[level];
  663. av_assert0(pic->refs[i]->ref_count[level] >= 0);
  664. }
  665. for (i = 0; i < pic->nb_dpb_pics; i++) {
  666. av_assert0(pic->dpb[i]);
  667. --pic->dpb[i]->ref_count[level];
  668. av_assert0(pic->dpb[i]->ref_count[level] >= 0);
  669. }
  670. av_assert0(pic->prev || pic->type == PICTURE_TYPE_IDR);
  671. if (pic->prev) {
  672. --pic->prev->ref_count[level];
  673. av_assert0(pic->prev->ref_count[level] >= 0);
  674. }
  675. pic->ref_removed[level] = 1;
  676. }
  677. static void vaapi_encode_set_b_pictures(AVCodecContext *avctx,
  678. VAAPIEncodePicture *start,
  679. VAAPIEncodePicture *end,
  680. VAAPIEncodePicture *prev,
  681. int current_depth,
  682. VAAPIEncodePicture **last)
  683. {
  684. VAAPIEncodeContext *ctx = avctx->priv_data;
  685. VAAPIEncodePicture *pic, *next, *ref;
  686. int i, len;
  687. av_assert0(start && end && start != end && start->next != end);
  688. // If we are at the maximum depth then encode all pictures as
  689. // non-referenced B-pictures. Also do this if there is exactly one
  690. // picture left, since there will be nothing to reference it.
  691. if (current_depth == ctx->max_b_depth || start->next->next == end) {
  692. for (pic = start->next; pic; pic = pic->next) {
  693. if (pic == end)
  694. break;
  695. pic->type = PICTURE_TYPE_B;
  696. pic->b_depth = current_depth;
  697. vaapi_encode_add_ref(avctx, pic, start, 1, 1, 0);
  698. vaapi_encode_add_ref(avctx, pic, end, 1, 1, 0);
  699. vaapi_encode_add_ref(avctx, pic, prev, 0, 0, 1);
  700. for (ref = end->refs[1]; ref; ref = ref->refs[1])
  701. vaapi_encode_add_ref(avctx, pic, ref, 0, 1, 0);
  702. }
  703. *last = prev;
  704. } else {
  705. // Split the current list at the midpoint with a referenced
  706. // B-picture, then descend into each side separately.
  707. len = 0;
  708. for (pic = start->next; pic != end; pic = pic->next)
  709. ++len;
  710. for (pic = start->next, i = 1; 2 * i < len; pic = pic->next, i++);
  711. pic->type = PICTURE_TYPE_B;
  712. pic->b_depth = current_depth;
  713. pic->is_reference = 1;
  714. vaapi_encode_add_ref(avctx, pic, pic, 0, 1, 0);
  715. vaapi_encode_add_ref(avctx, pic, start, 1, 1, 0);
  716. vaapi_encode_add_ref(avctx, pic, end, 1, 1, 0);
  717. vaapi_encode_add_ref(avctx, pic, prev, 0, 0, 1);
  718. for (ref = end->refs[1]; ref; ref = ref->refs[1])
  719. vaapi_encode_add_ref(avctx, pic, ref, 0, 1, 0);
  720. if (i > 1)
  721. vaapi_encode_set_b_pictures(avctx, start, pic, pic,
  722. current_depth + 1, &next);
  723. else
  724. next = pic;
  725. vaapi_encode_set_b_pictures(avctx, pic, end, next,
  726. current_depth + 1, last);
  727. }
  728. }
  729. static int vaapi_encode_pick_next(AVCodecContext *avctx,
  730. VAAPIEncodePicture **pic_out)
  731. {
  732. VAAPIEncodeContext *ctx = avctx->priv_data;
  733. VAAPIEncodePicture *pic = NULL, *next, *start;
  734. int i, b_counter, closed_gop_end;
  735. // If there are any B-frames already queued, the next one to encode
  736. // is the earliest not-yet-issued frame for which all references are
  737. // available.
  738. for (pic = ctx->pic_start; pic; pic = pic->next) {
  739. if (pic->encode_issued)
  740. continue;
  741. if (pic->type != PICTURE_TYPE_B)
  742. continue;
  743. for (i = 0; i < pic->nb_refs; i++) {
  744. if (!pic->refs[i]->encode_issued)
  745. break;
  746. }
  747. if (i == pic->nb_refs)
  748. break;
  749. }
  750. if (pic) {
  751. av_log(avctx, AV_LOG_DEBUG, "Pick B-picture at depth %d to "
  752. "encode next.\n", pic->b_depth);
  753. *pic_out = pic;
  754. return 0;
  755. }
  756. // Find the B-per-Pth available picture to become the next picture
  757. // on the top layer.
  758. start = NULL;
  759. b_counter = 0;
  760. closed_gop_end = ctx->closed_gop ||
  761. ctx->idr_counter == ctx->gop_per_idr;
  762. for (pic = ctx->pic_start; pic; pic = next) {
  763. next = pic->next;
  764. if (pic->encode_issued) {
  765. start = pic;
  766. continue;
  767. }
  768. // If the next available picture is force-IDR, encode it to start
  769. // a new GOP immediately.
  770. if (pic->force_idr)
  771. break;
  772. if (b_counter == ctx->b_per_p)
  773. break;
  774. // If this picture ends a closed GOP or starts a new GOP then it
  775. // needs to be in the top layer.
  776. if (ctx->gop_counter + b_counter + closed_gop_end >= ctx->gop_size)
  777. break;
  778. // If the picture after this one is force-IDR, we need to encode
  779. // this one in the top layer.
  780. if (next && next->force_idr)
  781. break;
  782. ++b_counter;
  783. }
  784. // At the end of the stream the last picture must be in the top layer.
  785. if (!pic && ctx->end_of_stream) {
  786. --b_counter;
  787. pic = ctx->pic_end;
  788. if (pic->encode_issued)
  789. return AVERROR_EOF;
  790. }
  791. if (!pic) {
  792. av_log(avctx, AV_LOG_DEBUG, "Pick nothing to encode next - "
  793. "need more input for reference pictures.\n");
  794. return AVERROR(EAGAIN);
  795. }
  796. if (ctx->input_order <= ctx->decode_delay && !ctx->end_of_stream) {
  797. av_log(avctx, AV_LOG_DEBUG, "Pick nothing to encode next - "
  798. "need more input for timestamps.\n");
  799. return AVERROR(EAGAIN);
  800. }
  801. if (pic->force_idr) {
  802. av_log(avctx, AV_LOG_DEBUG, "Pick forced IDR-picture to "
  803. "encode next.\n");
  804. pic->type = PICTURE_TYPE_IDR;
  805. ctx->idr_counter = 1;
  806. ctx->gop_counter = 1;
  807. } else if (ctx->gop_counter + b_counter >= ctx->gop_size) {
  808. if (ctx->idr_counter == ctx->gop_per_idr) {
  809. av_log(avctx, AV_LOG_DEBUG, "Pick new-GOP IDR-picture to "
  810. "encode next.\n");
  811. pic->type = PICTURE_TYPE_IDR;
  812. ctx->idr_counter = 1;
  813. } else {
  814. av_log(avctx, AV_LOG_DEBUG, "Pick new-GOP I-picture to "
  815. "encode next.\n");
  816. pic->type = PICTURE_TYPE_I;
  817. ++ctx->idr_counter;
  818. }
  819. ctx->gop_counter = 1;
  820. } else {
  821. if (ctx->gop_counter + b_counter + closed_gop_end == ctx->gop_size) {
  822. av_log(avctx, AV_LOG_DEBUG, "Pick group-end P-picture to "
  823. "encode next.\n");
  824. } else {
  825. av_log(avctx, AV_LOG_DEBUG, "Pick normal P-picture to "
  826. "encode next.\n");
  827. }
  828. pic->type = PICTURE_TYPE_P;
  829. av_assert0(start);
  830. ctx->gop_counter += 1 + b_counter;
  831. }
  832. pic->is_reference = 1;
  833. *pic_out = pic;
  834. vaapi_encode_add_ref(avctx, pic, pic, 0, 1, 0);
  835. if (pic->type != PICTURE_TYPE_IDR) {
  836. vaapi_encode_add_ref(avctx, pic, start,
  837. pic->type == PICTURE_TYPE_P,
  838. b_counter > 0, 0);
  839. vaapi_encode_add_ref(avctx, pic, ctx->next_prev, 0, 0, 1);
  840. }
  841. if (ctx->next_prev)
  842. --ctx->next_prev->ref_count[0];
  843. if (b_counter > 0) {
  844. vaapi_encode_set_b_pictures(avctx, start, pic, pic, 1,
  845. &ctx->next_prev);
  846. } else {
  847. ctx->next_prev = pic;
  848. }
  849. ++ctx->next_prev->ref_count[0];
  850. return 0;
  851. }
  852. static int vaapi_encode_clear_old(AVCodecContext *avctx)
  853. {
  854. VAAPIEncodeContext *ctx = avctx->priv_data;
  855. VAAPIEncodePicture *pic, *prev, *next;
  856. av_assert0(ctx->pic_start);
  857. // Remove direct references once each picture is complete.
  858. for (pic = ctx->pic_start; pic; pic = pic->next) {
  859. if (pic->encode_complete && pic->next)
  860. vaapi_encode_remove_refs(avctx, pic, 0);
  861. }
  862. // Remove indirect references once a picture has no direct references.
  863. for (pic = ctx->pic_start; pic; pic = pic->next) {
  864. if (pic->encode_complete && pic->ref_count[0] == 0)
  865. vaapi_encode_remove_refs(avctx, pic, 1);
  866. }
  867. // Clear out all complete pictures with no remaining references.
  868. prev = NULL;
  869. for (pic = ctx->pic_start; pic; pic = next) {
  870. next = pic->next;
  871. if (pic->encode_complete && pic->ref_count[1] == 0) {
  872. av_assert0(pic->ref_removed[0] && pic->ref_removed[1]);
  873. if (prev)
  874. prev->next = next;
  875. else
  876. ctx->pic_start = next;
  877. vaapi_encode_free(avctx, pic);
  878. } else {
  879. prev = pic;
  880. }
  881. }
  882. return 0;
  883. }
  884. static int vaapi_encode_check_frame(AVCodecContext *avctx,
  885. const AVFrame *frame)
  886. {
  887. VAAPIEncodeContext *ctx = avctx->priv_data;
  888. if ((frame->crop_top || frame->crop_bottom ||
  889. frame->crop_left || frame->crop_right) && !ctx->crop_warned) {
  890. av_log(avctx, AV_LOG_WARNING, "Cropping information on input "
  891. "frames ignored due to lack of API support.\n");
  892. ctx->crop_warned = 1;
  893. }
  894. if (!ctx->roi_allowed) {
  895. AVFrameSideData *sd =
  896. av_frame_get_side_data(frame, AV_FRAME_DATA_REGIONS_OF_INTEREST);
  897. if (sd && !ctx->roi_warned) {
  898. av_log(avctx, AV_LOG_WARNING, "ROI side data on input "
  899. "frames ignored due to lack of driver support.\n");
  900. ctx->roi_warned = 1;
  901. }
  902. }
  903. return 0;
  904. }
  905. static int vaapi_encode_send_frame(AVCodecContext *avctx, AVFrame *frame)
  906. {
  907. VAAPIEncodeContext *ctx = avctx->priv_data;
  908. VAAPIEncodePicture *pic;
  909. int err;
  910. if (frame) {
  911. av_log(avctx, AV_LOG_DEBUG, "Input frame: %ux%u (%"PRId64").\n",
  912. frame->width, frame->height, frame->pts);
  913. err = vaapi_encode_check_frame(avctx, frame);
  914. if (err < 0)
  915. return err;
  916. pic = vaapi_encode_alloc(avctx);
  917. if (!pic)
  918. return AVERROR(ENOMEM);
  919. pic->input_image = av_frame_alloc();
  920. if (!pic->input_image) {
  921. err = AVERROR(ENOMEM);
  922. goto fail;
  923. }
  924. if (ctx->input_order == 0 || frame->pict_type == AV_PICTURE_TYPE_I)
  925. pic->force_idr = 1;
  926. pic->input_surface = (VASurfaceID)(uintptr_t)frame->data[3];
  927. pic->pts = frame->pts;
  928. av_frame_move_ref(pic->input_image, frame);
  929. if (ctx->input_order == 0)
  930. ctx->first_pts = pic->pts;
  931. if (ctx->input_order == ctx->decode_delay)
  932. ctx->dts_pts_diff = pic->pts - ctx->first_pts;
  933. if (ctx->output_delay > 0)
  934. ctx->ts_ring[ctx->input_order % (3 * ctx->output_delay)] = pic->pts;
  935. pic->display_order = ctx->input_order;
  936. ++ctx->input_order;
  937. if (ctx->pic_start) {
  938. ctx->pic_end->next = pic;
  939. ctx->pic_end = pic;
  940. } else {
  941. ctx->pic_start = pic;
  942. ctx->pic_end = pic;
  943. }
  944. } else {
  945. ctx->end_of_stream = 1;
  946. // Fix timestamps if we hit end-of-stream before the initial decode
  947. // delay has elapsed.
  948. if (ctx->input_order < ctx->decode_delay)
  949. ctx->dts_pts_diff = ctx->pic_end->pts - ctx->first_pts;
  950. }
  951. return 0;
  952. fail:
  953. vaapi_encode_free(avctx, pic);
  954. return err;
  955. }
  956. int ff_vaapi_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
  957. {
  958. VAAPIEncodeContext *ctx = avctx->priv_data;
  959. VAAPIEncodePicture *pic;
  960. AVFrame *frame = ctx->frame;
  961. int err;
  962. err = ff_encode_get_frame(avctx, frame);
  963. if (err < 0 && err != AVERROR_EOF)
  964. return err;
  965. if (err == AVERROR_EOF)
  966. frame = NULL;
  967. err = vaapi_encode_send_frame(avctx, frame);
  968. if (err < 0)
  969. return err;
  970. if (!ctx->pic_start) {
  971. if (ctx->end_of_stream)
  972. return AVERROR_EOF;
  973. else
  974. return AVERROR(EAGAIN);
  975. }
  976. pic = NULL;
  977. err = vaapi_encode_pick_next(avctx, &pic);
  978. if (err < 0)
  979. return err;
  980. av_assert0(pic);
  981. pic->encode_order = ctx->encode_order++;
  982. err = vaapi_encode_issue(avctx, pic);
  983. if (err < 0) {
  984. av_log(avctx, AV_LOG_ERROR, "Encode failed: %d.\n", err);
  985. return err;
  986. }
  987. err = vaapi_encode_output(avctx, pic, pkt);
  988. if (err < 0) {
  989. av_log(avctx, AV_LOG_ERROR, "Output failed: %d.\n", err);
  990. return err;
  991. }
  992. if (ctx->output_delay == 0) {
  993. pkt->dts = pkt->pts;
  994. } else if (pic->encode_order < ctx->decode_delay) {
  995. if (ctx->ts_ring[pic->encode_order] < INT64_MIN + ctx->dts_pts_diff)
  996. pkt->dts = INT64_MIN;
  997. else
  998. pkt->dts = ctx->ts_ring[pic->encode_order] - ctx->dts_pts_diff;
  999. } else {
  1000. pkt->dts = ctx->ts_ring[(pic->encode_order - ctx->decode_delay) %
  1001. (3 * ctx->output_delay)];
  1002. }
  1003. av_log(avctx, AV_LOG_DEBUG, "Output packet: pts %"PRId64" dts %"PRId64".\n",
  1004. pkt->pts, pkt->dts);
  1005. ctx->output_order = pic->encode_order;
  1006. vaapi_encode_clear_old(avctx);
  1007. return 0;
  1008. }
  1009. static av_cold void vaapi_encode_add_global_param(AVCodecContext *avctx, int type,
  1010. void *buffer, size_t size)
  1011. {
  1012. VAAPIEncodeContext *ctx = avctx->priv_data;
  1013. av_assert0(ctx->nb_global_params < MAX_GLOBAL_PARAMS);
  1014. ctx->global_params_type[ctx->nb_global_params] = type;
  1015. ctx->global_params [ctx->nb_global_params] = buffer;
  1016. ctx->global_params_size[ctx->nb_global_params] = size;
  1017. ++ctx->nb_global_params;
  1018. }
  1019. typedef struct VAAPIEncodeRTFormat {
  1020. const char *name;
  1021. unsigned int value;
  1022. int depth;
  1023. int nb_components;
  1024. int log2_chroma_w;
  1025. int log2_chroma_h;
  1026. } VAAPIEncodeRTFormat;
  1027. static const VAAPIEncodeRTFormat vaapi_encode_rt_formats[] = {
  1028. { "YUV400", VA_RT_FORMAT_YUV400, 8, 1, },
  1029. { "YUV420", VA_RT_FORMAT_YUV420, 8, 3, 1, 1 },
  1030. { "YUV422", VA_RT_FORMAT_YUV422, 8, 3, 1, 0 },
  1031. { "YUV444", VA_RT_FORMAT_YUV444, 8, 3, 0, 0 },
  1032. { "YUV411", VA_RT_FORMAT_YUV411, 8, 3, 2, 0 },
  1033. #if VA_CHECK_VERSION(0, 38, 1)
  1034. { "YUV420_10", VA_RT_FORMAT_YUV420_10BPP, 10, 3, 1, 1 },
  1035. #endif
  1036. };
  1037. static const VAEntrypoint vaapi_encode_entrypoints_normal[] = {
  1038. VAEntrypointEncSlice,
  1039. VAEntrypointEncPicture,
  1040. #if VA_CHECK_VERSION(0, 39, 2)
  1041. VAEntrypointEncSliceLP,
  1042. #endif
  1043. 0
  1044. };
  1045. #if VA_CHECK_VERSION(0, 39, 2)
  1046. static const VAEntrypoint vaapi_encode_entrypoints_low_power[] = {
  1047. VAEntrypointEncSliceLP,
  1048. 0
  1049. };
  1050. #endif
  1051. static av_cold int vaapi_encode_profile_entrypoint(AVCodecContext *avctx)
  1052. {
  1053. VAAPIEncodeContext *ctx = avctx->priv_data;
  1054. VAProfile *va_profiles = NULL;
  1055. VAEntrypoint *va_entrypoints = NULL;
  1056. VAStatus vas;
  1057. const VAEntrypoint *usable_entrypoints;
  1058. const VAAPIEncodeProfile *profile;
  1059. const AVPixFmtDescriptor *desc;
  1060. VAConfigAttrib rt_format_attr;
  1061. const VAAPIEncodeRTFormat *rt_format;
  1062. const char *profile_string, *entrypoint_string;
  1063. int i, j, n, depth, err;
  1064. if (ctx->low_power) {
  1065. #if VA_CHECK_VERSION(0, 39, 2)
  1066. usable_entrypoints = vaapi_encode_entrypoints_low_power;
  1067. #else
  1068. av_log(avctx, AV_LOG_ERROR, "Low-power encoding is not "
  1069. "supported with this VAAPI version.\n");
  1070. return AVERROR(EINVAL);
  1071. #endif
  1072. } else {
  1073. usable_entrypoints = vaapi_encode_entrypoints_normal;
  1074. }
  1075. desc = av_pix_fmt_desc_get(ctx->input_frames->sw_format);
  1076. if (!desc) {
  1077. av_log(avctx, AV_LOG_ERROR, "Invalid input pixfmt (%d).\n",
  1078. ctx->input_frames->sw_format);
  1079. return AVERROR(EINVAL);
  1080. }
  1081. depth = desc->comp[0].depth;
  1082. for (i = 1; i < desc->nb_components; i++) {
  1083. if (desc->comp[i].depth != depth) {
  1084. av_log(avctx, AV_LOG_ERROR, "Invalid input pixfmt (%s).\n",
  1085. desc->name);
  1086. return AVERROR(EINVAL);
  1087. }
  1088. }
  1089. av_log(avctx, AV_LOG_VERBOSE, "Input surface format is %s.\n",
  1090. desc->name);
  1091. n = vaMaxNumProfiles(ctx->hwctx->display);
  1092. va_profiles = av_malloc_array(n, sizeof(VAProfile));
  1093. if (!va_profiles) {
  1094. err = AVERROR(ENOMEM);
  1095. goto fail;
  1096. }
  1097. vas = vaQueryConfigProfiles(ctx->hwctx->display, va_profiles, &n);
  1098. if (vas != VA_STATUS_SUCCESS) {
  1099. av_log(avctx, AV_LOG_ERROR, "Failed to query profiles: %d (%s).\n",
  1100. vas, vaErrorStr(vas));
  1101. err = AVERROR_EXTERNAL;
  1102. goto fail;
  1103. }
  1104. av_assert0(ctx->codec->profiles);
  1105. for (i = 0; (ctx->codec->profiles[i].av_profile !=
  1106. FF_PROFILE_UNKNOWN); i++) {
  1107. profile = &ctx->codec->profiles[i];
  1108. if (depth != profile->depth ||
  1109. desc->nb_components != profile->nb_components)
  1110. continue;
  1111. if (desc->nb_components > 1 &&
  1112. (desc->log2_chroma_w != profile->log2_chroma_w ||
  1113. desc->log2_chroma_h != profile->log2_chroma_h))
  1114. continue;
  1115. if (avctx->profile != profile->av_profile &&
  1116. avctx->profile != FF_PROFILE_UNKNOWN)
  1117. continue;
  1118. #if VA_CHECK_VERSION(1, 0, 0)
  1119. profile_string = vaProfileStr(profile->va_profile);
  1120. #else
  1121. profile_string = "(no profile names)";
  1122. #endif
  1123. for (j = 0; j < n; j++) {
  1124. if (va_profiles[j] == profile->va_profile)
  1125. break;
  1126. }
  1127. if (j >= n) {
  1128. av_log(avctx, AV_LOG_VERBOSE, "Compatible profile %s (%d) "
  1129. "is not supported by driver.\n", profile_string,
  1130. profile->va_profile);
  1131. continue;
  1132. }
  1133. ctx->profile = profile;
  1134. break;
  1135. }
  1136. if (!ctx->profile) {
  1137. av_log(avctx, AV_LOG_ERROR, "No usable encoding profile found.\n");
  1138. err = AVERROR(ENOSYS);
  1139. goto fail;
  1140. }
  1141. avctx->profile = profile->av_profile;
  1142. ctx->va_profile = profile->va_profile;
  1143. av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI profile %s (%d).\n",
  1144. profile_string, ctx->va_profile);
  1145. n = vaMaxNumEntrypoints(ctx->hwctx->display);
  1146. va_entrypoints = av_malloc_array(n, sizeof(VAEntrypoint));
  1147. if (!va_entrypoints) {
  1148. err = AVERROR(ENOMEM);
  1149. goto fail;
  1150. }
  1151. vas = vaQueryConfigEntrypoints(ctx->hwctx->display, ctx->va_profile,
  1152. va_entrypoints, &n);
  1153. if (vas != VA_STATUS_SUCCESS) {
  1154. av_log(avctx, AV_LOG_ERROR, "Failed to query entrypoints for "
  1155. "profile %s (%d): %d (%s).\n", profile_string,
  1156. ctx->va_profile, vas, vaErrorStr(vas));
  1157. err = AVERROR_EXTERNAL;
  1158. goto fail;
  1159. }
  1160. for (i = 0; i < n; i++) {
  1161. for (j = 0; usable_entrypoints[j]; j++) {
  1162. if (va_entrypoints[i] == usable_entrypoints[j])
  1163. break;
  1164. }
  1165. if (usable_entrypoints[j])
  1166. break;
  1167. }
  1168. if (i >= n) {
  1169. av_log(avctx, AV_LOG_ERROR, "No usable encoding entrypoint found "
  1170. "for profile %s (%d).\n", profile_string, ctx->va_profile);
  1171. err = AVERROR(ENOSYS);
  1172. goto fail;
  1173. }
  1174. ctx->va_entrypoint = va_entrypoints[i];
  1175. #if VA_CHECK_VERSION(1, 0, 0)
  1176. entrypoint_string = vaEntrypointStr(ctx->va_entrypoint);
  1177. #else
  1178. entrypoint_string = "(no entrypoint names)";
  1179. #endif
  1180. av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI entrypoint %s (%d).\n",
  1181. entrypoint_string, ctx->va_entrypoint);
  1182. for (i = 0; i < FF_ARRAY_ELEMS(vaapi_encode_rt_formats); i++) {
  1183. rt_format = &vaapi_encode_rt_formats[i];
  1184. if (rt_format->depth == depth &&
  1185. rt_format->nb_components == profile->nb_components &&
  1186. rt_format->log2_chroma_w == profile->log2_chroma_w &&
  1187. rt_format->log2_chroma_h == profile->log2_chroma_h)
  1188. break;
  1189. }
  1190. if (i >= FF_ARRAY_ELEMS(vaapi_encode_rt_formats)) {
  1191. av_log(avctx, AV_LOG_ERROR, "No usable render target format "
  1192. "found for profile %s (%d) entrypoint %s (%d).\n",
  1193. profile_string, ctx->va_profile,
  1194. entrypoint_string, ctx->va_entrypoint);
  1195. err = AVERROR(ENOSYS);
  1196. goto fail;
  1197. }
  1198. rt_format_attr = (VAConfigAttrib) { VAConfigAttribRTFormat };
  1199. vas = vaGetConfigAttributes(ctx->hwctx->display,
  1200. ctx->va_profile, ctx->va_entrypoint,
  1201. &rt_format_attr, 1);
  1202. if (vas != VA_STATUS_SUCCESS) {
  1203. av_log(avctx, AV_LOG_ERROR, "Failed to query RT format "
  1204. "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
  1205. err = AVERROR_EXTERNAL;
  1206. goto fail;
  1207. }
  1208. if (rt_format_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
  1209. av_log(avctx, AV_LOG_VERBOSE, "RT format config attribute not "
  1210. "supported by driver: assuming surface RT format %s "
  1211. "is valid.\n", rt_format->name);
  1212. } else if (!(rt_format_attr.value & rt_format->value)) {
  1213. av_log(avctx, AV_LOG_ERROR, "Surface RT format %s not supported "
  1214. "by driver for encoding profile %s (%d) entrypoint %s (%d).\n",
  1215. rt_format->name, profile_string, ctx->va_profile,
  1216. entrypoint_string, ctx->va_entrypoint);
  1217. err = AVERROR(ENOSYS);
  1218. goto fail;
  1219. } else {
  1220. av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI render target "
  1221. "format %s (%#x).\n", rt_format->name, rt_format->value);
  1222. ctx->config_attributes[ctx->nb_config_attributes++] =
  1223. (VAConfigAttrib) {
  1224. .type = VAConfigAttribRTFormat,
  1225. .value = rt_format->value,
  1226. };
  1227. }
  1228. err = 0;
  1229. fail:
  1230. av_freep(&va_profiles);
  1231. av_freep(&va_entrypoints);
  1232. return err;
  1233. }
  1234. static const VAAPIEncodeRCMode vaapi_encode_rc_modes[] = {
  1235. // Bitrate Quality
  1236. // | Maxrate | HRD/VBV
  1237. { 0 }, // | | | |
  1238. { RC_MODE_CQP, "CQP", 1, VA_RC_CQP, 0, 0, 1, 0 },
  1239. { RC_MODE_CBR, "CBR", 1, VA_RC_CBR, 1, 0, 0, 1 },
  1240. { RC_MODE_VBR, "VBR", 1, VA_RC_VBR, 1, 1, 0, 1 },
  1241. #if VA_CHECK_VERSION(1, 1, 0)
  1242. { RC_MODE_ICQ, "ICQ", 1, VA_RC_ICQ, 0, 0, 1, 0 },
  1243. #else
  1244. { RC_MODE_ICQ, "ICQ", 0 },
  1245. #endif
  1246. #if VA_CHECK_VERSION(1, 3, 0)
  1247. { RC_MODE_QVBR, "QVBR", 1, VA_RC_QVBR, 1, 1, 1, 1 },
  1248. { RC_MODE_AVBR, "AVBR", 0, VA_RC_AVBR, 1, 0, 0, 0 },
  1249. #else
  1250. { RC_MODE_QVBR, "QVBR", 0 },
  1251. { RC_MODE_AVBR, "AVBR", 0 },
  1252. #endif
  1253. };
  1254. static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx)
  1255. {
  1256. VAAPIEncodeContext *ctx = avctx->priv_data;
  1257. uint32_t supported_va_rc_modes;
  1258. const VAAPIEncodeRCMode *rc_mode;
  1259. int64_t rc_bits_per_second;
  1260. int rc_target_percentage;
  1261. int rc_window_size;
  1262. int rc_quality;
  1263. int64_t hrd_buffer_size;
  1264. int64_t hrd_initial_buffer_fullness;
  1265. int fr_num, fr_den;
  1266. VAConfigAttrib rc_attr = { VAConfigAttribRateControl };
  1267. VAStatus vas;
  1268. char supported_rc_modes_string[64];
  1269. vas = vaGetConfigAttributes(ctx->hwctx->display,
  1270. ctx->va_profile, ctx->va_entrypoint,
  1271. &rc_attr, 1);
  1272. if (vas != VA_STATUS_SUCCESS) {
  1273. av_log(avctx, AV_LOG_ERROR, "Failed to query rate control "
  1274. "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
  1275. return AVERROR_EXTERNAL;
  1276. }
  1277. if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
  1278. av_log(avctx, AV_LOG_VERBOSE, "Driver does not report any "
  1279. "supported rate control modes: assuming CQP only.\n");
  1280. supported_va_rc_modes = VA_RC_CQP;
  1281. strcpy(supported_rc_modes_string, "unknown");
  1282. } else {
  1283. char *str = supported_rc_modes_string;
  1284. size_t len = sizeof(supported_rc_modes_string);
  1285. int i, first = 1, res;
  1286. supported_va_rc_modes = rc_attr.value;
  1287. for (i = 0; i < FF_ARRAY_ELEMS(vaapi_encode_rc_modes); i++) {
  1288. rc_mode = &vaapi_encode_rc_modes[i];
  1289. if (supported_va_rc_modes & rc_mode->va_mode) {
  1290. res = snprintf(str, len, "%s%s",
  1291. first ? "" : ", ", rc_mode->name);
  1292. first = 0;
  1293. if (res < 0) {
  1294. *str = 0;
  1295. break;
  1296. }
  1297. len -= res;
  1298. str += res;
  1299. if (len == 0)
  1300. break;
  1301. }
  1302. }
  1303. av_log(avctx, AV_LOG_DEBUG, "Driver supports RC modes %s.\n",
  1304. supported_rc_modes_string);
  1305. }
  1306. // Rate control mode selection:
  1307. // * If the user has set a mode explicitly with the rc_mode option,
  1308. // use it and fail if it is not available.
  1309. // * If an explicit QP option has been set, use CQP.
  1310. // * If the codec is CQ-only, use CQP.
  1311. // * If the QSCALE avcodec option is set, use CQP.
  1312. // * If bitrate and quality are both set, try QVBR.
  1313. // * If quality is set, try ICQ, then CQP.
  1314. // * If bitrate and maxrate are set and have the same value, try CBR.
  1315. // * If a bitrate is set, try AVBR, then VBR, then CBR.
  1316. // * If no bitrate is set, try ICQ, then CQP.
  1317. #define TRY_RC_MODE(mode, fail) do { \
  1318. rc_mode = &vaapi_encode_rc_modes[mode]; \
  1319. if (!(rc_mode->va_mode & supported_va_rc_modes)) { \
  1320. if (fail) { \
  1321. av_log(avctx, AV_LOG_ERROR, "Driver does not support %s " \
  1322. "RC mode (supported modes: %s).\n", rc_mode->name, \
  1323. supported_rc_modes_string); \
  1324. return AVERROR(EINVAL); \
  1325. } \
  1326. av_log(avctx, AV_LOG_DEBUG, "Driver does not support %s " \
  1327. "RC mode.\n", rc_mode->name); \
  1328. rc_mode = NULL; \
  1329. } else { \
  1330. goto rc_mode_found; \
  1331. } \
  1332. } while (0)
  1333. if (ctx->explicit_rc_mode)
  1334. TRY_RC_MODE(ctx->explicit_rc_mode, 1);
  1335. if (ctx->explicit_qp)
  1336. TRY_RC_MODE(RC_MODE_CQP, 1);
  1337. if (ctx->codec->flags & FLAG_CONSTANT_QUALITY_ONLY)
  1338. TRY_RC_MODE(RC_MODE_CQP, 1);
  1339. if (avctx->flags & AV_CODEC_FLAG_QSCALE)
  1340. TRY_RC_MODE(RC_MODE_CQP, 1);
  1341. if (avctx->bit_rate > 0 && avctx->global_quality > 0)
  1342. TRY_RC_MODE(RC_MODE_QVBR, 0);
  1343. if (avctx->global_quality > 0) {
  1344. TRY_RC_MODE(RC_MODE_ICQ, 0);
  1345. TRY_RC_MODE(RC_MODE_CQP, 0);
  1346. }
  1347. if (avctx->bit_rate > 0 && avctx->rc_max_rate == avctx->bit_rate)
  1348. TRY_RC_MODE(RC_MODE_CBR, 0);
  1349. if (avctx->bit_rate > 0) {
  1350. TRY_RC_MODE(RC_MODE_AVBR, 0);
  1351. TRY_RC_MODE(RC_MODE_VBR, 0);
  1352. TRY_RC_MODE(RC_MODE_CBR, 0);
  1353. } else {
  1354. TRY_RC_MODE(RC_MODE_ICQ, 0);
  1355. TRY_RC_MODE(RC_MODE_CQP, 0);
  1356. }
  1357. av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
  1358. "RC mode compatible with selected options "
  1359. "(supported modes: %s).\n", supported_rc_modes_string);
  1360. return AVERROR(EINVAL);
  1361. rc_mode_found:
  1362. if (rc_mode->bitrate) {
  1363. if (avctx->bit_rate <= 0) {
  1364. av_log(avctx, AV_LOG_ERROR, "Bitrate must be set for %s "
  1365. "RC mode.\n", rc_mode->name);
  1366. return AVERROR(EINVAL);
  1367. }
  1368. if (rc_mode->mode == RC_MODE_AVBR) {
  1369. // For maximum confusion AVBR is hacked into the existing API
  1370. // by overloading some of the fields with completely different
  1371. // meanings.
  1372. // Target percentage does not apply in AVBR mode.
  1373. rc_bits_per_second = avctx->bit_rate;
  1374. // Accuracy tolerance range for meeting the specified target
  1375. // bitrate. It's very unclear how this is actually intended
  1376. // to work - since we do want to get the specified bitrate,
  1377. // set the accuracy to 100% for now.
  1378. rc_target_percentage = 100;
  1379. // Convergence period in frames. The GOP size reflects the
  1380. // user's intended block size for cutting, so reusing that
  1381. // as the convergence period seems a reasonable default.
  1382. rc_window_size = avctx->gop_size > 0 ? avctx->gop_size : 60;
  1383. } else if (rc_mode->maxrate) {
  1384. if (avctx->rc_max_rate > 0) {
  1385. if (avctx->rc_max_rate < avctx->bit_rate) {
  1386. av_log(avctx, AV_LOG_ERROR, "Invalid bitrate settings: "
  1387. "bitrate (%"PRId64") must not be greater than "
  1388. "maxrate (%"PRId64").\n", avctx->bit_rate,
  1389. avctx->rc_max_rate);
  1390. return AVERROR(EINVAL);
  1391. }
  1392. rc_bits_per_second = avctx->rc_max_rate;
  1393. rc_target_percentage = (avctx->bit_rate * 100) /
  1394. avctx->rc_max_rate;
  1395. } else {
  1396. // We only have a target bitrate, but this mode requires
  1397. // that a maximum rate be supplied as well. Since the
  1398. // user does not want this to be a constraint, arbitrarily
  1399. // pick a maximum rate of double the target rate.
  1400. rc_bits_per_second = 2 * avctx->bit_rate;
  1401. rc_target_percentage = 50;
  1402. }
  1403. } else {
  1404. if (avctx->rc_max_rate > avctx->bit_rate) {
  1405. av_log(avctx, AV_LOG_WARNING, "Max bitrate is ignored "
  1406. "in %s RC mode.\n", rc_mode->name);
  1407. }
  1408. rc_bits_per_second = avctx->bit_rate;
  1409. rc_target_percentage = 100;
  1410. }
  1411. } else {
  1412. rc_bits_per_second = 0;
  1413. rc_target_percentage = 100;
  1414. }
  1415. if (rc_mode->quality) {
  1416. if (ctx->explicit_qp) {
  1417. rc_quality = ctx->explicit_qp;
  1418. } else if (avctx->global_quality > 0) {
  1419. rc_quality = avctx->global_quality;
  1420. } else {
  1421. rc_quality = ctx->codec->default_quality;
  1422. av_log(avctx, AV_LOG_WARNING, "No quality level set; "
  1423. "using default (%d).\n", rc_quality);
  1424. }
  1425. } else {
  1426. rc_quality = 0;
  1427. }
  1428. if (rc_mode->hrd) {
  1429. if (avctx->rc_buffer_size)
  1430. hrd_buffer_size = avctx->rc_buffer_size;
  1431. else if (avctx->rc_max_rate > 0)
  1432. hrd_buffer_size = avctx->rc_max_rate;
  1433. else
  1434. hrd_buffer_size = avctx->bit_rate;
  1435. if (avctx->rc_initial_buffer_occupancy) {
  1436. if (avctx->rc_initial_buffer_occupancy > hrd_buffer_size) {
  1437. av_log(avctx, AV_LOG_ERROR, "Invalid RC buffer settings: "
  1438. "must have initial buffer size (%d) <= "
  1439. "buffer size (%"PRId64").\n",
  1440. avctx->rc_initial_buffer_occupancy, hrd_buffer_size);
  1441. return AVERROR(EINVAL);
  1442. }
  1443. hrd_initial_buffer_fullness = avctx->rc_initial_buffer_occupancy;
  1444. } else {
  1445. hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4;
  1446. }
  1447. rc_window_size = (hrd_buffer_size * 1000) / rc_bits_per_second;
  1448. } else {
  1449. if (avctx->rc_buffer_size || avctx->rc_initial_buffer_occupancy) {
  1450. av_log(avctx, AV_LOG_WARNING, "Buffering settings are ignored "
  1451. "in %s RC mode.\n", rc_mode->name);
  1452. }
  1453. hrd_buffer_size = 0;
  1454. hrd_initial_buffer_fullness = 0;
  1455. if (rc_mode->mode != RC_MODE_AVBR) {
  1456. // Already set (with completely different meaning) for AVBR.
  1457. rc_window_size = 1000;
  1458. }
  1459. }
  1460. if (rc_bits_per_second > UINT32_MAX ||
  1461. hrd_buffer_size > UINT32_MAX ||
  1462. hrd_initial_buffer_fullness > UINT32_MAX) {
  1463. av_log(avctx, AV_LOG_ERROR, "RC parameters of 2^32 or "
  1464. "greater are not supported by VAAPI.\n");
  1465. return AVERROR(EINVAL);
  1466. }
  1467. ctx->rc_mode = rc_mode;
  1468. ctx->rc_quality = rc_quality;
  1469. ctx->va_rc_mode = rc_mode->va_mode;
  1470. ctx->va_bit_rate = rc_bits_per_second;
  1471. av_log(avctx, AV_LOG_VERBOSE, "RC mode: %s.\n", rc_mode->name);
  1472. if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
  1473. // This driver does not want the RC mode attribute to be set.
  1474. } else {
  1475. ctx->config_attributes[ctx->nb_config_attributes++] =
  1476. (VAConfigAttrib) {
  1477. .type = VAConfigAttribRateControl,
  1478. .value = ctx->va_rc_mode,
  1479. };
  1480. }
  1481. if (rc_mode->quality)
  1482. av_log(avctx, AV_LOG_VERBOSE, "RC quality: %d.\n", rc_quality);
  1483. if (rc_mode->va_mode != VA_RC_CQP) {
  1484. if (rc_mode->mode == RC_MODE_AVBR) {
  1485. av_log(avctx, AV_LOG_VERBOSE, "RC target: %"PRId64" bps "
  1486. "converging in %d frames with %d%% accuracy.\n",
  1487. rc_bits_per_second, rc_window_size,
  1488. rc_target_percentage);
  1489. } else if (rc_mode->bitrate) {
  1490. av_log(avctx, AV_LOG_VERBOSE, "RC target: %d%% of "
  1491. "%"PRId64" bps over %d ms.\n", rc_target_percentage,
  1492. rc_bits_per_second, rc_window_size);
  1493. }
  1494. ctx->rc_params = (VAEncMiscParameterRateControl) {
  1495. .bits_per_second = rc_bits_per_second,
  1496. .target_percentage = rc_target_percentage,
  1497. .window_size = rc_window_size,
  1498. .initial_qp = 0,
  1499. .min_qp = (avctx->qmin > 0 ? avctx->qmin : 0),
  1500. .basic_unit_size = 0,
  1501. #if VA_CHECK_VERSION(1, 1, 0)
  1502. .ICQ_quality_factor = av_clip(rc_quality, 1, 51),
  1503. .max_qp = (avctx->qmax > 0 ? avctx->qmax : 0),
  1504. #endif
  1505. #if VA_CHECK_VERSION(1, 3, 0)
  1506. .quality_factor = rc_quality,
  1507. #endif
  1508. };
  1509. vaapi_encode_add_global_param(avctx,
  1510. VAEncMiscParameterTypeRateControl,
  1511. &ctx->rc_params,
  1512. sizeof(ctx->rc_params));
  1513. }
  1514. if (rc_mode->hrd) {
  1515. av_log(avctx, AV_LOG_VERBOSE, "RC buffer: %"PRId64" bits, "
  1516. "initial fullness %"PRId64" bits.\n",
  1517. hrd_buffer_size, hrd_initial_buffer_fullness);
  1518. ctx->hrd_params = (VAEncMiscParameterHRD) {
  1519. .initial_buffer_fullness = hrd_initial_buffer_fullness,
  1520. .buffer_size = hrd_buffer_size,
  1521. };
  1522. vaapi_encode_add_global_param(avctx,
  1523. VAEncMiscParameterTypeHRD,
  1524. &ctx->hrd_params,
  1525. sizeof(ctx->hrd_params));
  1526. }
  1527. if (avctx->framerate.num > 0 && avctx->framerate.den > 0)
  1528. av_reduce(&fr_num, &fr_den,
  1529. avctx->framerate.num, avctx->framerate.den, 65535);
  1530. else
  1531. av_reduce(&fr_num, &fr_den,
  1532. avctx->time_base.den, avctx->time_base.num, 65535);
  1533. av_log(avctx, AV_LOG_VERBOSE, "RC framerate: %d/%d (%.2f fps).\n",
  1534. fr_num, fr_den, (double)fr_num / fr_den);
  1535. ctx->fr_params = (VAEncMiscParameterFrameRate) {
  1536. .framerate = (unsigned int)fr_den << 16 | fr_num,
  1537. };
  1538. #if VA_CHECK_VERSION(0, 40, 0)
  1539. vaapi_encode_add_global_param(avctx,
  1540. VAEncMiscParameterTypeFrameRate,
  1541. &ctx->fr_params,
  1542. sizeof(ctx->fr_params));
  1543. #endif
  1544. return 0;
  1545. }
  1546. static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx)
  1547. {
  1548. VAAPIEncodeContext *ctx = avctx->priv_data;
  1549. VAStatus vas;
  1550. VAConfigAttrib attr = { VAConfigAttribEncMaxRefFrames };
  1551. uint32_t ref_l0, ref_l1;
  1552. vas = vaGetConfigAttributes(ctx->hwctx->display,
  1553. ctx->va_profile,
  1554. ctx->va_entrypoint,
  1555. &attr, 1);
  1556. if (vas != VA_STATUS_SUCCESS) {
  1557. av_log(avctx, AV_LOG_ERROR, "Failed to query reference frames "
  1558. "attribute: %d (%s).\n", vas, vaErrorStr(vas));
  1559. return AVERROR_EXTERNAL;
  1560. }
  1561. if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
  1562. ref_l0 = ref_l1 = 0;
  1563. } else {
  1564. ref_l0 = attr.value & 0xffff;
  1565. ref_l1 = attr.value >> 16 & 0xffff;
  1566. }
  1567. if (ctx->codec->flags & FLAG_INTRA_ONLY ||
  1568. avctx->gop_size <= 1) {
  1569. av_log(avctx, AV_LOG_VERBOSE, "Using intra frames only.\n");
  1570. ctx->gop_size = 1;
  1571. } else if (ref_l0 < 1) {
  1572. av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
  1573. "reference frames.\n");
  1574. return AVERROR(EINVAL);
  1575. } else if (!(ctx->codec->flags & FLAG_B_PICTURES) ||
  1576. ref_l1 < 1 || avctx->max_b_frames < 1) {
  1577. av_log(avctx, AV_LOG_VERBOSE, "Using intra and P-frames "
  1578. "(supported references: %d / %d).\n", ref_l0, ref_l1);
  1579. ctx->gop_size = avctx->gop_size;
  1580. ctx->p_per_i = INT_MAX;
  1581. ctx->b_per_p = 0;
  1582. } else {
  1583. av_log(avctx, AV_LOG_VERBOSE, "Using intra, P- and B-frames "
  1584. "(supported references: %d / %d).\n", ref_l0, ref_l1);
  1585. ctx->gop_size = avctx->gop_size;
  1586. ctx->p_per_i = INT_MAX;
  1587. ctx->b_per_p = avctx->max_b_frames;
  1588. if (ctx->codec->flags & FLAG_B_PICTURE_REFERENCES) {
  1589. ctx->max_b_depth = FFMIN(ctx->desired_b_depth,
  1590. av_log2(ctx->b_per_p) + 1);
  1591. } else {
  1592. ctx->max_b_depth = 1;
  1593. }
  1594. }
  1595. if (ctx->codec->flags & FLAG_NON_IDR_KEY_PICTURES) {
  1596. ctx->closed_gop = !!(avctx->flags & AV_CODEC_FLAG_CLOSED_GOP);
  1597. ctx->gop_per_idr = ctx->idr_interval + 1;
  1598. } else {
  1599. ctx->closed_gop = 1;
  1600. ctx->gop_per_idr = 1;
  1601. }
  1602. return 0;
  1603. }
  1604. static av_cold int vaapi_encode_init_slice_structure(AVCodecContext *avctx)
  1605. {
  1606. VAAPIEncodeContext *ctx = avctx->priv_data;
  1607. VAConfigAttrib attr[2] = { { VAConfigAttribEncMaxSlices },
  1608. { VAConfigAttribEncSliceStructure } };
  1609. VAStatus vas;
  1610. uint32_t max_slices, slice_structure;
  1611. int req_slices;
  1612. if (!(ctx->codec->flags & FLAG_SLICE_CONTROL)) {
  1613. if (avctx->slices > 0) {
  1614. av_log(avctx, AV_LOG_WARNING, "Multiple slices were requested "
  1615. "but this codec does not support controlling slices.\n");
  1616. }
  1617. return 0;
  1618. }
  1619. ctx->slice_block_rows = (avctx->height + ctx->slice_block_height - 1) /
  1620. ctx->slice_block_height;
  1621. ctx->slice_block_cols = (avctx->width + ctx->slice_block_width - 1) /
  1622. ctx->slice_block_width;
  1623. if (avctx->slices <= 1) {
  1624. ctx->nb_slices = 1;
  1625. ctx->slice_size = ctx->slice_block_rows;
  1626. return 0;
  1627. }
  1628. vas = vaGetConfigAttributes(ctx->hwctx->display,
  1629. ctx->va_profile,
  1630. ctx->va_entrypoint,
  1631. attr, FF_ARRAY_ELEMS(attr));
  1632. if (vas != VA_STATUS_SUCCESS) {
  1633. av_log(avctx, AV_LOG_ERROR, "Failed to query slice "
  1634. "attributes: %d (%s).\n", vas, vaErrorStr(vas));
  1635. return AVERROR_EXTERNAL;
  1636. }
  1637. max_slices = attr[0].value;
  1638. slice_structure = attr[1].value;
  1639. if (max_slices == VA_ATTRIB_NOT_SUPPORTED ||
  1640. slice_structure == VA_ATTRIB_NOT_SUPPORTED) {
  1641. av_log(avctx, AV_LOG_ERROR, "Driver does not support encoding "
  1642. "pictures as multiple slices.\n.");
  1643. return AVERROR(EINVAL);
  1644. }
  1645. // For fixed-size slices currently we only support whole rows, making
  1646. // rectangular slices. This could be extended to arbitrary runs of
  1647. // blocks, but since slices tend to be a conformance requirement and
  1648. // most cases (such as broadcast or bluray) want rectangular slices
  1649. // only it would need to be gated behind another option.
  1650. if (avctx->slices > ctx->slice_block_rows) {
  1651. av_log(avctx, AV_LOG_WARNING, "Not enough rows to use "
  1652. "configured number of slices (%d < %d); using "
  1653. "maximum.\n", ctx->slice_block_rows, avctx->slices);
  1654. req_slices = ctx->slice_block_rows;
  1655. } else {
  1656. req_slices = avctx->slices;
  1657. }
  1658. if (slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS ||
  1659. slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS) {
  1660. ctx->nb_slices = req_slices;
  1661. ctx->slice_size = ctx->slice_block_rows / ctx->nb_slices;
  1662. } else if (slice_structure & VA_ENC_SLICE_STRUCTURE_POWER_OF_TWO_ROWS) {
  1663. int k;
  1664. for (k = 1;; k *= 2) {
  1665. if (2 * k * (req_slices - 1) + 1 >= ctx->slice_block_rows)
  1666. break;
  1667. }
  1668. ctx->nb_slices = (ctx->slice_block_rows + k - 1) / k;
  1669. ctx->slice_size = k;
  1670. #if VA_CHECK_VERSION(1, 0, 0)
  1671. } else if (slice_structure & VA_ENC_SLICE_STRUCTURE_EQUAL_ROWS) {
  1672. ctx->nb_slices = ctx->slice_block_rows;
  1673. ctx->slice_size = 1;
  1674. #endif
  1675. } else {
  1676. av_log(avctx, AV_LOG_ERROR, "Driver does not support any usable "
  1677. "slice structure modes (%#x).\n", slice_structure);
  1678. return AVERROR(EINVAL);
  1679. }
  1680. if (ctx->nb_slices > avctx->slices) {
  1681. av_log(avctx, AV_LOG_WARNING, "Slice count rounded up to "
  1682. "%d (from %d) due to driver constraints on slice "
  1683. "structure.\n", ctx->nb_slices, avctx->slices);
  1684. }
  1685. if (ctx->nb_slices > max_slices) {
  1686. av_log(avctx, AV_LOG_ERROR, "Driver does not support "
  1687. "encoding with %d slices (max %"PRIu32").\n",
  1688. ctx->nb_slices, max_slices);
  1689. return AVERROR(EINVAL);
  1690. }
  1691. av_log(avctx, AV_LOG_VERBOSE, "Encoding pictures with %d slices "
  1692. "(default size %d block rows).\n",
  1693. ctx->nb_slices, ctx->slice_size);
  1694. return 0;
  1695. }
  1696. static av_cold int vaapi_encode_init_packed_headers(AVCodecContext *avctx)
  1697. {
  1698. VAAPIEncodeContext *ctx = avctx->priv_data;
  1699. VAStatus vas;
  1700. VAConfigAttrib attr = { VAConfigAttribEncPackedHeaders };
  1701. vas = vaGetConfigAttributes(ctx->hwctx->display,
  1702. ctx->va_profile,
  1703. ctx->va_entrypoint,
  1704. &attr, 1);
  1705. if (vas != VA_STATUS_SUCCESS) {
  1706. av_log(avctx, AV_LOG_ERROR, "Failed to query packed headers "
  1707. "attribute: %d (%s).\n", vas, vaErrorStr(vas));
  1708. return AVERROR_EXTERNAL;
  1709. }
  1710. if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
  1711. if (ctx->desired_packed_headers) {
  1712. av_log(avctx, AV_LOG_WARNING, "Driver does not support any "
  1713. "packed headers (wanted %#x).\n",
  1714. ctx->desired_packed_headers);
  1715. } else {
  1716. av_log(avctx, AV_LOG_VERBOSE, "Driver does not support any "
  1717. "packed headers (none wanted).\n");
  1718. }
  1719. ctx->va_packed_headers = 0;
  1720. } else {
  1721. if (ctx->desired_packed_headers & ~attr.value) {
  1722. av_log(avctx, AV_LOG_WARNING, "Driver does not support some "
  1723. "wanted packed headers (wanted %#x, found %#x).\n",
  1724. ctx->desired_packed_headers, attr.value);
  1725. } else {
  1726. av_log(avctx, AV_LOG_VERBOSE, "All wanted packed headers "
  1727. "available (wanted %#x, found %#x).\n",
  1728. ctx->desired_packed_headers, attr.value);
  1729. }
  1730. ctx->va_packed_headers = ctx->desired_packed_headers & attr.value;
  1731. }
  1732. if (ctx->va_packed_headers) {
  1733. ctx->config_attributes[ctx->nb_config_attributes++] =
  1734. (VAConfigAttrib) {
  1735. .type = VAConfigAttribEncPackedHeaders,
  1736. .value = ctx->va_packed_headers,
  1737. };
  1738. }
  1739. if ( (ctx->desired_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE) &&
  1740. !(ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE) &&
  1741. (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)) {
  1742. av_log(avctx, AV_LOG_WARNING, "Driver does not support packed "
  1743. "sequence headers, but a global header is requested.\n");
  1744. av_log(avctx, AV_LOG_WARNING, "No global header will be written: "
  1745. "this may result in a stream which is not usable for some "
  1746. "purposes (e.g. not muxable to some containers).\n");
  1747. }
  1748. return 0;
  1749. }
  1750. static av_cold int vaapi_encode_init_quality(AVCodecContext *avctx)
  1751. {
  1752. #if VA_CHECK_VERSION(0, 36, 0)
  1753. VAAPIEncodeContext *ctx = avctx->priv_data;
  1754. VAStatus vas;
  1755. VAConfigAttrib attr = { VAConfigAttribEncQualityRange };
  1756. int quality = avctx->compression_level;
  1757. vas = vaGetConfigAttributes(ctx->hwctx->display,
  1758. ctx->va_profile,
  1759. ctx->va_entrypoint,
  1760. &attr, 1);
  1761. if (vas != VA_STATUS_SUCCESS) {
  1762. av_log(avctx, AV_LOG_ERROR, "Failed to query quality "
  1763. "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
  1764. return AVERROR_EXTERNAL;
  1765. }
  1766. if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
  1767. if (quality != 0) {
  1768. av_log(avctx, AV_LOG_WARNING, "Quality attribute is not "
  1769. "supported: will use default quality level.\n");
  1770. }
  1771. } else {
  1772. if (quality > attr.value) {
  1773. av_log(avctx, AV_LOG_WARNING, "Invalid quality level: "
  1774. "valid range is 0-%d, using %d.\n",
  1775. attr.value, attr.value);
  1776. quality = attr.value;
  1777. }
  1778. ctx->quality_params = (VAEncMiscParameterBufferQualityLevel) {
  1779. .quality_level = quality,
  1780. };
  1781. vaapi_encode_add_global_param(avctx,
  1782. VAEncMiscParameterTypeQualityLevel,
  1783. &ctx->quality_params,
  1784. sizeof(ctx->quality_params));
  1785. }
  1786. #else
  1787. av_log(avctx, AV_LOG_WARNING, "The encode quality option is "
  1788. "not supported with this VAAPI version.\n");
  1789. #endif
  1790. return 0;
  1791. }
  1792. static av_cold int vaapi_encode_init_roi(AVCodecContext *avctx)
  1793. {
  1794. #if VA_CHECK_VERSION(1, 0, 0)
  1795. VAAPIEncodeContext *ctx = avctx->priv_data;
  1796. VAStatus vas;
  1797. VAConfigAttrib attr = { VAConfigAttribEncROI };
  1798. vas = vaGetConfigAttributes(ctx->hwctx->display,
  1799. ctx->va_profile,
  1800. ctx->va_entrypoint,
  1801. &attr, 1);
  1802. if (vas != VA_STATUS_SUCCESS) {
  1803. av_log(avctx, AV_LOG_ERROR, "Failed to query ROI "
  1804. "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
  1805. return AVERROR_EXTERNAL;
  1806. }
  1807. if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
  1808. ctx->roi_allowed = 0;
  1809. } else {
  1810. VAConfigAttribValEncROI roi = {
  1811. .value = attr.value,
  1812. };
  1813. ctx->roi_max_regions = roi.bits.num_roi_regions;
  1814. ctx->roi_allowed = ctx->roi_max_regions > 0 &&
  1815. (ctx->va_rc_mode == VA_RC_CQP ||
  1816. roi.bits.roi_rc_qp_delta_support);
  1817. }
  1818. #endif
  1819. return 0;
  1820. }
  1821. static void vaapi_encode_free_output_buffer(void *opaque,
  1822. uint8_t *data)
  1823. {
  1824. AVCodecContext *avctx = opaque;
  1825. VAAPIEncodeContext *ctx = avctx->priv_data;
  1826. VABufferID buffer_id;
  1827. buffer_id = (VABufferID)(uintptr_t)data;
  1828. vaDestroyBuffer(ctx->hwctx->display, buffer_id);
  1829. av_log(avctx, AV_LOG_DEBUG, "Freed output buffer %#x\n", buffer_id);
  1830. }
  1831. static AVBufferRef *vaapi_encode_alloc_output_buffer(void *opaque,
  1832. int size)
  1833. {
  1834. AVCodecContext *avctx = opaque;
  1835. VAAPIEncodeContext *ctx = avctx->priv_data;
  1836. VABufferID buffer_id;
  1837. VAStatus vas;
  1838. AVBufferRef *ref;
  1839. // The output buffer size is fixed, so it needs to be large enough
  1840. // to hold the largest possible compressed frame. We assume here
  1841. // that the uncompressed frame plus some header data is an upper
  1842. // bound on that.
  1843. vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
  1844. VAEncCodedBufferType,
  1845. 3 * ctx->surface_width * ctx->surface_height +
  1846. (1 << 16), 1, 0, &buffer_id);
  1847. if (vas != VA_STATUS_SUCCESS) {
  1848. av_log(avctx, AV_LOG_ERROR, "Failed to create bitstream "
  1849. "output buffer: %d (%s).\n", vas, vaErrorStr(vas));
  1850. return NULL;
  1851. }
  1852. av_log(avctx, AV_LOG_DEBUG, "Allocated output buffer %#x\n", buffer_id);
  1853. ref = av_buffer_create((uint8_t*)(uintptr_t)buffer_id,
  1854. sizeof(buffer_id),
  1855. &vaapi_encode_free_output_buffer,
  1856. avctx, AV_BUFFER_FLAG_READONLY);
  1857. if (!ref) {
  1858. vaDestroyBuffer(ctx->hwctx->display, buffer_id);
  1859. return NULL;
  1860. }
  1861. return ref;
  1862. }
  1863. static av_cold int vaapi_encode_create_recon_frames(AVCodecContext *avctx)
  1864. {
  1865. VAAPIEncodeContext *ctx = avctx->priv_data;
  1866. AVVAAPIHWConfig *hwconfig = NULL;
  1867. AVHWFramesConstraints *constraints = NULL;
  1868. enum AVPixelFormat recon_format;
  1869. int err, i;
  1870. hwconfig = av_hwdevice_hwconfig_alloc(ctx->device_ref);
  1871. if (!hwconfig) {
  1872. err = AVERROR(ENOMEM);
  1873. goto fail;
  1874. }
  1875. hwconfig->config_id = ctx->va_config;
  1876. constraints = av_hwdevice_get_hwframe_constraints(ctx->device_ref,
  1877. hwconfig);
  1878. if (!constraints) {
  1879. err = AVERROR(ENOMEM);
  1880. goto fail;
  1881. }
  1882. // Probably we can use the input surface format as the surface format
  1883. // of the reconstructed frames. If not, we just pick the first (only?)
  1884. // format in the valid list and hope that it all works.
  1885. recon_format = AV_PIX_FMT_NONE;
  1886. if (constraints->valid_sw_formats) {
  1887. for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) {
  1888. if (ctx->input_frames->sw_format ==
  1889. constraints->valid_sw_formats[i]) {
  1890. recon_format = ctx->input_frames->sw_format;
  1891. break;
  1892. }
  1893. }
  1894. if (recon_format == AV_PIX_FMT_NONE) {
  1895. // No match. Just use the first in the supported list and
  1896. // hope for the best.
  1897. recon_format = constraints->valid_sw_formats[0];
  1898. }
  1899. } else {
  1900. // No idea what to use; copy input format.
  1901. recon_format = ctx->input_frames->sw_format;
  1902. }
  1903. av_log(avctx, AV_LOG_DEBUG, "Using %s as format of "
  1904. "reconstructed frames.\n", av_get_pix_fmt_name(recon_format));
  1905. if (ctx->surface_width < constraints->min_width ||
  1906. ctx->surface_height < constraints->min_height ||
  1907. ctx->surface_width > constraints->max_width ||
  1908. ctx->surface_height > constraints->max_height) {
  1909. av_log(avctx, AV_LOG_ERROR, "Hardware does not support encoding at "
  1910. "size %dx%d (constraints: width %d-%d height %d-%d).\n",
  1911. ctx->surface_width, ctx->surface_height,
  1912. constraints->min_width, constraints->max_width,
  1913. constraints->min_height, constraints->max_height);
  1914. err = AVERROR(EINVAL);
  1915. goto fail;
  1916. }
  1917. av_freep(&hwconfig);
  1918. av_hwframe_constraints_free(&constraints);
  1919. ctx->recon_frames_ref = av_hwframe_ctx_alloc(ctx->device_ref);
  1920. if (!ctx->recon_frames_ref) {
  1921. err = AVERROR(ENOMEM);
  1922. goto fail;
  1923. }
  1924. ctx->recon_frames = (AVHWFramesContext*)ctx->recon_frames_ref->data;
  1925. ctx->recon_frames->format = AV_PIX_FMT_VAAPI;
  1926. ctx->recon_frames->sw_format = recon_format;
  1927. ctx->recon_frames->width = ctx->surface_width;
  1928. ctx->recon_frames->height = ctx->surface_height;
  1929. err = av_hwframe_ctx_init(ctx->recon_frames_ref);
  1930. if (err < 0) {
  1931. av_log(avctx, AV_LOG_ERROR, "Failed to initialise reconstructed "
  1932. "frame context: %d.\n", err);
  1933. goto fail;
  1934. }
  1935. err = 0;
  1936. fail:
  1937. av_freep(&hwconfig);
  1938. av_hwframe_constraints_free(&constraints);
  1939. return err;
  1940. }
  1941. av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
  1942. {
  1943. VAAPIEncodeContext *ctx = avctx->priv_data;
  1944. AVVAAPIFramesContext *recon_hwctx = NULL;
  1945. VAStatus vas;
  1946. int err;
  1947. ctx->frame = av_frame_alloc();
  1948. if (!ctx->frame) {
  1949. return AVERROR(ENOMEM);
  1950. }
  1951. if (!avctx->hw_frames_ctx) {
  1952. av_log(avctx, AV_LOG_ERROR, "A hardware frames reference is "
  1953. "required to associate the encoding device.\n");
  1954. return AVERROR(EINVAL);
  1955. }
  1956. ctx->va_config = VA_INVALID_ID;
  1957. ctx->va_context = VA_INVALID_ID;
  1958. ctx->input_frames_ref = av_buffer_ref(avctx->hw_frames_ctx);
  1959. if (!ctx->input_frames_ref) {
  1960. err = AVERROR(ENOMEM);
  1961. goto fail;
  1962. }
  1963. ctx->input_frames = (AVHWFramesContext*)ctx->input_frames_ref->data;
  1964. ctx->device_ref = av_buffer_ref(ctx->input_frames->device_ref);
  1965. if (!ctx->device_ref) {
  1966. err = AVERROR(ENOMEM);
  1967. goto fail;
  1968. }
  1969. ctx->device = (AVHWDeviceContext*)ctx->device_ref->data;
  1970. ctx->hwctx = ctx->device->hwctx;
  1971. err = vaapi_encode_profile_entrypoint(avctx);
  1972. if (err < 0)
  1973. goto fail;
  1974. err = vaapi_encode_init_rate_control(avctx);
  1975. if (err < 0)
  1976. goto fail;
  1977. err = vaapi_encode_init_gop_structure(avctx);
  1978. if (err < 0)
  1979. goto fail;
  1980. err = vaapi_encode_init_slice_structure(avctx);
  1981. if (err < 0)
  1982. goto fail;
  1983. err = vaapi_encode_init_packed_headers(avctx);
  1984. if (err < 0)
  1985. goto fail;
  1986. err = vaapi_encode_init_roi(avctx);
  1987. if (err < 0)
  1988. goto fail;
  1989. if (avctx->compression_level >= 0) {
  1990. err = vaapi_encode_init_quality(avctx);
  1991. if (err < 0)
  1992. goto fail;
  1993. }
  1994. vas = vaCreateConfig(ctx->hwctx->display,
  1995. ctx->va_profile, ctx->va_entrypoint,
  1996. ctx->config_attributes, ctx->nb_config_attributes,
  1997. &ctx->va_config);
  1998. if (vas != VA_STATUS_SUCCESS) {
  1999. av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "
  2000. "configuration: %d (%s).\n", vas, vaErrorStr(vas));
  2001. err = AVERROR(EIO);
  2002. goto fail;
  2003. }
  2004. err = vaapi_encode_create_recon_frames(avctx);
  2005. if (err < 0)
  2006. goto fail;
  2007. recon_hwctx = ctx->recon_frames->hwctx;
  2008. vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,
  2009. ctx->surface_width, ctx->surface_height,
  2010. VA_PROGRESSIVE,
  2011. recon_hwctx->surface_ids,
  2012. recon_hwctx->nb_surfaces,
  2013. &ctx->va_context);
  2014. if (vas != VA_STATUS_SUCCESS) {
  2015. av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "
  2016. "context: %d (%s).\n", vas, vaErrorStr(vas));
  2017. err = AVERROR(EIO);
  2018. goto fail;
  2019. }
  2020. ctx->output_buffer_pool =
  2021. av_buffer_pool_init2(sizeof(VABufferID), avctx,
  2022. &vaapi_encode_alloc_output_buffer, NULL);
  2023. if (!ctx->output_buffer_pool) {
  2024. err = AVERROR(ENOMEM);
  2025. goto fail;
  2026. }
  2027. if (ctx->codec->configure) {
  2028. err = ctx->codec->configure(avctx);
  2029. if (err < 0)
  2030. goto fail;
  2031. }
  2032. ctx->output_delay = ctx->b_per_p;
  2033. ctx->decode_delay = ctx->max_b_depth;
  2034. if (ctx->codec->sequence_params_size > 0) {
  2035. ctx->codec_sequence_params =
  2036. av_mallocz(ctx->codec->sequence_params_size);
  2037. if (!ctx->codec_sequence_params) {
  2038. err = AVERROR(ENOMEM);
  2039. goto fail;
  2040. }
  2041. }
  2042. if (ctx->codec->picture_params_size > 0) {
  2043. ctx->codec_picture_params =
  2044. av_mallocz(ctx->codec->picture_params_size);
  2045. if (!ctx->codec_picture_params) {
  2046. err = AVERROR(ENOMEM);
  2047. goto fail;
  2048. }
  2049. }
  2050. if (ctx->codec->init_sequence_params) {
  2051. err = ctx->codec->init_sequence_params(avctx);
  2052. if (err < 0) {
  2053. av_log(avctx, AV_LOG_ERROR, "Codec sequence initialisation "
  2054. "failed: %d.\n", err);
  2055. goto fail;
  2056. }
  2057. }
  2058. if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
  2059. ctx->codec->write_sequence_header &&
  2060. avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
  2061. char data[MAX_PARAM_BUFFER_SIZE];
  2062. size_t bit_len = 8 * sizeof(data);
  2063. err = ctx->codec->write_sequence_header(avctx, data, &bit_len);
  2064. if (err < 0) {
  2065. av_log(avctx, AV_LOG_ERROR, "Failed to write sequence header "
  2066. "for extradata: %d.\n", err);
  2067. goto fail;
  2068. } else {
  2069. avctx->extradata_size = (bit_len + 7) / 8;
  2070. avctx->extradata = av_mallocz(avctx->extradata_size +
  2071. AV_INPUT_BUFFER_PADDING_SIZE);
  2072. if (!avctx->extradata) {
  2073. err = AVERROR(ENOMEM);
  2074. goto fail;
  2075. }
  2076. memcpy(avctx->extradata, data, avctx->extradata_size);
  2077. }
  2078. }
  2079. return 0;
  2080. fail:
  2081. return err;
  2082. }
  2083. av_cold int ff_vaapi_encode_close(AVCodecContext *avctx)
  2084. {
  2085. VAAPIEncodeContext *ctx = avctx->priv_data;
  2086. VAAPIEncodePicture *pic, *next;
  2087. for (pic = ctx->pic_start; pic; pic = next) {
  2088. next = pic->next;
  2089. vaapi_encode_free(avctx, pic);
  2090. }
  2091. av_buffer_pool_uninit(&ctx->output_buffer_pool);
  2092. if (ctx->va_context != VA_INVALID_ID) {
  2093. vaDestroyContext(ctx->hwctx->display, ctx->va_context);
  2094. ctx->va_context = VA_INVALID_ID;
  2095. }
  2096. if (ctx->va_config != VA_INVALID_ID) {
  2097. vaDestroyConfig(ctx->hwctx->display, ctx->va_config);
  2098. ctx->va_config = VA_INVALID_ID;
  2099. }
  2100. av_frame_free(&ctx->frame);
  2101. av_freep(&ctx->codec_sequence_params);
  2102. av_freep(&ctx->codec_picture_params);
  2103. av_buffer_unref(&ctx->recon_frames_ref);
  2104. av_buffer_unref(&ctx->input_frames_ref);
  2105. av_buffer_unref(&ctx->device_ref);
  2106. return 0;
  2107. }