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.

471 lines
16KB

  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 <va/va.h>
  19. #include <va/va_enc_mpeg2.h>
  20. #include "libavutil/avassert.h"
  21. #include "libavutil/common.h"
  22. #include "libavutil/internal.h"
  23. #include "libavutil/opt.h"
  24. #include "libavutil/pixfmt.h"
  25. #include "avcodec.h"
  26. #include "internal.h"
  27. #include "mpegvideo.h"
  28. #include "put_bits.h"
  29. #include "vaapi_encode.h"
  30. typedef struct VAAPIEncodeMPEG2Context {
  31. int mb_width;
  32. int mb_height;
  33. int quant_i;
  34. int quant_p;
  35. int quant_b;
  36. int64_t last_i_frame;
  37. unsigned int bit_rate;
  38. unsigned int vbv_buffer_size;
  39. } VAAPIEncodeMPEG2Context;
  40. #define vseq_var(name) vseq->name, name
  41. #define vseqext_field(name) vseq->sequence_extension.bits.name, name
  42. #define vgop_field(name) vseq->gop_header.bits.name, name
  43. #define vpic_var(name) vpic->name, name
  44. #define vpcext_field(name) vpic->picture_coding_extension.bits.name, name
  45. #define vcomp_field(name) vpic->composite_display.bits.name, name
  46. #define u2(width, value, name) put_bits(&pbc, width, value)
  47. #define u(width, ...) u2(width, __VA_ARGS__)
  48. static int vaapi_encode_mpeg2_write_sequence_header(AVCodecContext *avctx,
  49. char *data, size_t *data_len)
  50. {
  51. VAAPIEncodeContext *ctx = avctx->priv_data;
  52. VAEncSequenceParameterBufferMPEG2 *vseq = ctx->codec_sequence_params;
  53. VAAPIEncodeMPEG2Context *priv = ctx->priv_data;
  54. PutBitContext pbc;
  55. init_put_bits(&pbc, data, 8 * *data_len);
  56. u(32, SEQ_START_CODE, sequence_header_code);
  57. u(12, vseq->picture_width, horizontal_size_value);
  58. u(12, vseq->picture_height, vertical_size_value);
  59. u(4, vseq_var(aspect_ratio_information));
  60. u(4, 8, frame_rate_code);
  61. u(18, priv->bit_rate & 0x3fff, bit_rate_value);
  62. u(1, 1, marker_bit);
  63. u(10, priv->vbv_buffer_size & 0x3ff, vbv_buffer_size_value);
  64. u(1, 0, constrained_parameters_flag);
  65. u(1, 0, load_intra_quantiser_matrix);
  66. // intra_quantiser_matrix[64]
  67. u(1, 0, load_non_intra_quantiser_matrix);
  68. // non_intra_quantiser_matrix[64]
  69. while (put_bits_count(&pbc) % 8)
  70. u(1, 0, zero_bit);
  71. u(32, EXT_START_CODE, extension_start_code);
  72. u(4, 1, extension_start_code_identifier);
  73. u(8, vseqext_field(profile_and_level_indication));
  74. u(1, vseqext_field(progressive_sequence));
  75. u(2, vseqext_field(chroma_format));
  76. u(2, 0, horizontal_size_extension);
  77. u(2, 0, vertical_size_extension);
  78. u(12, priv->bit_rate >> 18, bit_rate_extension);
  79. u(1, 1, marker_bit);
  80. u(8, priv->vbv_buffer_size >> 10, vbv_buffer_size_extension);
  81. u(1, vseqext_field(low_delay));
  82. u(2, vseqext_field(frame_rate_extension_n));
  83. u(2, vseqext_field(frame_rate_extension_d));
  84. while (put_bits_count(&pbc) % 8)
  85. u(1, 0, zero_bit);
  86. u(32, GOP_START_CODE, group_start_code);
  87. u(25, vgop_field(time_code));
  88. u(1, vgop_field(closed_gop));
  89. u(1, vgop_field(broken_link));
  90. while (put_bits_count(&pbc) % 8)
  91. u(1, 0, zero_bit);
  92. *data_len = put_bits_count(&pbc);
  93. flush_put_bits(&pbc);
  94. return 0;
  95. }
  96. static int vaapi_encode_mpeg2_write_picture_header(AVCodecContext *avctx,
  97. VAAPIEncodePicture *pic,
  98. char *data, size_t *data_len)
  99. {
  100. VAEncPictureParameterBufferMPEG2 *vpic = pic->codec_picture_params;
  101. int picture_coding_type;
  102. PutBitContext pbc;
  103. init_put_bits(&pbc, data, 8 * *data_len);
  104. u(32, PICTURE_START_CODE, picture_start_code);
  105. u(10, vpic_var(temporal_reference));
  106. switch (vpic->picture_type) {
  107. case VAEncPictureTypeIntra:
  108. picture_coding_type = AV_PICTURE_TYPE_I;
  109. break;
  110. case VAEncPictureTypePredictive:
  111. picture_coding_type = AV_PICTURE_TYPE_P;
  112. break;
  113. case VAEncPictureTypeBidirectional:
  114. picture_coding_type = AV_PICTURE_TYPE_B;
  115. break;
  116. default:
  117. av_assert0(0 && "invalid picture_coding_type");
  118. }
  119. u(3, picture_coding_type, picture_coding_type);
  120. u(16, 0xffff, vbv_delay);
  121. if (picture_coding_type == 2 || picture_coding_type == 3) {
  122. u(1, 0, full_pel_forward_vector);
  123. u(3, 7, forward_f_code);
  124. }
  125. if (picture_coding_type == 3) {
  126. u(1, 0, full_pel_backward_vector);
  127. u(3, 7, backward_f_code);
  128. }
  129. u(1, 0, extra_bit_picture);
  130. while (put_bits_count(&pbc) % 8)
  131. u(1, 0, zero_bit);
  132. u(32, EXT_START_CODE, extension_start_code);
  133. u(4, 8, extension_start_code_identifier);
  134. u(4, vpic_var(f_code[0][0]));
  135. u(4, vpic_var(f_code[0][1]));
  136. u(4, vpic_var(f_code[1][0]));
  137. u(4, vpic_var(f_code[1][1]));
  138. u(2, vpcext_field(intra_dc_precision));
  139. u(2, vpcext_field(picture_structure));
  140. u(1, vpcext_field(top_field_first));
  141. u(1, vpcext_field(frame_pred_frame_dct));
  142. u(1, vpcext_field(concealment_motion_vectors));
  143. u(1, vpcext_field(q_scale_type));
  144. u(1, vpcext_field(intra_vlc_format));
  145. u(1, vpcext_field(alternate_scan));
  146. u(1, vpcext_field(repeat_first_field));
  147. u(1, 1, chroma_420_type);
  148. u(1, vpcext_field(progressive_frame));
  149. u(1, vpcext_field(composite_display_flag));
  150. if (vpic->picture_coding_extension.bits.composite_display_flag) {
  151. u(1, vcomp_field(v_axis));
  152. u(3, vcomp_field(field_sequence));
  153. u(1, vcomp_field(sub_carrier));
  154. u(7, vcomp_field(burst_amplitude));
  155. u(8, vcomp_field(sub_carrier_phase));
  156. }
  157. while (put_bits_count(&pbc) % 8)
  158. u(1, 0, zero_bit);
  159. *data_len = put_bits_count(&pbc);
  160. flush_put_bits(&pbc);
  161. return 0;
  162. }
  163. static int vaapi_encode_mpeg2_init_sequence_params(AVCodecContext *avctx)
  164. {
  165. VAAPIEncodeContext *ctx = avctx->priv_data;
  166. VAEncSequenceParameterBufferMPEG2 *vseq = ctx->codec_sequence_params;
  167. VAEncPictureParameterBufferMPEG2 *vpic = ctx->codec_picture_params;
  168. VAAPIEncodeMPEG2Context *priv = ctx->priv_data;
  169. vseq->intra_period = avctx->gop_size;
  170. vseq->ip_period = ctx->b_per_p + 1;
  171. vseq->picture_width = avctx->width;
  172. vseq->picture_height = avctx->height;
  173. vseq->bits_per_second = avctx->bit_rate;
  174. if (avctx->framerate.num > 0 && avctx->framerate.den > 0)
  175. vseq->frame_rate = (float)avctx->framerate.num / avctx->framerate.den;
  176. else
  177. vseq->frame_rate = (float)avctx->time_base.num / avctx->time_base.den;
  178. vseq->aspect_ratio_information = 1;
  179. vseq->vbv_buffer_size = avctx->rc_buffer_size / (16 * 1024);
  180. vseq->sequence_extension.bits.profile_and_level_indication =
  181. avctx->profile << 4 | avctx->level;
  182. vseq->sequence_extension.bits.progressive_sequence = 1;
  183. vseq->sequence_extension.bits.chroma_format = 1;
  184. vseq->sequence_extension.bits.low_delay = 0;
  185. vseq->sequence_extension.bits.frame_rate_extension_n = 0;
  186. vseq->sequence_extension.bits.frame_rate_extension_d = 0;
  187. vseq->new_gop_header = 0;
  188. vseq->gop_header.bits.time_code = 0;
  189. vseq->gop_header.bits.closed_gop = 1;
  190. vseq->gop_header.bits.broken_link = 0;
  191. vpic->forward_reference_picture = VA_INVALID_ID;
  192. vpic->backward_reference_picture = VA_INVALID_ID;
  193. vpic->reconstructed_picture = VA_INVALID_ID;
  194. vpic->coded_buf = VA_INVALID_ID;
  195. vpic->temporal_reference = 0;
  196. vpic->f_code[0][0] = 15;
  197. vpic->f_code[0][1] = 15;
  198. vpic->f_code[1][0] = 15;
  199. vpic->f_code[1][1] = 15;
  200. vpic->picture_coding_extension.bits.intra_dc_precision = 0;
  201. vpic->picture_coding_extension.bits.picture_structure = 3;
  202. vpic->picture_coding_extension.bits.top_field_first = 0;
  203. vpic->picture_coding_extension.bits.frame_pred_frame_dct = 1;
  204. vpic->picture_coding_extension.bits.concealment_motion_vectors = 0;
  205. vpic->picture_coding_extension.bits.q_scale_type = 0;
  206. vpic->picture_coding_extension.bits.intra_vlc_format = 0;
  207. vpic->picture_coding_extension.bits.alternate_scan = 0;
  208. vpic->picture_coding_extension.bits.repeat_first_field = 0;
  209. vpic->picture_coding_extension.bits.progressive_frame = 1;
  210. vpic->picture_coding_extension.bits.composite_display_flag = 0;
  211. priv->bit_rate = (avctx->bit_rate + 399) / 400;
  212. priv->vbv_buffer_size = avctx->rc_buffer_size / (16 * 1024);
  213. return 0;
  214. }
  215. static int vaapi_encode_mpeg2_init_picture_params(AVCodecContext *avctx,
  216. VAAPIEncodePicture *pic)
  217. {
  218. VAAPIEncodeContext *ctx = avctx->priv_data;
  219. VAEncPictureParameterBufferMPEG2 *vpic = pic->codec_picture_params;
  220. VAAPIEncodeMPEG2Context *priv = ctx->priv_data;
  221. int fch, fcv;
  222. switch (avctx->level) {
  223. case 4: // High.
  224. case 6: // High 1440.
  225. fch = 9;
  226. fcv = 5;
  227. break;
  228. case 8: // Main.
  229. fch = 8;
  230. fcv = 5;
  231. break;
  232. case 10: // Low.
  233. default:
  234. fch = 7;
  235. fcv = 4;
  236. break;
  237. }
  238. switch (pic->type) {
  239. case PICTURE_TYPE_IDR:
  240. case PICTURE_TYPE_I:
  241. vpic->picture_type = VAEncPictureTypeIntra;
  242. priv->last_i_frame = pic->display_order;
  243. break;
  244. case PICTURE_TYPE_P:
  245. vpic->picture_type = VAEncPictureTypePredictive;
  246. vpic->forward_reference_picture = pic->refs[0]->recon_surface;
  247. vpic->f_code[0][0] = fch;
  248. vpic->f_code[0][1] = fcv;
  249. break;
  250. case PICTURE_TYPE_B:
  251. vpic->picture_type = VAEncPictureTypeBidirectional;
  252. vpic->forward_reference_picture = pic->refs[0]->recon_surface;
  253. vpic->backward_reference_picture = pic->refs[1]->recon_surface;
  254. vpic->f_code[0][0] = fch;
  255. vpic->f_code[0][1] = fcv;
  256. vpic->f_code[1][0] = fch;
  257. vpic->f_code[1][1] = fcv;
  258. break;
  259. default:
  260. av_assert0(0 && "invalid picture type");
  261. }
  262. vpic->reconstructed_picture = pic->recon_surface;
  263. vpic->coded_buf = pic->output_buffer;
  264. vpic->temporal_reference = pic->display_order - priv->last_i_frame;
  265. pic->nb_slices = priv->mb_height;
  266. return 0;
  267. }
  268. static int vaapi_encode_mpeg2_init_slice_params(AVCodecContext *avctx,
  269. VAAPIEncodePicture *pic,
  270. VAAPIEncodeSlice *slice)
  271. {
  272. VAAPIEncodeContext *ctx = avctx->priv_data;
  273. VAEncSliceParameterBufferMPEG2 *vslice = slice->codec_slice_params;
  274. VAAPIEncodeMPEG2Context *priv = ctx->priv_data;
  275. int qp;
  276. vslice->macroblock_address = priv->mb_width * slice->index;
  277. vslice->num_macroblocks = priv->mb_width;
  278. switch (pic->type) {
  279. case PICTURE_TYPE_IDR:
  280. case PICTURE_TYPE_I:
  281. qp = priv->quant_i;
  282. break;
  283. case PICTURE_TYPE_P:
  284. qp = priv->quant_p;
  285. break;
  286. case PICTURE_TYPE_B:
  287. qp = priv->quant_b;
  288. break;
  289. default:
  290. av_assert0(0 && "invalid picture type");
  291. }
  292. vslice->quantiser_scale_code = qp;
  293. vslice->is_intra_slice = (pic->type == PICTURE_TYPE_IDR ||
  294. pic->type == PICTURE_TYPE_I);
  295. return 0;
  296. }
  297. static av_cold int vaapi_encode_mpeg2_configure(AVCodecContext *avctx)
  298. {
  299. VAAPIEncodeContext *ctx = avctx->priv_data;
  300. VAAPIEncodeMPEG2Context *priv = ctx->priv_data;
  301. priv->mb_width = FFALIGN(avctx->width, 16) / 16;
  302. priv->mb_height = FFALIGN(avctx->height, 16) / 16;
  303. if (ctx->va_rc_mode == VA_RC_CQP) {
  304. priv->quant_p = av_clip(avctx->global_quality, 1, 31);
  305. if (avctx->i_quant_factor > 0.0)
  306. priv->quant_i = av_clip((avctx->global_quality *
  307. avctx->i_quant_factor +
  308. avctx->i_quant_offset) + 0.5,
  309. 1, 31);
  310. else
  311. priv->quant_i = priv->quant_p;
  312. if (avctx->b_quant_factor > 0.0)
  313. priv->quant_b = av_clip((avctx->global_quality *
  314. avctx->b_quant_factor +
  315. avctx->b_quant_offset) + 0.5,
  316. 1, 31);
  317. else
  318. priv->quant_b = priv->quant_p;
  319. av_log(avctx, AV_LOG_DEBUG, "Using fixed quantiser "
  320. "%d / %d / %d for I- / P- / B-frames.\n",
  321. priv->quant_i, priv->quant_p, priv->quant_b);
  322. } else {
  323. av_assert0(0 && "Invalid RC mode.");
  324. }
  325. return 0;
  326. }
  327. static const VAAPIEncodeType vaapi_encode_type_mpeg2 = {
  328. .priv_data_size = sizeof(VAAPIEncodeMPEG2Context),
  329. .configure = &vaapi_encode_mpeg2_configure,
  330. .sequence_params_size = sizeof(VAEncSequenceParameterBufferMPEG2),
  331. .init_sequence_params = &vaapi_encode_mpeg2_init_sequence_params,
  332. .picture_params_size = sizeof(VAEncPictureParameterBufferMPEG2),
  333. .init_picture_params = &vaapi_encode_mpeg2_init_picture_params,
  334. .slice_params_size = sizeof(VAEncSliceParameterBufferMPEG2),
  335. .init_slice_params = &vaapi_encode_mpeg2_init_slice_params,
  336. .sequence_header_type = VAEncPackedHeaderSequence,
  337. .write_sequence_header = &vaapi_encode_mpeg2_write_sequence_header,
  338. .picture_header_type = VAEncPackedHeaderPicture,
  339. .write_picture_header = &vaapi_encode_mpeg2_write_picture_header,
  340. };
  341. static av_cold int vaapi_encode_mpeg2_init(AVCodecContext *avctx)
  342. {
  343. VAAPIEncodeContext *ctx = avctx->priv_data;
  344. ctx->codec = &vaapi_encode_type_mpeg2;
  345. switch (avctx->profile) {
  346. case FF_PROFILE_MPEG2_SIMPLE:
  347. ctx->va_profile = VAProfileMPEG2Simple;
  348. break;
  349. case FF_PROFILE_MPEG2_MAIN:
  350. ctx->va_profile = VAProfileMPEG2Main;
  351. break;
  352. default:
  353. av_log(avctx, AV_LOG_ERROR, "Unknown MPEG-2 profile %d.\n",
  354. avctx->profile);
  355. return AVERROR(EINVAL);
  356. }
  357. ctx->va_entrypoint = VAEntrypointEncSlice;
  358. ctx->va_rt_format = VA_RT_FORMAT_YUV420;
  359. ctx->va_rc_mode = VA_RC_CQP;
  360. ctx->va_packed_headers = VA_ENC_PACKED_HEADER_SEQUENCE |
  361. VA_ENC_PACKED_HEADER_PICTURE;
  362. ctx->surface_width = FFALIGN(avctx->width, 16);
  363. ctx->surface_height = FFALIGN(avctx->height, 16);
  364. return ff_vaapi_encode_init(avctx);
  365. }
  366. static const AVCodecDefault vaapi_encode_mpeg2_defaults[] = {
  367. { "profile", "4" },
  368. { "level", "4" },
  369. { "bf", "1" },
  370. { "g", "120" },
  371. { "i_qfactor", "1.0" },
  372. { "i_qoffset", "0.0" },
  373. { "b_qfactor", "1.2" },
  374. { "b_qoffset", "0.0" },
  375. { "global_quality", "10" },
  376. { NULL },
  377. };
  378. AVCodec ff_mpeg2_vaapi_encoder = {
  379. .name = "mpeg2_vaapi",
  380. .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 (VAAPI)"),
  381. .type = AVMEDIA_TYPE_VIDEO,
  382. .id = AV_CODEC_ID_MPEG2VIDEO,
  383. .priv_data_size = sizeof(VAAPIEncodeContext),
  384. .init = &vaapi_encode_mpeg2_init,
  385. .encode2 = &ff_vaapi_encode2,
  386. .close = &ff_vaapi_encode_close,
  387. .capabilities = AV_CODEC_CAP_DELAY,
  388. .defaults = vaapi_encode_mpeg2_defaults,
  389. .pix_fmts = (const enum AVPixelFormat[]) {
  390. AV_PIX_FMT_VAAPI,
  391. AV_PIX_FMT_NONE,
  392. },
  393. };