FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
vaapi_encode_h264.c
Go to the documentation of this file.
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 
19 #include <va/va.h>
20 #include <va/va_enc_h264.h>
21 
22 #include "libavutil/avassert.h"
23 #include "libavutil/internal.h"
24 #include "libavutil/opt.h"
25 #include "libavutil/pixfmt.h"
26 
27 #include "avcodec.h"
28 #include "h264.h"
29 #include "internal.h"
30 #include "vaapi_encode.h"
31 #include "vaapi_encode_h26x.h"
32 
33 enum {
39 };
40 
41 // This structure contains all possibly-useful per-sequence syntax elements
42 // which are not already contained in the various VAAPI structures.
44  unsigned int profile_idc;
51 
54 
58 
60  unsigned int slice_group_map_type;
61 
63 
66 
67 // This structure contains all possibly-useful per-slice syntax elements
68 // which are not already contained in the various VAAPI structures.
70  unsigned int nal_unit_type;
71  unsigned int nal_ref_idc;
72 
73  unsigned int colour_plane_id;
76 
77  unsigned int redundant_pic_cnt;
78 
81 
84 
89 
90 typedef struct VAAPIEncodeH264Slice {
93 
94 typedef struct VAAPIEncodeH264Context {
96 
97  int mb_width;
98  int mb_height;
99 
103 
105  int64_t idr_pic_count;
106 
107  // Rate control configuration.
108  struct {
109  VAEncMiscParameterBuffer misc;
110  VAEncMiscParameterRateControl rc;
111  } rc_params;
112  struct {
113  VAEncMiscParameterBuffer misc;
114  VAEncMiscParameterHRD hrd;
115  } hrd_params;
116 
117 #if VA_CHECK_VERSION(0, 36, 0)
118  // Speed-quality tradeoff setting.
119  struct {
120  VAEncMiscParameterBuffer misc;
121  VAEncMiscParameterBufferQualityLevel quality;
122  } quality_params;
123 #endif
125 
126 typedef struct VAAPIEncodeH264Options {
127  int qp;
128  int quality;
131 
132 
133 #define vseq_var(name) vseq->name, name
134 #define vseq_field(name) vseq->seq_fields.bits.name, name
135 #define vpic_var(name) vpic->name, name
136 #define vpic_field(name) vpic->pic_fields.bits.name, name
137 #define vslice_var(name) vslice->name, name
138 #define vslice_field(name) vslice->slice_fields.bits.name, name
139 #define mseq_var(name) mseq->name, name
140 #define mslice_var(name) mslice->name, name
141 
143  int nal_unit_type, int nal_ref_idc)
144 {
145  u(1, 0, forbidden_zero_bit);
146  u(2, nal_ref_idc, nal_ref_idc);
147  u(5, nal_unit_type, nal_unit_type);
148 }
149 
151 {
152  u(1, 1, rbsp_stop_one_bit);
153  while (put_bits_count(pbc) & 7)
154  u(1, 0, rbsp_alignment_zero_bit);
155 }
156 
159 {
160  VAEncSequenceParameterBufferH264 *vseq = ctx->codec_sequence_params;
161  VAAPIEncodeH264Context *priv = ctx->priv_data;
163  int i;
164 
166 
167  u(8, mseq_var(profile_idc));
168  u(1, mseq_var(constraint_set0_flag));
169  u(1, mseq_var(constraint_set1_flag));
170  u(1, mseq_var(constraint_set2_flag));
171  u(1, mseq_var(constraint_set3_flag));
172  u(1, mseq_var(constraint_set4_flag));
173  u(1, mseq_var(constraint_set5_flag));
174  u(2, 0, reserved_zero_2bits);
175 
176  u(8, vseq_var(level_idc));
177 
178  ue(vseq_var(seq_parameter_set_id));
179 
180  if (mseq->profile_idc == 100 || mseq->profile_idc == 110 ||
181  mseq->profile_idc == 122 || mseq->profile_idc == 244 ||
182  mseq->profile_idc == 44 || mseq->profile_idc == 83 ||
183  mseq->profile_idc == 86 || mseq->profile_idc == 118 ||
184  mseq->profile_idc == 128 || mseq->profile_idc == 138) {
185  ue(vseq_field(chroma_format_idc));
186 
187  if (vseq->seq_fields.bits.chroma_format_idc == 3)
188  u(1, mseq_var(separate_colour_plane_flag));
189 
190  ue(vseq_var(bit_depth_luma_minus8));
191  ue(vseq_var(bit_depth_chroma_minus8));
192 
193  u(1, mseq_var(qpprime_y_zero_transform_bypass_flag));
194 
195  u(1, vseq_field(seq_scaling_matrix_present_flag));
196  if (vseq->seq_fields.bits.seq_scaling_matrix_present_flag) {
197  av_assert0(0 && "scaling matrices not supported");
198  }
199  }
200 
201  ue(vseq_field(log2_max_frame_num_minus4));
202  ue(vseq_field(pic_order_cnt_type));
203 
204  if (vseq->seq_fields.bits.pic_order_cnt_type == 0) {
205  ue(vseq_field(log2_max_pic_order_cnt_lsb_minus4));
206  } else if (vseq->seq_fields.bits.pic_order_cnt_type == 1) {
207  u(1, mseq_var(delta_pic_order_always_zero_flag));
208  se(vseq_var(offset_for_non_ref_pic));
209  se(vseq_var(offset_for_top_to_bottom_field));
210  ue(vseq_var(num_ref_frames_in_pic_order_cnt_cycle));
211 
212  for (i = 0; i < vseq->num_ref_frames_in_pic_order_cnt_cycle; i++)
213  se(vseq_var(offset_for_ref_frame[i]));
214  }
215 
216  ue(vseq_var(max_num_ref_frames));
217  u(1, mseq_var(gaps_in_frame_num_allowed_flag));
218 
219  ue(vseq->picture_width_in_mbs - 1, pic_width_in_mbs_minus1);
220  ue(vseq->picture_height_in_mbs - 1, pic_height_in_mbs_minus1);
221 
222  u(1, vseq_field(frame_mbs_only_flag));
223  if (!vseq->seq_fields.bits.frame_mbs_only_flag)
224  u(1, vseq_field(mb_adaptive_frame_field_flag));
225 
226  u(1, vseq_field(direct_8x8_inference_flag));
227 
228  u(1, vseq_var(frame_cropping_flag));
229  if (vseq->frame_cropping_flag) {
230  ue(vseq_var(frame_crop_left_offset));
231  ue(vseq_var(frame_crop_right_offset));
232  ue(vseq_var(frame_crop_top_offset));
233  ue(vseq_var(frame_crop_bottom_offset));
234  }
235 
236  u(1, mseq_var(vui_parameters_present_flag));
237 
239 }
240 
243 {
244  VAEncPictureParameterBufferH264 *vpic = ctx->codec_picture_params;
245  VAAPIEncodeH264Context *priv = ctx->priv_data;
247 
249 
250  ue(vpic_var(pic_parameter_set_id));
251  ue(vpic_var(seq_parameter_set_id));
252 
253  u(1, vpic_field(entropy_coding_mode_flag));
254  u(1, mseq_var(bottom_field_pic_order_in_frame_present_flag));
255 
256  ue(mseq_var(num_slice_groups_minus1));
257  if (mseq->num_slice_groups_minus1 > 0) {
258  ue(mseq_var(slice_group_map_type));
259  av_assert0(0 && "slice groups not supported");
260  }
261 
262  ue(vpic_var(num_ref_idx_l0_active_minus1));
263  ue(vpic_var(num_ref_idx_l1_active_minus1));
264 
265  u(1, vpic_field(weighted_pred_flag));
266  u(2, vpic_field(weighted_bipred_idc));
267 
268  se(vpic->pic_init_qp - 26, pic_init_qp_minus26);
269  se(mseq_var(pic_init_qs_minus26));
270  se(vpic_var(chroma_qp_index_offset));
271 
272  u(1, vpic_field(deblocking_filter_control_present_flag));
273  u(1, vpic_field(constrained_intra_pred_flag));
274  u(1, vpic_field(redundant_pic_cnt_present_flag));
275  u(1, vpic_field(transform_8x8_mode_flag));
276 
277  u(1, vpic_field(pic_scaling_matrix_present_flag));
278  if (vpic->pic_fields.bits.pic_scaling_matrix_present_flag) {
279  av_assert0(0 && "scaling matrices not supported");
280  }
281 
282  se(vpic_var(second_chroma_qp_index_offset));
283 
285 }
286 
289  VAAPIEncodePicture *pic,
290  VAAPIEncodeSlice *slice)
291 {
292  VAEncSequenceParameterBufferH264 *vseq = ctx->codec_sequence_params;
293  VAEncPictureParameterBufferH264 *vpic = pic->codec_picture_params;
294  VAEncSliceParameterBufferH264 *vslice = slice->codec_slice_params;
295  VAAPIEncodeH264Context *priv = ctx->priv_data;
297  VAAPIEncodeH264Slice *pslice = slice->priv_data;
299 
301  mslice->nal_ref_idc);
302 
303  ue(vslice->macroblock_address, first_mb_in_slice);
304  ue(vslice_var(slice_type));
305  ue(vpic_var(pic_parameter_set_id));
306 
307  if (mseq->separate_colour_plane_flag) {
308  u(2, mslice_var(colour_plane_id));
309  }
310 
311  u(4 + vseq->seq_fields.bits.log2_max_frame_num_minus4,
312  (vpic->frame_num &
313  ((1 << (4 + vseq->seq_fields.bits.log2_max_frame_num_minus4)) - 1)),
314  frame_num);
315 
316  if (!vseq->seq_fields.bits.frame_mbs_only_flag) {
317  u(1, mslice_var(field_pic_flag));
318  if (mslice->field_pic_flag)
319  u(1, mslice_var(bottom_field_flag));
320  }
321 
322  if (vpic->pic_fields.bits.idr_pic_flag) {
323  ue(vslice_var(idr_pic_id));
324  }
325 
326  if (vseq->seq_fields.bits.pic_order_cnt_type == 0) {
327  u(4 + vseq->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4,
328  vslice_var(pic_order_cnt_lsb));
330  !mslice->field_pic_flag) {
331  se(vslice_var(delta_pic_order_cnt_bottom));
332  }
333  }
334 
335  if (vseq->seq_fields.bits.pic_order_cnt_type == 1 &&
336  !vseq->seq_fields.bits.delta_pic_order_always_zero_flag) {
337  se(vslice_var(delta_pic_order_cnt[0]));
339  !mslice->field_pic_flag) {
340  se(vslice_var(delta_pic_order_cnt[1]));
341  }
342  }
343 
344  if (vpic->pic_fields.bits.redundant_pic_cnt_present_flag) {
345  ue(mslice_var(redundant_pic_cnt));
346  }
347 
348  if (vslice->slice_type == SLICE_TYPE_B) {
349  u(1, vslice_var(direct_spatial_mv_pred_flag));
350  }
351 
352  if (vslice->slice_type == SLICE_TYPE_P ||
353  vslice->slice_type == SLICE_TYPE_SP ||
354  vslice->slice_type == SLICE_TYPE_B) {
355  u(1, vslice_var(num_ref_idx_active_override_flag));
356  if (vslice->num_ref_idx_active_override_flag) {
357  ue(vslice_var(num_ref_idx_l0_active_minus1));
358  if (vslice->slice_type == SLICE_TYPE_B)
359  ue(vslice_var(num_ref_idx_l1_active_minus1));
360  }
361  }
362 
363  if (mslice->nal_unit_type == 20 || mslice->nal_unit_type == 21) {
364  av_assert0(0 && "no MVC support");
365  } else {
366  if (vslice->slice_type % 5 != 2 && vslice->slice_type % 5 != 4) {
367  u(1, mslice_var(ref_pic_list_modification_flag_l0));
368  if (mslice->ref_pic_list_modification_flag_l0) {
369  av_assert0(0 && "ref pic list modification");
370  }
371  }
372  if (vslice->slice_type % 5 == 1) {
373  u(1, mslice_var(ref_pic_list_modification_flag_l1));
374  if (mslice->ref_pic_list_modification_flag_l1) {
375  av_assert0(0 && "ref pic list modification");
376  }
377  }
378  }
379 
380  if ((vpic->pic_fields.bits.weighted_pred_flag &&
381  (vslice->slice_type == SLICE_TYPE_P ||
382  vslice->slice_type == SLICE_TYPE_SP)) ||
383  (vpic->pic_fields.bits.weighted_bipred_idc == 1 &&
384  vslice->slice_type == SLICE_TYPE_B)) {
385  av_assert0(0 && "prediction weights not supported");
386  }
387 
388  av_assert0(mslice->nal_ref_idc > 0 ==
389  vpic->pic_fields.bits.reference_pic_flag);
390  if (mslice->nal_ref_idc != 0) {
391  if (vpic->pic_fields.bits.idr_pic_flag) {
392  u(1, mslice_var(no_output_of_prior_pics_flag));
393  u(1, mslice_var(long_term_reference_flag));
394  } else {
395  u(1, mslice_var(adaptive_ref_pic_marking_mode_flag));
397  av_assert0(0 && "MMCOs not supported");
398  }
399  }
400  }
401 
402  if (vpic->pic_fields.bits.entropy_coding_mode_flag &&
403  vslice->slice_type != SLICE_TYPE_I &&
404  vslice->slice_type != SLICE_TYPE_SI) {
405  ue(vslice_var(cabac_init_idc));
406  }
407 
408  se(vslice_var(slice_qp_delta));
409  if (vslice->slice_type == SLICE_TYPE_SP ||
410  vslice->slice_type == SLICE_TYPE_SI) {
411  if (vslice->slice_type == SLICE_TYPE_SP)
412  u(1, mslice_var(sp_for_switch_flag));
413  se(mslice_var(slice_qs_delta));
414  }
415 
416  if (vpic->pic_fields.bits.deblocking_filter_control_present_flag) {
417  ue(vslice_var(disable_deblocking_filter_idc));
418  if (vslice->disable_deblocking_filter_idc != 1) {
419  se(vslice_var(slice_alpha_c0_offset_div2));
420  se(vslice_var(slice_beta_offset_div2));
421  }
422  }
423 
424  if (mseq->num_slice_groups_minus1 > 0 &&
425  mseq->slice_group_map_type >= 3 && mseq->slice_group_map_type <= 5) {
426  av_assert0(0 && "slice groups not supported");
427  }
428 
429  // No alignment - this need not be a byte boundary.
430 }
431 
433  char *data, size_t *data_len)
434 {
435  VAAPIEncodeContext *ctx = avctx->priv_data;
436  PutBitContext pbc;
437  char tmp[256];
438  int err;
439  size_t nal_len, bit_len, bit_pos, next_len;
440 
441  bit_len = *data_len;
442  bit_pos = 0;
443 
444  init_put_bits(&pbc, tmp, sizeof(tmp));
445  vaapi_encode_h264_write_sps(&pbc, ctx);
446  nal_len = put_bits_count(&pbc);
447  flush_put_bits(&pbc);
448 
449  next_len = bit_len - bit_pos;
450  err = ff_vaapi_encode_h26x_nal_unit_to_byte_stream(data + bit_pos / 8,
451  &next_len,
452  tmp, nal_len);
453  if (err < 0)
454  return err;
455  bit_pos += next_len;
456 
457  init_put_bits(&pbc, tmp, sizeof(tmp));
458  vaapi_encode_h264_write_pps(&pbc, ctx);
459  nal_len = put_bits_count(&pbc);
460  flush_put_bits(&pbc);
461 
462  next_len = bit_len - bit_pos;
463  err = ff_vaapi_encode_h26x_nal_unit_to_byte_stream(data + bit_pos / 8,
464  &next_len,
465  tmp, nal_len);
466  if (err < 0)
467  return err;
468  bit_pos += next_len;
469 
470  *data_len = bit_pos;
471  return 0;
472 }
473 
475  VAAPIEncodePicture *pic,
476  VAAPIEncodeSlice *slice,
477  char *data, size_t *data_len)
478 {
479  VAAPIEncodeContext *ctx = avctx->priv_data;
480  PutBitContext pbc;
481  char tmp[256];
482  size_t header_len;
483 
484  init_put_bits(&pbc, tmp, sizeof(tmp));
485  vaapi_encode_h264_write_slice_header2(&pbc, ctx, pic, slice);
486  header_len = put_bits_count(&pbc);
487  flush_put_bits(&pbc);
488 
489  return ff_vaapi_encode_h26x_nal_unit_to_byte_stream(data, data_len,
490  tmp, header_len);
491 }
492 
494 {
495  VAAPIEncodeContext *ctx = avctx->priv_data;
496  VAEncSequenceParameterBufferH264 *vseq = ctx->codec_sequence_params;
497  VAEncPictureParameterBufferH264 *vpic = ctx->codec_picture_params;
498  VAAPIEncodeH264Context *priv = ctx->priv_data;
500  int i;
501 
502  {
503  vseq->seq_parameter_set_id = 0;
504 
505  vseq->level_idc = avctx->level;
506 
507  vseq->max_num_ref_frames = 2;
508 
509  vseq->picture_width_in_mbs = priv->mb_width;
510  vseq->picture_height_in_mbs = priv->mb_height;
511 
512  vseq->seq_fields.bits.chroma_format_idc = 1;
513  vseq->seq_fields.bits.frame_mbs_only_flag = 1;
514  vseq->seq_fields.bits.direct_8x8_inference_flag = 1;
515  vseq->seq_fields.bits.log2_max_frame_num_minus4 = 4;
516  vseq->seq_fields.bits.pic_order_cnt_type = 0;
517 
518  if (ctx->input_width != ctx->aligned_width ||
519  ctx->input_height != ctx->aligned_height) {
520  vseq->frame_cropping_flag = 1;
521 
522  vseq->frame_crop_left_offset = 0;
523  vseq->frame_crop_right_offset =
524  (ctx->aligned_width - ctx->input_width) / 2;
525  vseq->frame_crop_top_offset = 0;
526  vseq->frame_crop_bottom_offset =
527  (ctx->aligned_height - ctx->input_height) / 2;
528  } else {
529  vseq->frame_cropping_flag = 0;
530  }
531 
532  vseq->bits_per_second = avctx->bit_rate;
533  if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
534  vseq->num_units_in_tick = avctx->framerate.num;
535  vseq->time_scale = 2 * avctx->framerate.den;
536  } else {
537  vseq->num_units_in_tick = avctx->time_base.num;
538  vseq->time_scale = 2 * avctx->time_base.den;
539  }
540 
541  vseq->intra_period = ctx->p_per_i * (ctx->b_per_p + 1);
542  vseq->intra_idr_period = vseq->intra_period;
543  vseq->ip_period = ctx->b_per_p + 1;
544  }
545 
546  {
547  vpic->CurrPic.picture_id = VA_INVALID_ID;
548  vpic->CurrPic.flags = VA_PICTURE_H264_INVALID;
549 
550  for (i = 0; i < FF_ARRAY_ELEMS(vpic->ReferenceFrames); i++) {
551  vpic->ReferenceFrames[i].picture_id = VA_INVALID_ID;
552  vpic->ReferenceFrames[i].flags = VA_PICTURE_H264_INVALID;
553  }
554 
555  vpic->coded_buf = VA_INVALID_ID;
556 
557  vpic->pic_parameter_set_id = 0;
558  vpic->seq_parameter_set_id = 0;
559 
560  vpic->num_ref_idx_l0_active_minus1 = 0;
561  vpic->num_ref_idx_l1_active_minus1 = 0;
562 
563  vpic->pic_fields.bits.entropy_coding_mode_flag =
564  ((avctx->profile & 0xff) != 66);
565  vpic->pic_fields.bits.weighted_pred_flag = 0;
566  vpic->pic_fields.bits.weighted_bipred_idc = 0;
567  vpic->pic_fields.bits.transform_8x8_mode_flag =
568  ((avctx->profile & 0xff) >= 100);
569 
570  vpic->pic_init_qp = priv->fixed_qp_idr;
571  }
572 
573  {
574  mseq->profile_idc = avctx->profile & 0xff;
575 
577  mseq->constraint_set1_flag = 1;
578  if (avctx->profile & FF_PROFILE_H264_INTRA)
579  mseq->constraint_set3_flag = 1;
580  }
581 
582  return 0;
583 }
584 
586  VAAPIEncodePicture *pic)
587 {
588  VAAPIEncodeContext *ctx = avctx->priv_data;
589  VAEncSequenceParameterBufferH264 *vseq = ctx->codec_sequence_params;
590  VAEncPictureParameterBufferH264 *vpic = pic->codec_picture_params;
591  VAAPIEncodeH264Context *priv = ctx->priv_data;
592  int i;
593 
594  if (pic->type == PICTURE_TYPE_IDR) {
595  av_assert0(pic->display_order == pic->encode_order);
596  vpic->frame_num = 0;
597  priv->next_frame_num = 1;
598  } else {
599  vpic->frame_num = priv->next_frame_num;
600  if (pic->type != PICTURE_TYPE_B) {
601  // nal_ref_idc != 0
602  ++priv->next_frame_num;
603  }
604  }
605 
606  vpic->frame_num = vpic->frame_num &
607  ((1 << (4 + vseq->seq_fields.bits.log2_max_frame_num_minus4)) - 1);
608 
609  vpic->CurrPic.picture_id = pic->recon_surface;
610  vpic->CurrPic.frame_idx = vpic->frame_num;
611  vpic->CurrPic.flags = 0;
612  vpic->CurrPic.TopFieldOrderCnt = pic->display_order;
613  vpic->CurrPic.BottomFieldOrderCnt = pic->display_order;
614 
615  for (i = 0; i < pic->nb_refs; i++) {
616  VAAPIEncodePicture *ref = pic->refs[i];
617  av_assert0(ref && ref->encode_order < pic->encode_order);
618  vpic->ReferenceFrames[i].picture_id = ref->recon_surface;
619  vpic->ReferenceFrames[i].frame_idx = ref->encode_order;
620  vpic->ReferenceFrames[i].flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE;
621  vpic->ReferenceFrames[i].TopFieldOrderCnt = ref->display_order;
622  vpic->ReferenceFrames[i].BottomFieldOrderCnt = ref->display_order;
623  }
624  for (; i < FF_ARRAY_ELEMS(vpic->ReferenceFrames); i++) {
625  vpic->ReferenceFrames[i].picture_id = VA_INVALID_ID;
626  vpic->ReferenceFrames[i].flags = VA_PICTURE_H264_INVALID;
627  }
628 
629  vpic->coded_buf = pic->output_buffer;
630 
631  vpic->pic_fields.bits.idr_pic_flag = (pic->type == PICTURE_TYPE_IDR);
632  vpic->pic_fields.bits.reference_pic_flag = (pic->type != PICTURE_TYPE_B);
633 
634  pic->nb_slices = 1;
635 
636  return 0;
637 }
638 
640  VAAPIEncodePicture *pic,
641  VAAPIEncodeSlice *slice)
642 {
643  VAAPIEncodeContext *ctx = avctx->priv_data;
644  VAEncSequenceParameterBufferH264 *vseq = ctx->codec_sequence_params;
645  VAEncPictureParameterBufferH264 *vpic = pic->codec_picture_params;
646  VAEncSliceParameterBufferH264 *vslice = slice->codec_slice_params;
647  VAAPIEncodeH264Context *priv = ctx->priv_data;
648  VAAPIEncodeH264Slice *pslice;
650  int i;
651 
652  slice->priv_data = av_mallocz(sizeof(*pslice));
653  if (!slice->priv_data)
654  return AVERROR(ENOMEM);
655  pslice = slice->priv_data;
656  mslice = &pslice->misc_slice_params;
657 
658  if (pic->type == PICTURE_TYPE_IDR)
659  mslice->nal_unit_type = NAL_IDR_SLICE;
660  else
661  mslice->nal_unit_type = NAL_SLICE;
662 
663  switch (pic->type) {
664  case PICTURE_TYPE_IDR:
665  vslice->slice_type = SLICE_TYPE_I;
666  mslice->nal_ref_idc = 3;
667  break;
668  case PICTURE_TYPE_I:
669  vslice->slice_type = SLICE_TYPE_I;
670  mslice->nal_ref_idc = 2;
671  break;
672  case PICTURE_TYPE_P:
673  vslice->slice_type = SLICE_TYPE_P;
674  mslice->nal_ref_idc = 1;
675  break;
676  case PICTURE_TYPE_B:
677  vslice->slice_type = SLICE_TYPE_B;
678  mslice->nal_ref_idc = 0;
679  break;
680  default:
681  av_assert0(0 && "invalid picture type");
682  }
683 
684  // Only one slice per frame.
685  vslice->macroblock_address = 0;
686  vslice->num_macroblocks = priv->mb_width * priv->mb_height;
687 
688  vslice->macroblock_info = VA_INVALID_ID;
689 
690  vslice->pic_parameter_set_id = vpic->pic_parameter_set_id;
691  vslice->idr_pic_id = priv->idr_pic_count++;
692 
693  vslice->pic_order_cnt_lsb = pic->display_order &
694  ((1 << (4 + vseq->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4)) - 1);
695 
696  for (i = 0; i < FF_ARRAY_ELEMS(vslice->RefPicList0); i++) {
697  vslice->RefPicList0[i].picture_id = VA_INVALID_ID;
698  vslice->RefPicList0[i].flags = VA_PICTURE_H264_INVALID;
699  vslice->RefPicList1[i].picture_id = VA_INVALID_ID;
700  vslice->RefPicList1[i].flags = VA_PICTURE_H264_INVALID;
701  }
702 
703  av_assert0(pic->nb_refs <= 2);
704  if (pic->nb_refs >= 1) {
705  // Backward reference for P- or B-frame.
706  av_assert0(pic->type == PICTURE_TYPE_P ||
707  pic->type == PICTURE_TYPE_B);
708 
709  vslice->num_ref_idx_l0_active_minus1 = 0;
710  vslice->RefPicList0[0] = vpic->ReferenceFrames[0];
711  }
712  if (pic->nb_refs >= 2) {
713  // Forward reference for B-frame.
714  av_assert0(pic->type == PICTURE_TYPE_B);
715 
716  vslice->num_ref_idx_l1_active_minus1 = 0;
717  vslice->RefPicList1[0] = vpic->ReferenceFrames[1];
718  }
719 
720  if (pic->type == PICTURE_TYPE_B)
721  vslice->slice_qp_delta = priv->fixed_qp_b - vpic->pic_init_qp;
722  else if (pic->type == PICTURE_TYPE_P)
723  vslice->slice_qp_delta = priv->fixed_qp_p - vpic->pic_init_qp;
724  else
725  vslice->slice_qp_delta = priv->fixed_qp_idr - vpic->pic_init_qp;
726 
727  vslice->direct_spatial_mv_pred_flag = 1;
728 
729  return 0;
730 }
731 
733 {
734  VAAPIEncodeContext *ctx = avctx->priv_data;
735  VAAPIEncodeH264Context *priv = ctx->priv_data;
736  int hrd_buffer_size;
737  int hrd_initial_buffer_fullness;
738 
739  if (avctx->bit_rate > INT32_MAX) {
740  av_log(avctx, AV_LOG_ERROR, "Target bitrate of 2^31 bps or "
741  "higher is not supported.\n");
742  return AVERROR(EINVAL);
743  }
744 
745  if (avctx->rc_buffer_size)
746  hrd_buffer_size = avctx->rc_buffer_size;
747  else
748  hrd_buffer_size = avctx->bit_rate;
749  if (avctx->rc_initial_buffer_occupancy)
750  hrd_initial_buffer_fullness = avctx->rc_initial_buffer_occupancy;
751  else
752  hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4;
753 
754  priv->rc_params.misc.type = VAEncMiscParameterTypeRateControl;
755  priv->rc_params.rc = (VAEncMiscParameterRateControl) {
756  .bits_per_second = avctx->bit_rate,
757  .target_percentage = 66,
758  .window_size = 1000,
759  .initial_qp = (avctx->qmax >= 0 ? avctx->qmax : 40),
760  .min_qp = (avctx->qmin >= 0 ? avctx->qmin : 18),
761  .basic_unit_size = 0,
762  };
763  ctx->global_params[ctx->nb_global_params] =
764  &priv->rc_params.misc;
765  ctx->global_params_size[ctx->nb_global_params++] =
766  sizeof(priv->rc_params);
767 
768  priv->hrd_params.misc.type = VAEncMiscParameterTypeHRD;
769  priv->hrd_params.hrd = (VAEncMiscParameterHRD) {
770  .initial_buffer_fullness = hrd_initial_buffer_fullness,
771  .buffer_size = hrd_buffer_size,
772  };
773  ctx->global_params[ctx->nb_global_params] =
774  &priv->hrd_params.misc;
775  ctx->global_params_size[ctx->nb_global_params++] =
776  sizeof(priv->hrd_params);
777 
778  // These still need to be set for pic_init_qp/slice_qp_delta.
779  priv->fixed_qp_idr = 26;
780  priv->fixed_qp_p = 26;
781  priv->fixed_qp_b = 26;
782 
783  av_log(avctx, AV_LOG_DEBUG, "Using constant-bitrate = %"PRId64" bps.\n",
784  avctx->bit_rate);
785  return 0;
786 }
787 
789 {
790  VAAPIEncodeContext *ctx = avctx->priv_data;
791  VAAPIEncodeH264Context *priv = ctx->priv_data;
793 
794  priv->fixed_qp_p = opt->qp;
795  if (avctx->i_quant_factor > 0.0)
796  priv->fixed_qp_idr = (int)((priv->fixed_qp_p * avctx->i_quant_factor +
797  avctx->i_quant_offset) + 0.5);
798  else
799  priv->fixed_qp_idr = priv->fixed_qp_p;
800  if (avctx->b_quant_factor > 0.0)
801  priv->fixed_qp_b = (int)((priv->fixed_qp_p * avctx->b_quant_factor +
802  avctx->b_quant_offset) + 0.5);
803  else
804  priv->fixed_qp_b = priv->fixed_qp_p;
805 
806  av_log(avctx, AV_LOG_DEBUG, "Using fixed QP = "
807  "%d / %d / %d for IDR- / P- / B-frames.\n",
808  priv->fixed_qp_idr, priv->fixed_qp_p, priv->fixed_qp_b);
809  return 0;
810 }
811 
813 {
814  static const VAConfigAttrib default_config_attributes[] = {
815  { .type = VAConfigAttribRTFormat,
816  .value = VA_RT_FORMAT_YUV420 },
817  { .type = VAConfigAttribEncPackedHeaders,
818  .value = (VA_ENC_PACKED_HEADER_SEQUENCE |
819  VA_ENC_PACKED_HEADER_SLICE) },
820  };
821 
822  VAAPIEncodeContext *ctx = avctx->priv_data;
823  VAAPIEncodeH264Context *priv = ctx->priv_data;
825  int i, err;
826 
827  switch (avctx->profile) {
829  ctx->va_profile = VAProfileH264ConstrainedBaseline;
830  break;
832  ctx->va_profile = VAProfileH264Baseline;
833  break;
835  ctx->va_profile = VAProfileH264Main;
836  break;
838  av_log(avctx, AV_LOG_ERROR, "H.264 extended profile "
839  "is not supported.\n");
840  return AVERROR_PATCHWELCOME;
841  case FF_PROFILE_UNKNOWN:
843  ctx->va_profile = VAProfileH264High;
844  break;
847  av_log(avctx, AV_LOG_ERROR, "H.264 10-bit profiles "
848  "are not supported.\n");
849  return AVERROR_PATCHWELCOME;
856  av_log(avctx, AV_LOG_ERROR, "H.264 non-4:2:0 profiles "
857  "are not supported.\n");
858  return AVERROR_PATCHWELCOME;
859  default:
860  av_log(avctx, AV_LOG_ERROR, "Unknown H.264 profile %d.\n",
861  avctx->profile);
862  return AVERROR(EINVAL);
863  }
864  if (opt->low_power) {
865 #if VA_CHECK_VERSION(0, 39, 1)
866  ctx->va_entrypoint = VAEntrypointEncSliceLP;
867 #else
868  av_log(avctx, AV_LOG_ERROR, "Low-power encoding is not "
869  "supported with this VAAPI version.\n");
870  return AVERROR(EINVAL);
871 #endif
872  } else {
873  ctx->va_entrypoint = VAEntrypointEncSlice;
874  }
875 
876  ctx->input_width = avctx->width;
877  ctx->input_height = avctx->height;
878  ctx->aligned_width = FFALIGN(ctx->input_width, 16);
879  ctx->aligned_height = FFALIGN(ctx->input_height, 16);
880  priv->mb_width = ctx->aligned_width / 16;
881  priv->mb_height = ctx->aligned_height / 16;
882 
883  for (i = 0; i < FF_ARRAY_ELEMS(default_config_attributes); i++) {
885  default_config_attributes[i];
886  }
887 
888  if (avctx->bit_rate > 0) {
889  ctx->va_rc_mode = VA_RC_CBR;
891  } else {
892  ctx->va_rc_mode = VA_RC_CQP;
893  err = vaapi_encode_h264_init_fixed_qp(avctx);
894  }
895  if (err < 0)
896  return err;
897 
898  ctx->config_attributes[ctx->nb_config_attributes++] = (VAConfigAttrib) {
899  .type = VAConfigAttribRateControl,
900  .value = ctx->va_rc_mode,
901  };
902 
903  if (opt->quality > 0) {
904 #if VA_CHECK_VERSION(0, 36, 0)
905  priv->quality_params.misc.type =
906  VAEncMiscParameterTypeQualityLevel;
907  priv->quality_params.quality.quality_level = opt->quality;
908 
909  ctx->global_params[ctx->nb_global_params] =
910  &priv->quality_params.misc;
911  ctx->global_params_size[ctx->nb_global_params++] =
912  sizeof(priv->quality_params);
913 #else
914  av_log(avctx, AV_LOG_WARNING, "The encode quality option is not "
915  "supported with this VAAPI version.\n");
916 #endif
917  }
918 
919  ctx->nb_recon_frames = 20;
920 
921  return 0;
922 }
923 
926 
928 
929  .sequence_params_size = sizeof(VAEncSequenceParameterBufferH264),
930  .init_sequence_params = &vaapi_encode_h264_init_sequence_params,
931 
932  .picture_params_size = sizeof(VAEncPictureParameterBufferH264),
933  .init_picture_params = &vaapi_encode_h264_init_picture_params,
934 
935  .slice_params_size = sizeof(VAEncSliceParameterBufferH264),
936  .init_slice_params = &vaapi_encode_h264_init_slice_params,
937 
938  .sequence_header_type = VAEncPackedHeaderSequence,
939  .write_sequence_header = &vaapi_encode_h264_write_sequence_header,
940 
941  .slice_header_type = VAEncPackedHeaderH264_Slice,
942  .write_slice_header = &vaapi_encode_h264_write_slice_header,
943 };
944 
946 {
947  return ff_vaapi_encode_init(avctx, &vaapi_encode_type_h264);
948 }
949 
950 #define OFFSET(x) (offsetof(VAAPIEncodeContext, codec_options_data) + \
951  offsetof(VAAPIEncodeH264Options, x))
952 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
954  { "qp", "Constant QP (for P-frames; scaled by qfactor/qoffset for I/B)",
955  OFFSET(qp), AV_OPT_TYPE_INT, { .i64 = 20 }, 0, 52, FLAGS },
956  { "quality", "Set encode quality (trades off against speed, higher is faster)",
957  OFFSET(quality), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 8, FLAGS },
958  { "low_power", "Use low-power encoding mode (experimental: only supported "
959  "on some platforms, does not support all features)",
960  OFFSET(low_power), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS },
961  { NULL },
962 };
963 
965  { "profile", "100" },
966  { "level", "51" },
967  { "b", "0" },
968  { "bf", "2" },
969  { "g", "120" },
970  { "i_qfactor", "1.0" },
971  { "i_qoffset", "0.0" },
972  { "b_qfactor", "1.2" },
973  { "b_qoffset", "0.0" },
974  { NULL },
975 };
976 
978  .class_name = "h264_vaapi",
979  .item_name = av_default_item_name,
980  .option = vaapi_encode_h264_options,
981  .version = LIBAVUTIL_VERSION_INT,
982 };
983 
985  .name = "h264_vaapi",
986  .long_name = NULL_IF_CONFIG_SMALL("H.264/AVC (VAAPI)"),
987  .type = AVMEDIA_TYPE_VIDEO,
988  .id = AV_CODEC_ID_H264,
989  .priv_data_size = (sizeof(VAAPIEncodeContext) +
990  sizeof(VAAPIEncodeH264Options)),
992  .encode2 = &ff_vaapi_encode2,
993  .close = &ff_vaapi_encode_close,
994  .priv_class = &vaapi_encode_h264_class,
995  .capabilities = AV_CODEC_CAP_DELAY,
996  .defaults = vaapi_encode_h264_defaults,
997  .pix_fmts = (const enum AVPixelFormat[]) {
1000  },
1001 };
#define vpic_field(name)
#define FF_PROFILE_H264_MAIN
Definition: avcodec.h:3187
#define NULL
Definition: coverity.c:32
AVRational framerate
Definition: avcodec.h:3338
#define FF_PROFILE_H264_CAVLC_444
Definition: avcodec.h:3197
VAProfile va_profile
Definition: vaapi_encode.h:108
VAEntrypoint va_entrypoint
Definition: vaapi_encode.h:109
AVOption.
Definition: opt.h:245
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:101
static void vaapi_encode_h264_write_slice_header2(PutBitContext *pbc, VAAPIEncodeContext *ctx, VAAPIEncodePicture *pic, VAAPIEncodeSlice *slice)
Definition: h264.h:123
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
int64_t bit_rate
the average bitrate
Definition: avcodec.h:1714
#define LIBAVUTIL_VERSION_INT
Definition: version.h:70
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
int rc_initial_buffer_occupancy
Number of bits which should be loaded into the rc buffer before decoding starts.
Definition: avcodec.h:2687
av_cold int ff_vaapi_encode_close(AVCodecContext *avctx)
#define FF_PROFILE_H264_INTRA
Definition: avcodec.h:3183
int num
numerator
Definition: rational.h:44
size_t priv_data_size
Definition: vaapi_encode.h:184
void * codec_sequence_params
Definition: vaapi_encode.h:141
#define FLAGS
#define OFFSET(x)
VAEncMiscParameterHRD hrd
VAEncMiscParameterBuffer misc
int profile
profile
Definition: avcodec.h:3153
AVCodec.
Definition: avcodec.h:3542
float i_quant_offset
qscale offset between P and I-frames
Definition: avcodec.h:1993
static const AVClass vaapi_encode_h264_class
#define FF_PROFILE_H264_HIGH_444_PREDICTIVE
Definition: avcodec.h:3195
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avcodec.h:1786
static void vaapi_encode_h264_write_nal_header(PutBitContext *pbc, int nal_unit_type, int nal_ref_idc)
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
#define AV_CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
Definition: avcodec.h:981
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
static VAAPIEncodeType vaapi_encode_type_h264
static const AVOption vaapi_encode_h264_options[]
#define FF_PROFILE_H264_BASELINE
Definition: avcodec.h:3185
#define av_cold
Definition: attributes.h:82
AVOptions.
static const AVCodecDefault vaapi_encode_h264_defaults[]
float b_quant_factor
qscale factor between IP and B-frames If > 0 then the last P-frame quantizer will be used (q= lastp_q...
Definition: avcodec.h:1944
av_cold int ff_vaapi_encode_init(AVCodecContext *avctx, const VAAPIEncodeType *type)
static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, VAAPIEncodePicture *pic)
#define se(...)
static av_cold int vaapi_encode_h264_init(AVCodecContext *avctx)
#define FF_PROFILE_H264_EXTENDED
Definition: avcodec.h:3188
static void vaapi_encode_h264_write_pps(PutBitContext *pbc, VAAPIEncodeContext *ctx)
VASurfaceID recon_surface
Definition: vaapi_encode.h:82
#define vseq_var(name)
#define FFALIGN(x, a)
Definition: macros.h:48
#define av_log(a,...)
#define vslice_var(name)
#define ue(...)
H.264 / AVC / MPEG-4 part10 codec.
VAConfigAttrib config_attributes[MAX_CONFIG_ATTRIBUTES]
Definition: vaapi_encode.h:133
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
av_default_item_name
#define AVERROR(e)
Definition: error.h:43
int qmax
maximum quantizer
Definition: avcodec.h:2598
int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *input_image, int *got_packet)
Definition: vaapi_encode.c:788
#define vseq_field(name)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:176
#define vpic_var(name)
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
VAEncMiscParameterBuffer * global_params[MAX_GLOBAL_PARAMS]
Definition: vaapi_encode.h:136
#define FF_PROFILE_H264_HIGH_422
Definition: avcodec.h:3192
#define FF_PROFILE_H264_HIGH
Definition: avcodec.h:3189
static av_cold int vaapi_encode_h264_init_fixed_qp(AVCodecContext *avctx)
simple assert() macros that are a bit more flexible than ISO C assert().
const char * name
Name of the codec implementation.
Definition: avcodec.h:3549
float i_quant_factor
qscale factor between P- and I-frames If > 0 then the last P-frame quantizer will be used (q = lastp_...
Definition: avcodec.h:1986
struct VAAPIEncodeH264Context::@113 rc_params
static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx)
void * codec_picture_params
Definition: vaapi_encode.h:90
static int put_bits_count(PutBitContext *s)
Definition: put_bits.h:85
int rc_buffer_size
decoder bitstream buffer size
Definition: avcodec.h:2625
common internal API header
AVCodec ff_h264_vaapi_encoder
static void vaapi_encode_h264_write_sps(PutBitContext *pbc, VAAPIEncodeContext *ctx)
static int vaapi_encode_h264_write_sequence_header(AVCodecContext *avctx, char *data, size_t *data_len)
int width
picture width / height.
Definition: avcodec.h:1836
#define FF_PROFILE_UNKNOWN
Definition: avcodec.h:3154
AVFormatContext * ctx
Definition: movenc.c:48
int level
level
Definition: avcodec.h:3242
void * codec_picture_params
Definition: vaapi_encode.h:145
static int vaapi_encode_h264_write_slice_header(AVCodecContext *avctx, VAAPIEncodePicture *pic, VAAPIEncodeSlice *slice, char *data, size_t *data_len)
Definition: h264.h:122
#define FF_ARRAY_ELEMS(a)
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
struct VAAPIEncodePicture * refs[MAX_PICTURE_REFERENCES]
Definition: vaapi_encode.h:93
#define mseq_var(name)
Libavcodec external API header.
#define FF_PROFILE_H264_HIGH_422_INTRA
Definition: avcodec.h:3193
main external API structure.
Definition: avcodec.h:1649
int qmin
minimum quantizer
Definition: avcodec.h:2591
#define FF_PROFILE_H264_HIGH_10_INTRA
Definition: avcodec.h:3191
Describe the class of an AVClass context structure.
Definition: log.h:67
struct VAAPIEncodeH264Context::@114 hrd_params
#define FF_PROFILE_H264_HIGH_444
Definition: avcodec.h:3194
float b_quant_offset
qscale offset between IP and B-frames
Definition: avcodec.h:1963
#define u(width,...)
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:262
VAAPIEncodeH264MiscSliceParams misc_slice_params
static av_cold int vaapi_encode_h264_init_internal(AVCodecContext *avctx)
size_t global_params_size[MAX_GLOBAL_PARAMS]
Definition: vaapi_encode.h:137
static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx, VAAPIEncodePicture *pic, VAAPIEncodeSlice *slice)
VAEncMiscParameterRateControl rc
common internal api header.
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
Definition: put_bits.h:101
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:107
static void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
Initialize the PutBitContext s.
Definition: put_bits.h:48
int den
denominator
Definition: rational.h:45
static av_cold int vaapi_encode_h264_init_constant_bitrate(AVCodecContext *avctx)
void * priv_data
Definition: avcodec.h:1691
pixel format definitions
#define mslice_var(name)
static uint8_t tmp[8]
Definition: des.c:38
void * codec_slice_params
Definition: vaapi_encode.h:63
#define FF_PROFILE_H264_HIGH_444_INTRA
Definition: avcodec.h:3196
static void vaapi_encode_h264_write_trailing_rbsp(PutBitContext *pbc)
static const AVCodecDefault defaults[]
Definition: dcaenc.c:975
#define FF_PROFILE_H264_CONSTRAINED
Definition: avcodec.h:3182
#define FF_PROFILE_H264_CONSTRAINED_BASELINE
Definition: avcodec.h:3186
VABufferID output_buffer
Definition: vaapi_encode.h:87
#define FF_PROFILE_H264_HIGH_10
Definition: avcodec.h:3190
AVPixelFormat
Pixel format.
Definition: pixfmt.h:60
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:252
VAAPIEncodeH264MiscSequenceParams misc_sequence_params
int ff_vaapi_encode_h26x_nal_unit_to_byte_stream(uint8_t *dst, size_t *dst_bit_len, uint8_t *src, size_t src_bit_len)