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.

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