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.

1097 lines
35KB

  1. /*
  2. * This file is part of Libav.
  3. *
  4. * Libav 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. * Libav 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 Libav; 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/log.h"
  22. #include "libavutil/pixdesc.h"
  23. #include "vaapi_encode.h"
  24. #include "avcodec.h"
  25. static const char *picture_type_name[] = { "IDR", "I", "P", "B" };
  26. static int vaapi_encode_make_packed_header(AVCodecContext *avctx,
  27. VAAPIEncodePicture *pic,
  28. int type, char *data, size_t bit_len)
  29. {
  30. VAAPIEncodeContext *ctx = avctx->priv_data;
  31. VAStatus vas;
  32. VABufferID param_buffer, data_buffer;
  33. VAEncPackedHeaderParameterBuffer params = {
  34. .type = type,
  35. .bit_length = bit_len,
  36. .has_emulation_bytes = 1,
  37. };
  38. av_assert0(pic->nb_param_buffers + 2 <= MAX_PARAM_BUFFERS);
  39. vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
  40. VAEncPackedHeaderParameterBufferType,
  41. sizeof(params), 1, &params, &param_buffer);
  42. if (vas != VA_STATUS_SUCCESS) {
  43. av_log(avctx, AV_LOG_ERROR, "Failed to create parameter buffer "
  44. "for packed header (type %d): %d (%s).\n",
  45. type, vas, vaErrorStr(vas));
  46. return AVERROR(EIO);
  47. }
  48. pic->param_buffers[pic->nb_param_buffers++] = param_buffer;
  49. vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
  50. VAEncPackedHeaderDataBufferType,
  51. (bit_len + 7) / 8, 1, data, &data_buffer);
  52. if (vas != VA_STATUS_SUCCESS) {
  53. av_log(avctx, AV_LOG_ERROR, "Failed to create data 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++] = data_buffer;
  59. av_log(avctx, AV_LOG_DEBUG, "Packed header buffer (%d) is %#x/%#x "
  60. "(%zu bits).\n", type, param_buffer, data_buffer, bit_len);
  61. return 0;
  62. }
  63. static int vaapi_encode_make_param_buffer(AVCodecContext *avctx,
  64. VAAPIEncodePicture *pic,
  65. int type, char *data, size_t len)
  66. {
  67. VAAPIEncodeContext *ctx = avctx->priv_data;
  68. VAStatus vas;
  69. VABufferID buffer;
  70. av_assert0(pic->nb_param_buffers + 1 <= MAX_PARAM_BUFFERS);
  71. vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
  72. type, len, 1, data, &buffer);
  73. if (vas != VA_STATUS_SUCCESS) {
  74. av_log(avctx, AV_LOG_ERROR, "Failed to create parameter buffer "
  75. "(type %d): %d (%s).\n", type, vas, vaErrorStr(vas));
  76. return AVERROR(EIO);
  77. }
  78. pic->param_buffers[pic->nb_param_buffers++] = buffer;
  79. av_log(avctx, AV_LOG_DEBUG, "Param buffer (%d) is %#x.\n",
  80. type, buffer);
  81. return 0;
  82. }
  83. static int vaapi_encode_wait(AVCodecContext *avctx,
  84. VAAPIEncodePicture *pic)
  85. {
  86. VAAPIEncodeContext *ctx = avctx->priv_data;
  87. VAStatus vas;
  88. av_assert0(pic->encode_issued);
  89. if (pic->encode_complete) {
  90. // Already waited for this picture.
  91. return 0;
  92. }
  93. av_log(avctx, AV_LOG_DEBUG, "Sync to pic %"PRId64"/%"PRId64" "
  94. "(recon surface %#x).\n", pic->display_order,
  95. pic->encode_order, pic->recon_surface);
  96. vas = vaSyncSurface(ctx->hwctx->display, pic->recon_surface);
  97. if (vas != VA_STATUS_SUCCESS) {
  98. av_log(avctx, AV_LOG_ERROR, "Failed to sync to picture completion: "
  99. "%d (%s).\n", vas, vaErrorStr(vas));
  100. return AVERROR(EIO);
  101. }
  102. // Input is definitely finished with now.
  103. av_frame_free(&pic->input_image);
  104. pic->encode_complete = 1;
  105. return 0;
  106. }
  107. static int vaapi_encode_issue(AVCodecContext *avctx,
  108. VAAPIEncodePicture *pic)
  109. {
  110. VAAPIEncodeContext *ctx = avctx->priv_data;
  111. VAAPIEncodeSlice *slice;
  112. VAStatus vas;
  113. int err, i;
  114. char data[MAX_PARAM_BUFFER_SIZE];
  115. size_t bit_len;
  116. av_log(avctx, AV_LOG_DEBUG, "Issuing encode for pic %"PRId64"/%"PRId64" "
  117. "as type %s.\n", pic->display_order, pic->encode_order,
  118. picture_type_name[pic->type]);
  119. if (pic->nb_refs == 0) {
  120. av_log(avctx, AV_LOG_DEBUG, "No reference pictures.\n");
  121. } else {
  122. av_log(avctx, AV_LOG_DEBUG, "Refers to:");
  123. for (i = 0; i < pic->nb_refs; i++) {
  124. av_log(avctx, AV_LOG_DEBUG, " %"PRId64"/%"PRId64,
  125. pic->refs[i]->display_order, pic->refs[i]->encode_order);
  126. }
  127. av_log(avctx, AV_LOG_DEBUG, ".\n");
  128. }
  129. av_assert0(pic->input_available && !pic->encode_issued);
  130. for (i = 0; i < pic->nb_refs; i++) {
  131. av_assert0(pic->refs[i]);
  132. // If we are serialised then the references must have already
  133. // completed. If not, they must have been issued but need not
  134. // have completed yet.
  135. if (ctx->issue_mode == ISSUE_MODE_SERIALISE_EVERYTHING)
  136. av_assert0(pic->refs[i]->encode_complete);
  137. else
  138. av_assert0(pic->refs[i]->encode_issued);
  139. }
  140. av_log(avctx, AV_LOG_DEBUG, "Input surface is %#x.\n", pic->input_surface);
  141. pic->recon_image = av_frame_alloc();
  142. if (!pic->recon_image) {
  143. err = AVERROR(ENOMEM);
  144. goto fail;
  145. }
  146. err = av_hwframe_get_buffer(ctx->recon_frames_ref, pic->recon_image, 0);
  147. if (err < 0) {
  148. err = AVERROR(ENOMEM);
  149. goto fail;
  150. }
  151. pic->recon_surface = (VASurfaceID)(uintptr_t)pic->recon_image->data[3];
  152. av_log(avctx, AV_LOG_DEBUG, "Recon surface is %#x.\n", pic->recon_surface);
  153. vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
  154. VAEncCodedBufferType,
  155. MAX_OUTPUT_BUFFER_SIZE, 1, 0,
  156. &pic->output_buffer);
  157. if (vas != VA_STATUS_SUCCESS) {
  158. av_log(avctx, AV_LOG_ERROR, "Failed to create bitstream "
  159. "output buffer: %d (%s).\n", vas, vaErrorStr(vas));
  160. err = AVERROR(ENOMEM);
  161. goto fail;
  162. }
  163. av_log(avctx, AV_LOG_DEBUG, "Output buffer is %#x.\n",
  164. pic->output_buffer);
  165. if (ctx->codec->picture_params_size > 0) {
  166. pic->codec_picture_params = av_malloc(ctx->codec->picture_params_size);
  167. if (!pic->codec_picture_params)
  168. goto fail;
  169. memcpy(pic->codec_picture_params, ctx->codec_picture_params,
  170. ctx->codec->picture_params_size);
  171. } else {
  172. av_assert0(!ctx->codec_picture_params);
  173. }
  174. pic->nb_param_buffers = 0;
  175. if (pic->type == PICTURE_TYPE_IDR && ctx->codec->init_sequence_params) {
  176. err = vaapi_encode_make_param_buffer(avctx, pic,
  177. VAEncSequenceParameterBufferType,
  178. ctx->codec_sequence_params,
  179. ctx->codec->sequence_params_size);
  180. if (err < 0)
  181. goto fail;
  182. }
  183. if (ctx->codec->init_picture_params) {
  184. err = ctx->codec->init_picture_params(avctx, pic);
  185. if (err < 0) {
  186. av_log(avctx, AV_LOG_ERROR, "Failed to initialise picture "
  187. "parameters: %d.\n", err);
  188. goto fail;
  189. }
  190. err = vaapi_encode_make_param_buffer(avctx, pic,
  191. VAEncPictureParameterBufferType,
  192. pic->codec_picture_params,
  193. ctx->codec->picture_params_size);
  194. if (err < 0)
  195. goto fail;
  196. }
  197. if (pic->type == PICTURE_TYPE_IDR) {
  198. if (ctx->codec->write_sequence_header) {
  199. bit_len = 8 * sizeof(data);
  200. err = ctx->codec->write_sequence_header(avctx, data, &bit_len);
  201. if (err < 0) {
  202. av_log(avctx, AV_LOG_ERROR, "Failed to write per-sequence "
  203. "header: %d.\n", err);
  204. goto fail;
  205. }
  206. err = vaapi_encode_make_packed_header(avctx, pic,
  207. ctx->codec->sequence_header_type,
  208. data, bit_len);
  209. if (err < 0)
  210. goto fail;
  211. }
  212. }
  213. if (ctx->codec->write_picture_header) {
  214. bit_len = 8 * sizeof(data);
  215. err = ctx->codec->write_picture_header(avctx, pic, data, &bit_len);
  216. if (err < 0) {
  217. av_log(avctx, AV_LOG_ERROR, "Failed to write per-picture "
  218. "header: %d.\n", err);
  219. goto fail;
  220. }
  221. err = vaapi_encode_make_packed_header(avctx, pic,
  222. ctx->codec->picture_header_type,
  223. data, bit_len);
  224. if (err < 0)
  225. goto fail;
  226. }
  227. if (ctx->codec->write_extra_buffer) {
  228. for (i = 0;; i++) {
  229. size_t len = sizeof(data);
  230. int type;
  231. err = ctx->codec->write_extra_buffer(avctx, pic, i, &type,
  232. data, &len);
  233. if (err == AVERROR_EOF)
  234. break;
  235. if (err < 0) {
  236. av_log(avctx, AV_LOG_ERROR, "Failed to write extra "
  237. "buffer %d: %d.\n", i, err);
  238. goto fail;
  239. }
  240. err = vaapi_encode_make_param_buffer(avctx, pic, type,
  241. data, len);
  242. if (err < 0)
  243. goto fail;
  244. }
  245. }
  246. av_assert0(pic->nb_slices <= MAX_PICTURE_SLICES);
  247. for (i = 0; i < pic->nb_slices; i++) {
  248. slice = av_mallocz(sizeof(*slice));
  249. if (!slice) {
  250. err = AVERROR(ENOMEM);
  251. goto fail;
  252. }
  253. pic->slices[i] = slice;
  254. if (ctx->codec->slice_params_size > 0) {
  255. slice->codec_slice_params = av_mallocz(ctx->codec->slice_params_size);
  256. if (!slice->codec_slice_params) {
  257. err = AVERROR(ENOMEM);
  258. goto fail;
  259. }
  260. }
  261. if (ctx->codec->init_slice_params) {
  262. err = ctx->codec->init_slice_params(avctx, pic, slice);
  263. if (err < 0) {
  264. av_log(avctx, AV_LOG_ERROR, "Failed to initalise slice "
  265. "parameters: %d.\n", err);
  266. goto fail;
  267. }
  268. }
  269. if (ctx->codec->write_slice_header) {
  270. bit_len = 8 * sizeof(data);
  271. err = ctx->codec->write_slice_header(avctx, pic, slice,
  272. data, &bit_len);
  273. if (err < 0) {
  274. av_log(avctx, AV_LOG_ERROR, "Failed to write per-slice "
  275. "header: %d.\n", err);
  276. goto fail;
  277. }
  278. err = vaapi_encode_make_packed_header(avctx, pic,
  279. ctx->codec->slice_header_type,
  280. data, bit_len);
  281. if (err < 0)
  282. goto fail;
  283. }
  284. if (ctx->codec->init_slice_params) {
  285. err = vaapi_encode_make_param_buffer(avctx, pic,
  286. VAEncSliceParameterBufferType,
  287. slice->codec_slice_params,
  288. ctx->codec->slice_params_size);
  289. if (err < 0)
  290. goto fail;
  291. }
  292. }
  293. vas = vaBeginPicture(ctx->hwctx->display, ctx->va_context,
  294. pic->input_surface);
  295. if (vas != VA_STATUS_SUCCESS) {
  296. av_log(avctx, AV_LOG_ERROR, "Failed to begin picture encode issue: "
  297. "%d (%s).\n", vas, vaErrorStr(vas));
  298. err = AVERROR(EIO);
  299. goto fail_with_picture;
  300. }
  301. vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context,
  302. pic->param_buffers, pic->nb_param_buffers);
  303. if (vas != VA_STATUS_SUCCESS) {
  304. av_log(avctx, AV_LOG_ERROR, "Failed to upload encode parameters: "
  305. "%d (%s).\n", vas, vaErrorStr(vas));
  306. err = AVERROR(EIO);
  307. goto fail_with_picture;
  308. }
  309. vas = vaEndPicture(ctx->hwctx->display, ctx->va_context);
  310. if (vas != VA_STATUS_SUCCESS) {
  311. av_log(avctx, AV_LOG_ERROR, "Failed to end picture encode issue: "
  312. "%d (%s).\n", vas, vaErrorStr(vas));
  313. err = AVERROR(EIO);
  314. goto fail_at_end;
  315. }
  316. pic->encode_issued = 1;
  317. if (ctx->issue_mode == ISSUE_MODE_SERIALISE_EVERYTHING)
  318. return vaapi_encode_wait(avctx, pic);
  319. else
  320. return 0;
  321. fail_with_picture:
  322. vaEndPicture(ctx->hwctx->display, ctx->va_context);
  323. fail:
  324. for(i = 0; i < pic->nb_param_buffers; i++)
  325. vaDestroyBuffer(ctx->hwctx->display, pic->param_buffers[i]);
  326. fail_at_end:
  327. av_freep(&pic->codec_picture_params);
  328. av_frame_free(&pic->recon_image);
  329. return err;
  330. }
  331. static int vaapi_encode_output(AVCodecContext *avctx,
  332. VAAPIEncodePicture *pic, AVPacket *pkt)
  333. {
  334. VAAPIEncodeContext *ctx = avctx->priv_data;
  335. VACodedBufferSegment *buf_list, *buf;
  336. VAStatus vas;
  337. int err;
  338. err = vaapi_encode_wait(avctx, pic);
  339. if (err < 0)
  340. return err;
  341. buf_list = NULL;
  342. vas = vaMapBuffer(ctx->hwctx->display, pic->output_buffer,
  343. (void**)&buf_list);
  344. if (vas != VA_STATUS_SUCCESS) {
  345. av_log(avctx, AV_LOG_ERROR, "Failed to map output buffers: "
  346. "%d (%s).\n", vas, vaErrorStr(vas));
  347. err = AVERROR(EIO);
  348. goto fail;
  349. }
  350. for (buf = buf_list; buf; buf = buf->next) {
  351. av_log(avctx, AV_LOG_DEBUG, "Output buffer: %u bytes "
  352. "(status %08x).\n", buf->size, buf->status);
  353. err = av_new_packet(pkt, buf->size);
  354. if (err < 0)
  355. goto fail;
  356. memcpy(pkt->data, buf->buf, buf->size);
  357. }
  358. if (pic->type == PICTURE_TYPE_IDR)
  359. pkt->flags |= AV_PKT_FLAG_KEY;
  360. pkt->pts = pic->pts;
  361. vas = vaUnmapBuffer(ctx->hwctx->display, pic->output_buffer);
  362. if (vas != VA_STATUS_SUCCESS) {
  363. av_log(avctx, AV_LOG_ERROR, "Failed to unmap output buffers: "
  364. "%d (%s).\n", vas, vaErrorStr(vas));
  365. err = AVERROR(EIO);
  366. goto fail;
  367. }
  368. vaDestroyBuffer(ctx->hwctx->display, pic->output_buffer);
  369. pic->output_buffer = VA_INVALID_ID;
  370. av_log(avctx, AV_LOG_DEBUG, "Output read for pic %"PRId64"/%"PRId64".\n",
  371. pic->display_order, pic->encode_order);
  372. return 0;
  373. fail:
  374. if (pic->output_buffer != VA_INVALID_ID) {
  375. vaUnmapBuffer(ctx->hwctx->display, pic->output_buffer);
  376. vaDestroyBuffer(ctx->hwctx->display, pic->output_buffer);
  377. pic->output_buffer = VA_INVALID_ID;
  378. }
  379. return err;
  380. }
  381. static int vaapi_encode_discard(AVCodecContext *avctx,
  382. VAAPIEncodePicture *pic)
  383. {
  384. VAAPIEncodeContext *ctx = avctx->priv_data;
  385. vaapi_encode_wait(avctx, pic);
  386. if (pic->output_buffer != VA_INVALID_ID) {
  387. av_log(avctx, AV_LOG_DEBUG, "Discard output for pic "
  388. "%"PRId64"/%"PRId64".\n",
  389. pic->display_order, pic->encode_order);
  390. vaDestroyBuffer(ctx->hwctx->display, pic->output_buffer);
  391. pic->output_buffer = VA_INVALID_ID;
  392. }
  393. return 0;
  394. }
  395. static VAAPIEncodePicture *vaapi_encode_alloc(void)
  396. {
  397. VAAPIEncodePicture *pic;
  398. pic = av_mallocz(sizeof(*pic));
  399. if (!pic)
  400. return NULL;
  401. pic->input_surface = VA_INVALID_ID;
  402. pic->recon_surface = VA_INVALID_ID;
  403. pic->output_buffer = VA_INVALID_ID;
  404. return pic;
  405. }
  406. static int vaapi_encode_free(AVCodecContext *avctx,
  407. VAAPIEncodePicture *pic)
  408. {
  409. int i;
  410. if (pic->encode_issued)
  411. vaapi_encode_discard(avctx, pic);
  412. for (i = 0; i < pic->nb_slices; i++) {
  413. av_freep(&pic->slices[i]->priv_data);
  414. av_freep(&pic->slices[i]->codec_slice_params);
  415. av_freep(&pic->slices[i]);
  416. }
  417. av_freep(&pic->codec_picture_params);
  418. av_frame_free(&pic->input_image);
  419. av_frame_free(&pic->recon_image);
  420. // Output buffer should already be destroyed.
  421. av_assert0(pic->output_buffer == VA_INVALID_ID);
  422. av_freep(&pic->priv_data);
  423. av_freep(&pic->codec_picture_params);
  424. av_free(pic);
  425. return 0;
  426. }
  427. static int vaapi_encode_step(AVCodecContext *avctx,
  428. VAAPIEncodePicture *target)
  429. {
  430. VAAPIEncodeContext *ctx = avctx->priv_data;
  431. VAAPIEncodePicture *pic;
  432. int i, err;
  433. if (ctx->issue_mode == ISSUE_MODE_SERIALISE_EVERYTHING ||
  434. ctx->issue_mode == ISSUE_MODE_MINIMISE_LATENCY) {
  435. // These two modes are equivalent, except that we wait for
  436. // immediate completion on each operation if serialised.
  437. if (!target) {
  438. // No target, nothing to do yet.
  439. return 0;
  440. }
  441. if (target->encode_complete) {
  442. // Already done.
  443. return 0;
  444. }
  445. pic = target;
  446. for (i = 0; i < pic->nb_refs; i++) {
  447. if (!pic->refs[i]->encode_complete) {
  448. err = vaapi_encode_step(avctx, pic->refs[i]);
  449. if (err < 0)
  450. return err;
  451. }
  452. }
  453. err = vaapi_encode_issue(avctx, pic);
  454. if (err < 0)
  455. return err;
  456. } else if (ctx->issue_mode == ISSUE_MODE_MAXIMISE_THROUGHPUT) {
  457. int activity;
  458. do {
  459. activity = 0;
  460. for (pic = ctx->pic_start; pic; pic = pic->next) {
  461. if (!pic->input_available || pic->encode_issued)
  462. continue;
  463. for (i = 0; i < pic->nb_refs; i++) {
  464. if (!pic->refs[i]->encode_issued)
  465. break;
  466. }
  467. if (i < pic->nb_refs)
  468. continue;
  469. err = vaapi_encode_issue(avctx, pic);
  470. if (err < 0)
  471. return err;
  472. activity = 1;
  473. }
  474. } while(activity);
  475. if (target) {
  476. av_assert0(target->encode_issued && "broken dependencies?");
  477. }
  478. } else {
  479. av_assert0(0);
  480. }
  481. return 0;
  482. }
  483. static int vaapi_encode_get_next(AVCodecContext *avctx,
  484. VAAPIEncodePicture **pic_out)
  485. {
  486. VAAPIEncodeContext *ctx = avctx->priv_data;
  487. VAAPIEncodePicture *start, *end, *pic;
  488. int i;
  489. for (pic = ctx->pic_start; pic; pic = pic->next) {
  490. if (pic->next)
  491. av_assert0(pic->display_order + 1 == pic->next->display_order);
  492. if (pic->display_order == ctx->input_order) {
  493. *pic_out = pic;
  494. return 0;
  495. }
  496. }
  497. if (ctx->input_order == 0) {
  498. // First frame is always an IDR frame.
  499. av_assert0(!ctx->pic_start && !ctx->pic_end);
  500. pic = vaapi_encode_alloc();
  501. if (!pic)
  502. return AVERROR(ENOMEM);
  503. pic->type = PICTURE_TYPE_IDR;
  504. pic->display_order = 0;
  505. pic->encode_order = 0;
  506. ctx->pic_start = ctx->pic_end = pic;
  507. *pic_out = pic;
  508. return 0;
  509. }
  510. pic = vaapi_encode_alloc();
  511. if (!pic)
  512. return AVERROR(ENOMEM);
  513. if (ctx->p_per_i == 0 || ctx->p_counter == ctx->p_per_i) {
  514. if (ctx->i_per_idr == 0 || ctx->i_counter == ctx->i_per_idr) {
  515. pic->type = PICTURE_TYPE_IDR;
  516. ctx->i_counter = 0;
  517. } else {
  518. pic->type = PICTURE_TYPE_I;
  519. ++ctx->i_counter;
  520. }
  521. ctx->p_counter = 0;
  522. } else {
  523. pic->type = PICTURE_TYPE_P;
  524. pic->refs[0] = ctx->pic_end;
  525. pic->nb_refs = 1;
  526. ++ctx->p_counter;
  527. }
  528. start = end = pic;
  529. if (pic->type != PICTURE_TYPE_IDR) {
  530. // If that was not an IDR frame, add B frames display-before and
  531. // encode-after it.
  532. for (i = 0; i < ctx->b_per_p; i++) {
  533. pic = vaapi_encode_alloc();
  534. if (!pic)
  535. goto fail;
  536. pic->type = PICTURE_TYPE_B;
  537. pic->refs[0] = ctx->pic_end;
  538. pic->refs[1] = end;
  539. pic->nb_refs = 2;
  540. pic->next = start;
  541. pic->display_order = ctx->input_order + ctx->b_per_p - i - 1;
  542. pic->encode_order = pic->display_order + 1;
  543. start = pic;
  544. }
  545. }
  546. for (i = 0, pic = start; pic; i++, pic = pic->next) {
  547. pic->display_order = ctx->input_order + i;
  548. if (end->type == PICTURE_TYPE_IDR)
  549. pic->encode_order = ctx->input_order + i;
  550. else if (pic == end)
  551. pic->encode_order = ctx->input_order;
  552. else
  553. pic->encode_order = ctx->input_order + i + 1;
  554. }
  555. av_assert0(ctx->pic_end);
  556. ctx->pic_end->next = start;
  557. ctx->pic_end = end;
  558. *pic_out = start;
  559. av_log(avctx, AV_LOG_DEBUG, "Pictures:");
  560. for (pic = ctx->pic_start; pic; pic = pic->next) {
  561. av_log(avctx, AV_LOG_DEBUG, " %s (%"PRId64"/%"PRId64")",
  562. picture_type_name[pic->type],
  563. pic->display_order, pic->encode_order);
  564. }
  565. av_log(avctx, AV_LOG_DEBUG, "\n");
  566. return 0;
  567. fail:
  568. while (start) {
  569. pic = start->next;
  570. vaapi_encode_free(avctx, start);
  571. start = pic;
  572. }
  573. return AVERROR(ENOMEM);
  574. }
  575. static int vaapi_encode_mangle_end(AVCodecContext *avctx)
  576. {
  577. VAAPIEncodeContext *ctx = avctx->priv_data;
  578. VAAPIEncodePicture *pic, *last_pic, *next;
  579. // Find the last picture we actually have input for.
  580. for (pic = ctx->pic_start; pic; pic = pic->next) {
  581. if (!pic->input_available)
  582. break;
  583. last_pic = pic;
  584. }
  585. if (pic) {
  586. av_assert0(last_pic);
  587. if (last_pic->type == PICTURE_TYPE_B) {
  588. // Some fixing up is required. Change the type of this
  589. // picture to P, then modify preceeding B references which
  590. // point beyond it to point at it instead.
  591. last_pic->type = PICTURE_TYPE_P;
  592. last_pic->encode_order = last_pic->refs[1]->encode_order;
  593. for (pic = ctx->pic_start; pic != last_pic; pic = pic->next) {
  594. if (pic->type == PICTURE_TYPE_B &&
  595. pic->refs[1] == last_pic->refs[1])
  596. pic->refs[1] = last_pic;
  597. }
  598. last_pic->nb_refs = 1;
  599. last_pic->refs[1] = NULL;
  600. } else {
  601. // We can use the current structure (no references point
  602. // beyond the end), but there are unused pics to discard.
  603. }
  604. // Discard all following pics, they will never be used.
  605. for (pic = last_pic->next; pic; pic = next) {
  606. next = pic->next;
  607. vaapi_encode_free(avctx, pic);
  608. }
  609. last_pic->next = NULL;
  610. ctx->pic_end = last_pic;
  611. } else {
  612. // Input is available for all pictures, so we don't need to
  613. // mangle anything.
  614. }
  615. av_log(avctx, AV_LOG_DEBUG, "Pictures at end of stream:");
  616. for (pic = ctx->pic_start; pic; pic = pic->next) {
  617. av_log(avctx, AV_LOG_DEBUG, " %s (%"PRId64"/%"PRId64")",
  618. picture_type_name[pic->type],
  619. pic->display_order, pic->encode_order);
  620. }
  621. av_log(avctx, AV_LOG_DEBUG, "\n");
  622. return 0;
  623. }
  624. static int vaapi_encode_clear_old(AVCodecContext *avctx)
  625. {
  626. VAAPIEncodeContext *ctx = avctx->priv_data;
  627. VAAPIEncodePicture *pic, *old;
  628. int i;
  629. while (ctx->pic_start != ctx->pic_end) {
  630. old = ctx->pic_start;
  631. if (old->encode_order > ctx->output_order)
  632. break;
  633. for (pic = old->next; pic; pic = pic->next) {
  634. if (pic->encode_complete)
  635. continue;
  636. for (i = 0; i < pic->nb_refs; i++) {
  637. if (pic->refs[i] == old) {
  638. // We still need this picture because it's referred to
  639. // directly by a later one, so it and all following
  640. // pictures have to stay.
  641. return 0;
  642. }
  643. }
  644. }
  645. pic = ctx->pic_start;
  646. ctx->pic_start = pic->next;
  647. vaapi_encode_free(avctx, pic);
  648. }
  649. return 0;
  650. }
  651. int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt,
  652. const AVFrame *input_image, int *got_packet)
  653. {
  654. VAAPIEncodeContext *ctx = avctx->priv_data;
  655. VAAPIEncodePicture *pic;
  656. int err;
  657. if (input_image) {
  658. av_log(avctx, AV_LOG_DEBUG, "Encode frame: %ux%u (%"PRId64").\n",
  659. input_image->width, input_image->height, input_image->pts);
  660. err = vaapi_encode_get_next(avctx, &pic);
  661. if (err) {
  662. av_log(avctx, AV_LOG_ERROR, "Input setup failed: %d.\n", err);
  663. return err;
  664. }
  665. pic->input_image = av_frame_alloc();
  666. if (!pic->input_image) {
  667. err = AVERROR(ENOMEM);
  668. goto fail;
  669. }
  670. err = av_frame_ref(pic->input_image, input_image);
  671. if (err < 0)
  672. goto fail;
  673. pic->input_surface = (VASurfaceID)(uintptr_t)input_image->data[3];
  674. pic->pts = input_image->pts;
  675. if (ctx->input_order == 0)
  676. ctx->first_pts = pic->pts;
  677. if (ctx->input_order == ctx->decode_delay)
  678. ctx->dts_pts_diff = pic->pts - ctx->first_pts;
  679. if (ctx->output_delay > 0)
  680. ctx->ts_ring[ctx->input_order % (3 * ctx->output_delay)] = pic->pts;
  681. pic->input_available = 1;
  682. } else {
  683. if (!ctx->end_of_stream) {
  684. err = vaapi_encode_mangle_end(avctx);
  685. if (err < 0)
  686. goto fail;
  687. ctx->end_of_stream = 1;
  688. }
  689. }
  690. ++ctx->input_order;
  691. ++ctx->output_order;
  692. av_assert0(ctx->output_order + ctx->output_delay + 1 == ctx->input_order);
  693. for (pic = ctx->pic_start; pic; pic = pic->next)
  694. if (pic->encode_order == ctx->output_order)
  695. break;
  696. // pic can be null here if we don't have a specific target in this
  697. // iteration. We might still issue encodes if things can be overlapped,
  698. // even though we don't intend to output anything.
  699. err = vaapi_encode_step(avctx, pic);
  700. if (err < 0) {
  701. av_log(avctx, AV_LOG_ERROR, "Encode failed: %d.\n", err);
  702. goto fail;
  703. }
  704. if (!pic) {
  705. *got_packet = 0;
  706. } else {
  707. err = vaapi_encode_output(avctx, pic, pkt);
  708. if (err < 0) {
  709. av_log(avctx, AV_LOG_ERROR, "Output failed: %d.\n", err);
  710. goto fail;
  711. }
  712. if (ctx->output_delay == 0) {
  713. pkt->dts = pkt->pts;
  714. } else if (ctx->output_order < ctx->decode_delay) {
  715. if (ctx->ts_ring[ctx->output_order] < INT64_MIN + ctx->dts_pts_diff)
  716. pkt->dts = INT64_MIN;
  717. else
  718. pkt->dts = ctx->ts_ring[ctx->output_order] - ctx->dts_pts_diff;
  719. } else {
  720. pkt->dts = ctx->ts_ring[(ctx->output_order - ctx->decode_delay) %
  721. (3 * ctx->output_delay)];
  722. }
  723. *got_packet = 1;
  724. }
  725. err = vaapi_encode_clear_old(avctx);
  726. if (err < 0) {
  727. av_log(avctx, AV_LOG_ERROR, "List clearing failed: %d.\n", err);
  728. goto fail;
  729. }
  730. return 0;
  731. fail:
  732. // Unclear what to clean up on failure. There are probably some things we
  733. // could do usefully clean up here, but for now just leave them for uninit()
  734. // to do instead.
  735. return err;
  736. }
  737. av_cold int ff_vaapi_encode_init(AVCodecContext *avctx,
  738. const VAAPIEncodeType *type)
  739. {
  740. VAAPIEncodeContext *ctx = avctx->priv_data;
  741. AVVAAPIFramesContext *recon_hwctx = NULL;
  742. AVVAAPIHWConfig *hwconfig = NULL;
  743. AVHWFramesConstraints *constraints = NULL;
  744. enum AVPixelFormat recon_format;
  745. VAStatus vas;
  746. int err, i;
  747. if (!avctx->hw_frames_ctx) {
  748. av_log(avctx, AV_LOG_ERROR, "A hardware frames reference is "
  749. "required to associate the encoding device.\n");
  750. return AVERROR(EINVAL);
  751. }
  752. ctx->codec = type;
  753. ctx->priv_data = av_mallocz(type->priv_data_size);
  754. if (!ctx->priv_data) {
  755. err = AVERROR(ENOMEM);
  756. goto fail;
  757. }
  758. ctx->input_frames_ref = av_buffer_ref(avctx->hw_frames_ctx);
  759. if (!ctx->input_frames_ref) {
  760. err = AVERROR(ENOMEM);
  761. goto fail;
  762. }
  763. ctx->input_frames = (AVHWFramesContext*)ctx->input_frames_ref->data;
  764. ctx->device_ref = av_buffer_ref(ctx->input_frames->device_ref);
  765. if (!ctx->device_ref) {
  766. err = AVERROR(ENOMEM);
  767. goto fail;
  768. }
  769. ctx->device = (AVHWDeviceContext*)ctx->device_ref->data;
  770. ctx->hwctx = ctx->device->hwctx;
  771. err = ctx->codec->init(avctx);
  772. if (err < 0)
  773. goto fail;
  774. vas = vaCreateConfig(ctx->hwctx->display,
  775. ctx->va_profile, ctx->va_entrypoint,
  776. ctx->config_attributes, ctx->nb_config_attributes,
  777. &ctx->va_config);
  778. if (vas != VA_STATUS_SUCCESS) {
  779. av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "
  780. "configuration: %d (%s).\n", vas, vaErrorStr(vas));
  781. err = AVERROR(EIO);
  782. goto fail;
  783. }
  784. hwconfig = av_hwdevice_hwconfig_alloc(ctx->device_ref);
  785. if (!hwconfig) {
  786. err = AVERROR(ENOMEM);
  787. goto fail;
  788. }
  789. hwconfig->config_id = ctx->va_config;
  790. constraints = av_hwdevice_get_hwframe_constraints(ctx->device_ref,
  791. hwconfig);
  792. if (!constraints) {
  793. err = AVERROR(ENOMEM);
  794. goto fail;
  795. }
  796. // Probably we can use the input surface format as the surface format
  797. // of the reconstructed frames. If not, we just pick the first (only?)
  798. // format in the valid list and hope that it all works.
  799. recon_format = AV_PIX_FMT_NONE;
  800. if (constraints->valid_sw_formats) {
  801. for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) {
  802. if (ctx->input_frames->sw_format ==
  803. constraints->valid_sw_formats[i]) {
  804. recon_format = ctx->input_frames->sw_format;
  805. break;
  806. }
  807. }
  808. if (recon_format == AV_PIX_FMT_NONE)
  809. recon_format = constraints->valid_sw_formats[i];
  810. } else {
  811. // No idea what to use; copy input format.
  812. recon_format = ctx->input_frames->sw_format;
  813. }
  814. av_log(avctx, AV_LOG_DEBUG, "Using %s as format of "
  815. "reconstructed frames.\n", av_get_pix_fmt_name(recon_format));
  816. if (ctx->aligned_width < constraints->min_width ||
  817. ctx->aligned_height < constraints->min_height ||
  818. ctx->aligned_width > constraints->max_width ||
  819. ctx->aligned_height > constraints->max_height) {
  820. av_log(avctx, AV_LOG_ERROR, "Hardware does not support encoding at "
  821. "size %dx%d (constraints: width %d-%d height %d-%d).\n",
  822. ctx->aligned_width, ctx->aligned_height,
  823. constraints->min_width, constraints->max_width,
  824. constraints->min_height, constraints->max_height);
  825. err = AVERROR(EINVAL);
  826. goto fail;
  827. }
  828. av_freep(&hwconfig);
  829. av_hwframe_constraints_free(&constraints);
  830. ctx->recon_frames_ref = av_hwframe_ctx_alloc(ctx->device_ref);
  831. if (!ctx->recon_frames_ref) {
  832. err = AVERROR(ENOMEM);
  833. goto fail;
  834. }
  835. ctx->recon_frames = (AVHWFramesContext*)ctx->recon_frames_ref->data;
  836. ctx->recon_frames->format = AV_PIX_FMT_VAAPI;
  837. ctx->recon_frames->sw_format = recon_format;
  838. ctx->recon_frames->width = ctx->aligned_width;
  839. ctx->recon_frames->height = ctx->aligned_height;
  840. ctx->recon_frames->initial_pool_size = ctx->nb_recon_frames;
  841. err = av_hwframe_ctx_init(ctx->recon_frames_ref);
  842. if (err < 0) {
  843. av_log(avctx, AV_LOG_ERROR, "Failed to initialise reconstructed "
  844. "frame context: %d.\n", err);
  845. goto fail;
  846. }
  847. recon_hwctx = ctx->recon_frames->hwctx;
  848. vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,
  849. ctx->aligned_width, ctx->aligned_height,
  850. VA_PROGRESSIVE,
  851. recon_hwctx->surface_ids,
  852. recon_hwctx->nb_surfaces,
  853. &ctx->va_context);
  854. if (vas != VA_STATUS_SUCCESS) {
  855. av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "
  856. "context: %d (%s).\n", vas, vaErrorStr(vas));
  857. err = AVERROR(EIO);
  858. goto fail;
  859. }
  860. ctx->input_order = 0;
  861. ctx->output_delay = avctx->max_b_frames;
  862. ctx->decode_delay = 1;
  863. ctx->output_order = - ctx->output_delay - 1;
  864. if (ctx->codec->sequence_params_size > 0) {
  865. ctx->codec_sequence_params =
  866. av_mallocz(ctx->codec->sequence_params_size);
  867. if (!ctx->codec_sequence_params) {
  868. err = AVERROR(ENOMEM);
  869. goto fail;
  870. }
  871. }
  872. if (ctx->codec->picture_params_size > 0) {
  873. ctx->codec_picture_params =
  874. av_mallocz(ctx->codec->picture_params_size);
  875. if (!ctx->codec_picture_params) {
  876. err = AVERROR(ENOMEM);
  877. goto fail;
  878. }
  879. }
  880. if (ctx->codec->init_sequence_params) {
  881. err = ctx->codec->init_sequence_params(avctx);
  882. if (err < 0) {
  883. av_log(avctx, AV_LOG_ERROR, "Codec sequence initialisation "
  884. "failed: %d.\n", err);
  885. goto fail;
  886. }
  887. }
  888. // All I are IDR for now.
  889. ctx->i_per_idr = 0;
  890. ctx->p_per_i = ((avctx->gop_size + avctx->max_b_frames) /
  891. (avctx->max_b_frames + 1));
  892. ctx->b_per_p = avctx->max_b_frames;
  893. // This should be configurable somehow. (Needs testing on a machine
  894. // where it actually overlaps properly, though.)
  895. ctx->issue_mode = ISSUE_MODE_MAXIMISE_THROUGHPUT;
  896. return 0;
  897. fail:
  898. av_freep(&hwconfig);
  899. av_hwframe_constraints_free(&constraints);
  900. ff_vaapi_encode_close(avctx);
  901. return err;
  902. }
  903. av_cold int ff_vaapi_encode_close(AVCodecContext *avctx)
  904. {
  905. VAAPIEncodeContext *ctx = avctx->priv_data;
  906. VAAPIEncodePicture *pic, *next;
  907. for (pic = ctx->pic_start; pic; pic = next) {
  908. next = pic->next;
  909. vaapi_encode_free(avctx, pic);
  910. }
  911. if (ctx->va_context != VA_INVALID_ID)
  912. vaDestroyContext(ctx->hwctx->display, ctx->va_context);
  913. if (ctx->va_config != VA_INVALID_ID)
  914. vaDestroyConfig(ctx->hwctx->display, ctx->va_config);
  915. if (ctx->codec->close)
  916. ctx->codec->close(avctx);
  917. av_freep(&ctx->codec_sequence_params);
  918. av_freep(&ctx->codec_picture_params);
  919. av_buffer_unref(&ctx->recon_frames_ref);
  920. av_buffer_unref(&ctx->input_frames_ref);
  921. av_buffer_unref(&ctx->device_ref);
  922. av_freep(&ctx->priv_data);
  923. return 0;
  924. }