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 <string.h>
20
21 #include <va/va.h>
22 #include <va/va_enc_hevc.h>
23
29
39
40 enum {
43 };
44
47
49
54
57
58 // Encoder features.
60 // Block size info.
64
65 // User options.
72
73 // Derived settings.
77
78 // Writer structures.
84
87
93
94
96 char *
data,
size_t *data_len,
98 {
100 int err;
101
103 if (err < 0) {
105 return err;
106 }
107
110 "%zu < %zu.\n", *data_len,
113 }
114
117
118 return 0;
119 }
120
123 void *nal_unit)
124 {
126 int err;
127
130 if (err < 0) {
132 "type = %d.\n",
header->nal_unit_type);
133 return err;
134 }
135
136 return 0;
137 }
138
140 char *
data,
size_t *data_len)
141 {
144 int err;
145
148 if (err < 0)
151 }
152
154 if (err < 0)
156
158 if (err < 0)
160
162 if (err < 0)
164
168 return err;
169 }
170
174 char *
data,
size_t *data_len)
175 {
178 int err;
179
182 if (err < 0)
185 }
186
188 if (err < 0)
190
194 return err;
195 }
196
200 char *
data,
size_t *data_len)
201 {
204 int err;
205
209 if (err < 0)
212 }
213
218 if (err < 0)
220 }
221
226 if (err < 0)
228 }
229
231
233 if (err < 0)
235
237
238 *
type = VAEncPackedHeaderRawData;
239 return 0;
240 } else {
242 }
243
246 return err;
247 }
248
250 {
258 VAEncSequenceParameterBufferHEVC *vseq =
ctx->codec_sequence_params;
259 VAEncPictureParameterBufferHEVC *vpic =
ctx->codec_picture_params;
263
264 memset(
vps, 0,
sizeof(*
vps));
265 memset(
sps, 0,
sizeof(*
sps));
266 memset(
pps, 0,
sizeof(*
pps));
267
268
271 if (
desc->nb_components == 1) {
272 chroma_format = 0;
273 } else {
274 if (
desc->log2_chroma_w == 1 &&
desc->log2_chroma_h == 1) {
275 chroma_format = 1;
276 }
else if (
desc->log2_chroma_w == 1 &&
desc->log2_chroma_h == 0) {
277 chroma_format = 2;
278 }
else if (
desc->log2_chroma_w == 0 &&
desc->log2_chroma_h == 0) {
279 chroma_format = 3;
280 } else {
282 "%s is not supported.\n",
desc->name);
284 }
285 }
287
288
289 // VPS
290
293 .nuh_layer_id = 0,
294 .nuh_temporal_id_plus1 = 1,
295 };
296
297 vps->vps_video_parameter_set_id = 0;
298
299 vps->vps_base_layer_internal_flag = 1;
300 vps->vps_base_layer_available_flag = 1;
301 vps->vps_max_layers_minus1 = 0;
302 vps->vps_max_sub_layers_minus1 = 0;
303 vps->vps_temporal_id_nesting_flag = 1;
304
308
310
316 }
317
322
327
331
334
336
339 } else {
341
343 ctx->surface_width,
ctx->surface_height,
344 ctx->nb_slices,
ctx->tile_rows,
ctx->tile_cols,
345 (
ctx->b_per_p > 0) + 1);
349 } else {
351 "any normal level; using level 8.5.\n");
353 // The tier flag must be set in level 8.5.
355 }
356 }
357
358 vps->vps_sub_layer_ordering_info_present_flag = 0;
359 vps->vps_max_dec_pic_buffering_minus1[0] =
ctx->max_b_depth + 1;
360 vps->vps_max_num_reorder_pics[0] =
ctx->max_b_depth;
361 vps->vps_max_latency_increase_plus1[0] = 0;
362
363 vps->vps_max_layer_id = 0;
364 vps->vps_num_layer_sets_minus1 = 0;
365 vps->layer_id_included_flag[0][0] = 1;
366
367 vps->vps_timing_info_present_flag = 1;
371 vps->vps_poc_proportional_to_timing_flag = 1;
372 vps->vps_num_ticks_poc_diff_one_minus1 = 0;
373 } else {
376 vps->vps_poc_proportional_to_timing_flag = 0;
377 }
378 vps->vps_num_hrd_parameters = 0;
379
380
381 // SPS
382
385 .nuh_layer_id = 0,
386 .nuh_temporal_id_plus1 = 1,
387 };
388
389 sps->sps_video_parameter_set_id =
vps->vps_video_parameter_set_id;
390
391 sps->sps_max_sub_layers_minus1 =
vps->vps_max_sub_layers_minus1;
392 sps->sps_temporal_id_nesting_flag =
vps->vps_temporal_id_nesting_flag;
393
394 sps->profile_tier_level =
vps->profile_tier_level;
395
396 sps->sps_seq_parameter_set_id = 0;
397
398 sps->chroma_format_idc = chroma_format;
399 sps->separate_colour_plane_flag = 0;
400
401 sps->pic_width_in_luma_samples =
ctx->surface_width;
402 sps->pic_height_in_luma_samples =
ctx->surface_height;
403
404 if (avctx->
width !=
ctx->surface_width ||
406 sps->conformance_window_flag = 1;
407 sps->conf_win_left_offset = 0;
408 sps->conf_win_right_offset =
409 (
ctx->surface_width - avctx->
width) >>
desc->log2_chroma_w;
410 sps->conf_win_top_offset = 0;
411 sps->conf_win_bottom_offset =
412 (
ctx->surface_height - avctx->
height) >>
desc->log2_chroma_h;
413 } else {
414 sps->conformance_window_flag = 0;
415 }
416
419
420 sps->log2_max_pic_order_cnt_lsb_minus4 = 8;
421
422 sps->sps_sub_layer_ordering_info_present_flag =
423 vps->vps_sub_layer_ordering_info_present_flag;
424 for (
i = 0;
i <=
sps->sps_max_sub_layers_minus1;
i++) {
425 sps->sps_max_dec_pic_buffering_minus1[
i] =
426 vps->vps_max_dec_pic_buffering_minus1[
i];
427 sps->sps_max_num_reorder_pics[
i] =
428 vps->vps_max_num_reorder_pics[
i];
429 sps->sps_max_latency_increase_plus1[
i] =
430 vps->vps_max_latency_increase_plus1[
i];
431 }
432
433 // These values come from the capabilities of the first encoder
434 // implementation in the i965 driver on Intel Skylake. They may
435 // fail badly with other platforms or drivers.
436 // CTB size from 8x8 to 32x32.
437 sps->log2_min_luma_coding_block_size_minus3 = 0;
438 sps->log2_diff_max_min_luma_coding_block_size = 2;
439 // Transform size from 4x4 to 32x32.
440 sps->log2_min_luma_transform_block_size_minus2 = 0;
441 sps->log2_diff_max_min_luma_transform_block_size = 3;
442 // Full transform hierarchy allowed (2-5).
443 sps->max_transform_hierarchy_depth_inter = 3;
444 sps->max_transform_hierarchy_depth_intra = 3;
445 // AMP works.
446 sps->amp_enabled_flag = 1;
447 // SAO and temporal MVP do not work.
448 sps->sample_adaptive_offset_enabled_flag = 0;
449 sps->sps_temporal_mvp_enabled_flag = 0;
450
451 sps->pcm_enabled_flag = 0;
452
453 // update sps setting according to queried result
454 #if VA_CHECK_VERSION(1, 13, 0)
456 VAConfigAttribValEncHEVCFeatures features = { .value = priv->
va_features };
457
458 // Enable feature if get queried result is VA_FEATURE_SUPPORTED | VA_FEATURE_REQUIRED
459 sps->amp_enabled_flag =
460 !!features.bits.amp;
461 sps->sample_adaptive_offset_enabled_flag =
462 !!features.bits.sao;
463 sps->sps_temporal_mvp_enabled_flag =
464 !!features.bits.temporal_mvp;
465 sps->pcm_enabled_flag =
466 !!features.bits.pcm;
467 }
468
470 VAConfigAttribValEncHEVCBlockSizes bs = { .value = priv->
va_bs };
471 sps->log2_min_luma_coding_block_size_minus3 =
473 sps->log2_diff_max_min_luma_coding_block_size =
475
476 sps->log2_min_luma_transform_block_size_minus2 =
477 bs.bits.log2_min_luma_transform_block_size_minus2;
478 sps->log2_diff_max_min_luma_transform_block_size =
479 bs.bits.log2_max_luma_transform_block_size_minus2 -
480 bs.bits.log2_min_luma_transform_block_size_minus2;
481
482 sps->max_transform_hierarchy_depth_inter =
483 bs.bits.max_max_transform_hierarchy_depth_inter;
484 sps->max_transform_hierarchy_depth_intra =
485 bs.bits.max_max_transform_hierarchy_depth_intra;
486 }
487 #endif
488
489 // STRPSs should ideally be here rather than defined individually in
490 // each slice, but the structure isn't completely fixed so for now
491 // don't bother.
492 sps->num_short_term_ref_pic_sets = 0;
493 sps->long_term_ref_pics_present_flag = 0;
494
495 sps->vui_parameters_present_flag = 1;
496
500 { 0, 0 },
501 { 1, 1 }, { 12, 11 }, { 10, 11 }, { 16, 11 },
502 { 40, 33 }, { 24, 11 }, { 20, 11 }, { 32, 11 },
503 { 80, 33 }, { 18, 11 }, { 15, 11 }, { 64, 33 },
504 { 160, 99 }, { 4, 3 }, { 3, 2 }, { 2, 1 },
505 };
510 if (num == sar_idc[
i].num &&
511 den == sar_idc[
i].den) {
513 break;
514 }
515 }
520 }
522 }
523
524 // Unspecified video format, from table E-2.
538
544 }
545
552
560
561
562 // PPS
563
566 .nuh_layer_id = 0,
567 .nuh_temporal_id_plus1 = 1,
568 };
569
570 pps->pps_pic_parameter_set_id = 0;
571 pps->pps_seq_parameter_set_id =
sps->sps_seq_parameter_set_id;
572
573 pps->num_ref_idx_l0_default_active_minus1 = 0;
574 pps->num_ref_idx_l1_default_active_minus1 = 0;
575
577
578 pps->cu_qp_delta_enabled_flag = (
ctx->va_rc_mode != VA_RC_CQP);
579 pps->diff_cu_qp_delta_depth = 0;
580
581 // update pps setting according to queried result
582 #if VA_CHECK_VERSION(1, 13, 0)
584 VAConfigAttribValEncHEVCFeatures features = { .value = priv->
va_features };
585 if (
ctx->va_rc_mode != VA_RC_CQP)
586 pps->cu_qp_delta_enabled_flag =
587 !!features.bits.cu_qp_delta;
588
589 pps->transform_skip_enabled_flag =
590 !!features.bits.transform_skip;
591 // set diff_cu_qp_delta_depth as its max value if cu_qp_delta enabled. Otherwise
592 // 0 will make cu_qp_delta invalid.
593 if (
pps->cu_qp_delta_enabled_flag)
594 pps->diff_cu_qp_delta_depth =
sps->log2_diff_max_min_luma_coding_block_size;
595 }
596 #endif
597
598 if (
ctx->tile_rows &&
ctx->tile_cols) {
599 int uniform_spacing;
600
601 pps->tiles_enabled_flag = 1;
602 pps->num_tile_columns_minus1 =
ctx->tile_cols - 1;
603 pps->num_tile_rows_minus1 =
ctx->tile_rows - 1;
604
605 // Test whether the spacing provided matches the H.265 uniform
606 // spacing, and set the flag if it does.
607 uniform_spacing = 1;
608 for (
i = 0;
i <=
pps->num_tile_columns_minus1 &&
609 uniform_spacing;
i++) {
610 if (
ctx->col_width[
i] !=
611 (
i + 1) *
ctx->slice_block_cols /
ctx->tile_cols -
612 i *
ctx->slice_block_cols /
ctx->tile_cols)
613 uniform_spacing = 0;
614 }
615 for (
i = 0;
i <=
pps->num_tile_rows_minus1 &&
616 uniform_spacing;
i++) {
617 if (
ctx->row_height[
i] !=
618 (
i + 1) *
ctx->slice_block_rows /
ctx->tile_rows -
619 i *
ctx->slice_block_rows /
ctx->tile_rows)
620 uniform_spacing = 0;
621 }
622 pps->uniform_spacing_flag = uniform_spacing;
623
624 for (
i = 0;
i <=
pps->num_tile_columns_minus1;
i++)
625 pps->column_width_minus1[
i] =
ctx->col_width[
i] - 1;
626 for (
i = 0;
i <=
pps->num_tile_rows_minus1;
i++)
627 pps->row_height_minus1[
i] =
ctx->row_height[
i] - 1;
628
629 pps->loop_filter_across_tiles_enabled_flag = 1;
630 }
631
632 pps->pps_loop_filter_across_slices_enabled_flag = 1;
633
634 // Fill VAAPI parameter buffers.
635
636 *vseq = (VAEncSequenceParameterBufferHEVC) {
637 .general_profile_idc =
vps->profile_tier_level.general_profile_idc,
638 .general_level_idc =
vps->profile_tier_level.general_level_idc,
639 .general_tier_flag =
vps->profile_tier_level.general_tier_flag,
640
641 .intra_period =
ctx->gop_size,
642 .intra_idr_period =
ctx->gop_size,
643 .ip_period =
ctx->b_per_p + 1,
644 .bits_per_second =
ctx->va_bit_rate,
645
646 .pic_width_in_luma_samples =
sps->pic_width_in_luma_samples,
647 .pic_height_in_luma_samples =
sps->pic_height_in_luma_samples,
648
649 .seq_fields.bits = {
650 .chroma_format_idc =
sps->chroma_format_idc,
651 .separate_colour_plane_flag =
sps->separate_colour_plane_flag,
652 .bit_depth_luma_minus8 =
sps->bit_depth_luma_minus8,
653 .bit_depth_chroma_minus8 =
sps->bit_depth_chroma_minus8,
654 .scaling_list_enabled_flag =
sps->scaling_list_enabled_flag,
655 .strong_intra_smoothing_enabled_flag =
656 sps->strong_intra_smoothing_enabled_flag,
657 .amp_enabled_flag =
sps->amp_enabled_flag,
658 .sample_adaptive_offset_enabled_flag =
659 sps->sample_adaptive_offset_enabled_flag,
660 .pcm_enabled_flag =
sps->pcm_enabled_flag,
661 .pcm_loop_filter_disabled_flag =
sps->pcm_loop_filter_disabled_flag,
662 .sps_temporal_mvp_enabled_flag =
sps->sps_temporal_mvp_enabled_flag,
663 },
664
665 .log2_min_luma_coding_block_size_minus3 =
666 sps->log2_min_luma_coding_block_size_minus3,
667 .log2_diff_max_min_luma_coding_block_size =
668 sps->log2_diff_max_min_luma_coding_block_size,
669 .log2_min_transform_block_size_minus2 =
670 sps->log2_min_luma_transform_block_size_minus2,
671 .log2_diff_max_min_transform_block_size =
672 sps->log2_diff_max_min_luma_transform_block_size,
673 .max_transform_hierarchy_depth_inter =
674 sps->max_transform_hierarchy_depth_inter,
675 .max_transform_hierarchy_depth_intra =
676 sps->max_transform_hierarchy_depth_intra,
677
678 .pcm_sample_bit_depth_luma_minus1 =
679 sps->pcm_sample_bit_depth_luma_minus1,
680 .pcm_sample_bit_depth_chroma_minus1 =
681 sps->pcm_sample_bit_depth_chroma_minus1,
682 .log2_min_pcm_luma_coding_block_size_minus3 =
683 sps->log2_min_pcm_luma_coding_block_size_minus3,
684 .log2_max_pcm_luma_coding_block_size_minus3 =
685 sps->log2_min_pcm_luma_coding_block_size_minus3 +
686 sps->log2_diff_max_min_pcm_luma_coding_block_size,
687
688 .vui_parameters_present_flag = 0,
689 };
690
691 *vpic = (VAEncPictureParameterBufferHEVC) {
692 .decoded_curr_pic = {
693 .picture_id = VA_INVALID_ID,
694 .flags = VA_PICTURE_HEVC_INVALID,
695 },
696
697 .coded_buf = VA_INVALID_ID,
698
699 .collocated_ref_pic_index =
sps->sps_temporal_mvp_enabled_flag ?
700 0 : 0xff,
701 .last_picture = 0,
702
703 .pic_init_qp =
pps->init_qp_minus26 + 26,
704 .diff_cu_qp_delta_depth =
pps->diff_cu_qp_delta_depth,
705 .pps_cb_qp_offset =
pps->pps_cb_qp_offset,
706 .pps_cr_qp_offset =
pps->pps_cr_qp_offset,
707
708 .num_tile_columns_minus1 =
pps->num_tile_columns_minus1,
709 .num_tile_rows_minus1 =
pps->num_tile_rows_minus1,
710
711 .log2_parallel_merge_level_minus2 =
pps->log2_parallel_merge_level_minus2,
712 .ctu_max_bitsize_allowed = 0,
713
714 .num_ref_idx_l0_default_active_minus1 =
715 pps->num_ref_idx_l0_default_active_minus1,
716 .num_ref_idx_l1_default_active_minus1 =
717 pps->num_ref_idx_l1_default_active_minus1,
718
719 .slice_pic_parameter_set_id =
pps->pps_pic_parameter_set_id,
720
721 .pic_fields.bits = {
722 .sign_data_hiding_enabled_flag =
pps->sign_data_hiding_enabled_flag,
723 .constrained_intra_pred_flag =
pps->constrained_intra_pred_flag,
724 .transform_skip_enabled_flag =
pps->transform_skip_enabled_flag,
725 .cu_qp_delta_enabled_flag =
pps->cu_qp_delta_enabled_flag,
726 .weighted_pred_flag =
pps->weighted_pred_flag,
727 .weighted_bipred_flag =
pps->weighted_bipred_flag,
728 .transquant_bypass_enabled_flag =
pps->transquant_bypass_enabled_flag,
729 .tiles_enabled_flag =
pps->tiles_enabled_flag,
730 .entropy_coding_sync_enabled_flag =
pps->entropy_coding_sync_enabled_flag,
731 .loop_filter_across_tiles_enabled_flag =
732 pps->loop_filter_across_tiles_enabled_flag,
733 .pps_loop_filter_across_slices_enabled_flag =
734 pps->pps_loop_filter_across_slices_enabled_flag,
735 .scaling_list_data_present_flag = (
sps->sps_scaling_list_data_present_flag |
736 pps->pps_scaling_list_data_present_flag),
737 .screen_content_flag = 0,
738 .enable_gpu_weighted_prediction = 0,
739 .no_output_of_prior_pics_flag = 0,
740 },
741 };
742
743 if (
pps->tiles_enabled_flag) {
744 for (
i = 0;
i <= vpic->num_tile_rows_minus1;
i++)
745 vpic->row_height_minus1[
i] =
pps->row_height_minus1[
i];
746 for (
i = 0;
i <= vpic->num_tile_columns_minus1;
i++)
747 vpic->column_width_minus1[
i] =
pps->column_width_minus1[
i];
748 }
749
750 return 0;
751 }
752
755 {
763
766
768
772 } else {
775
785 } else {
788 for (irap_ref = pic; irap_ref; irap_ref = irap_ref->
refs[1]) {
790 break;
791 }
795 } else {
798 }
801 }
802 }
804
810 .nuh_layer_id = 0,
811 .nuh_temporal_id_plus1 = 1,
812 },
814 };
815 } else {
817 }
818
820
821 // Only look for the metadata on I/IDR frame on the output. We
822 // may force an IDR frame on the output where the medadata gets
823 // changed on the input frame.
829
830 if (sd) {
833
834 // SEI is needed when both the primaries and luminance are set
838 const int mapping[3] = {1, 2, 0};
839 const int chroma_den = 50000;
840 const int luma_den = 10000;
841
842 for (
i = 0;
i < 3;
i++) {
843 const int j = mapping[
i];
847 chroma_den);
851 chroma_den);
852 }
853
856 chroma_den);
859 chroma_den);
860
866
868 }
869 }
870 }
871
877
878 if (sd) {
883
885 clli->max_pic_average_light_level =
FFMIN(clm->
MaxFALL, 65535);
886
888 }
889 }
890
891 vpic->decoded_curr_pic = (VAPictureHEVC) {
894 .flags = 0,
895 };
896
900
902 href =
ref->priv_data;
903
904 vpic->reference_frames[
i] = (VAPictureHEVC) {
905 .picture_id =
ref->recon_surface,
908 VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE : 0) |
910 VA_PICTURE_HEVC_RPS_ST_CURR_AFTER : 0),
911 };
912 }
914 vpic->reference_frames[
i] = (VAPictureHEVC) {
915 .picture_id = VA_INVALID_ID,
916 .flags = VA_PICTURE_HEVC_INVALID,
917 };
918 }
919
921
923
926 vpic->pic_fields.bits.idr_pic_flag = 1;
927 vpic->pic_fields.bits.coding_type = 1;
928 vpic->pic_fields.bits.reference_pic_flag = 1;
929 break;
931 vpic->pic_fields.bits.idr_pic_flag = 0;
932 vpic->pic_fields.bits.coding_type = 1;
933 vpic->pic_fields.bits.reference_pic_flag = 1;
934 break;
936 vpic->pic_fields.bits.idr_pic_flag = 0;
937 vpic->pic_fields.bits.coding_type = 2;
938 vpic->pic_fields.bits.reference_pic_flag = 1;
939 break;
941 vpic->pic_fields.bits.idr_pic_flag = 0;
942 vpic->pic_fields.bits.coding_type = 3;
943 vpic->pic_fields.bits.reference_pic_flag = 0;
944 break;
945 default:
947 }
948
949 return 0;
950 }
951
955 {
965
968 .nuh_layer_id = 0,
969 .nuh_temporal_id_plus1 = 1,
970 };
971
973
976
978
981
983 (1 << (
sps->log2_max_pic_order_cnt_lsb_minus4 + 4)) - 1;
984
990 int i, j, poc, rps_pics;
991
993
995 memset(rps, 0, sizeof(*rps));
996
997 rps_pics = 0;
1001 rps_used[rps_pics] = 1;
1002 ++rps_pics;
1003 }
1005 if (pic->
dpb[
i] == pic)
1006 continue;
1007 for (j = 0; j < pic->
nb_refs; j++) {
1009 break;
1010 }
1011 if (j < pic->nb_refs)
1012 continue;
1015 rps_used[rps_pics] = 0;
1016 ++rps_pics;
1017 }
1018
1019 for (
i = 1;
i < rps_pics;
i++) {
1020 for (j =
i; j > 0; j--) {
1021 if (rps_poc[j] > rps_poc[j - 1])
1022 break;
1024 FFSWAP(
int, rps_poc[j], rps_poc[j - 1]);
1025 FFSWAP(
int, rps_used[j], rps_used[j - 1]);
1026 }
1027 }
1028
1031 for (
i = 0;
i < rps_pics;
i++) {
1033 rps_poc[
i], rps_used[
i]);
1034 }
1036
1037 for (
i = 0;
i < rps_pics;
i++) {
1040 break;
1041 }
1042
1045 for (j =
i - 1; j >= 0; j--) {
1048 poc = rps_poc[j];
1049 }
1050
1053 for (j =
i; j < rps_pics; j++) {
1056 poc = rps_poc[j];
1057 }
1058
1061
1062 // when this flag is not present, it is inerred to 1.
1065 sps->sps_temporal_mvp_enabled_flag;
1070 }
1071
1075 }
1076
1078 sps->sample_adaptive_offset_enabled_flag;
1079
1084 else
1086
1087
1088 *vslice = (VAEncSliceParameterBufferHEVC) {
1091
1094
1097
1100
1102
1106
1109
1110 .slice_fields.bits = {
1114 .slice_temporal_mvp_enabled_flag =
1118 .num_ref_idx_active_override_flag =
1122 .slice_deblocking_filter_disabled_flag =
1124 .slice_loop_filter_across_slices_enabled_flag =
1127 },
1128 };
1129
1131 vslice->ref_pic_list0[
i].picture_id = VA_INVALID_ID;
1132 vslice->ref_pic_list0[
i].flags = VA_PICTURE_HEVC_INVALID;
1133 vslice->ref_pic_list1[
i].picture_id = VA_INVALID_ID;
1134 vslice->ref_pic_list1[
i].flags = VA_PICTURE_HEVC_INVALID;
1135 }
1136
1139 // Backward reference for P- or B-frame.
1142 vslice->ref_pic_list0[0] = vpic->reference_frames[0];
1144 // Reference for GPB B-frame, L0 == L1
1145 vslice->ref_pic_list1[0] = vpic->reference_frames[0];
1146 }
1148 // Forward reference for B-frame.
1150 vslice->ref_pic_list1[0] = vpic->reference_frames[1];
1151 }
1152
1156 vslice->ref_pic_list1[
i].picture_id = vslice->ref_pic_list0[
i].picture_id;
1157 vslice->ref_pic_list1[
i].flags = vslice->ref_pic_list0[
i].flags;
1158 }
1159 }
1160
1161 return 0;
1162 }
1163
1165 {
1168
1169 #if VA_CHECK_VERSION(1, 13, 0)
1170 {
1171 VAConfigAttribValEncHEVCBlockSizes block_size;
1172 VAConfigAttrib attr;
1173 VAStatus vas;
1174
1175 attr.type = VAConfigAttribEncHEVCFeatures;
1176 vas = vaGetConfigAttributes(
ctx->hwctx->display,
ctx->va_profile,
1177 ctx->va_entrypoint, &attr, 1);
1178 if (vas != VA_STATUS_SUCCESS) {
1180 "features, using guessed defaults.\n");
1182 } else if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1184 "encoder features, using guessed defaults.\n");
1185 } else {
1187 }
1188
1189 attr.type = VAConfigAttribEncHEVCBlockSizes;
1190 vas = vaGetConfigAttributes(
ctx->hwctx->display,
ctx->va_profile,
1191 ctx->va_entrypoint, &attr, 1);
1192 if (vas != VA_STATUS_SUCCESS) {
1194 "block size, using guessed defaults.\n");
1196 } else if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1198 "encoder block size, using guessed defaults.\n");
1199 } else {
1200 priv->
va_bs = block_size.value = attr.value;
1201
1203 1 << block_size.bits.log2_max_coding_tree_block_size_minus3 + 3;
1205 1 << block_size.bits.log2_min_luma_coding_block_size_minus3 + 3;
1206 }
1207 }
1208 #endif
1209
1213 }
1217
1220
1221 ctx->slice_block_width =
ctx->slice_block_height = priv->
ctu_size;
1222
1223 return 0;
1224 }
1225
1227 {
1230 int err;
1231
1233 if (err < 0)
1234 return err;
1235
1236 if (
ctx->va_rc_mode == VA_RC_CQP) {
1237 // Note that VAAPI only supports positive QP values - the range is
1238 // therefore always bounded below by 1, even in 10-bit mode where
1239 // it should go down to -12.
1240
1246 else
1252 else
1254
1256 "%d / %d / %d for IDR- / P- / B-frames.\n",
1258
1259 } else {
1260 // These still need to be set for init_qp/slice_qp_delta.
1264 }
1265
1266 ctx->roi_quant_range = 51 + 6 * (
ctx->profile->depth - 8);
1267
1268 return 0;
1269 }
1270
1274 #if VA_CHECK_VERSION(0, 37, 0)
1277 #endif
1278 #if VA_CHECK_VERSION(1, 2, 0)
1281 #endif
1283 };
1284
1287
1292
1293 .default_quality = 25,
1294
1297
1299
1300 .sequence_params_size = sizeof(VAEncSequenceParameterBufferHEVC),
1302
1303 .picture_params_size = sizeof(VAEncPictureParameterBufferHEVC),
1305
1306 .slice_params_size = sizeof(VAEncSliceParameterBufferHEVC),
1308
1309 .sequence_header_type = VAEncPackedHeaderSequence,
1311
1312 .slice_header_type = VAEncPackedHeaderHEVC_Slice,
1314
1316 };
1317
1319 {
1322
1324
1329
1332 "in 8-bit unsigned integer.\n", avctx->
level);
1334 }
1335
1336 ctx->desired_packed_headers =
1337 VA_ENC_PACKED_HEADER_SEQUENCE | // VPS, SPS and PPS.
1338 VA_ENC_PACKED_HEADER_SLICE | // Slice headers.
1339 VA_ENC_PACKED_HEADER_MISC; // SEI
1340
1342 ctx->explicit_qp = priv->
qp;
1343
1345 }
1346
1348 {
1350
1353
1355 }
1356
1357 #define OFFSET(x) offsetof(VAAPIEncodeH265Context, x)
1358 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
1362
1363 { "qp", "Constant QP (for P-frames; scaled by qfactor/qoffset for I/B)",
1365
1366 { "aud", "Include AUD",
1368
1369 { "profile", "Set profile (general_profile_idc)",
1372
1373 #define PROFILE(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
1374 { .i64 = value }, 0, 0, FLAGS, "profile"
1378 #undef PROFILE
1379
1380 { "tier", "Set tier (general_tier_flag)",
1382 { .i64 = 0 }, 0, 1,
FLAGS,
"tier" },
1384 { .i64 = 0 }, 0, 0,
FLAGS,
"tier" },
1386 { .i64 = 1 }, 0, 0,
FLAGS,
"tier" },
1387
1388 { "level", "Set level (general_level_idc)",
1391
1392 #define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
1393 { .i64 = value }, 0, 0, FLAGS, "level"
1396 {
LEVEL(
"2.1", 63) },
1398 {
LEVEL(
"3.1", 93) },
1399 {
LEVEL(
"4", 120) },
1400 {
LEVEL(
"4.1", 123) },
1401 {
LEVEL(
"5", 150) },
1402 {
LEVEL(
"5.1", 153) },
1403 {
LEVEL(
"5.2", 156) },
1404 {
LEVEL(
"6", 180) },
1405 {
LEVEL(
"6.1", 183) },
1406 {
LEVEL(
"6.2", 186) },
1407 #undef LEVEL
1408
1409 { "sei", "Set SEI to include",
1412 0, INT_MAX,
FLAGS,
"sei" },
1413 { "hdr",
1414 "Include HDR metadata for mastering display colour volume "
1415 "and content light level information",
1418 INT_MIN, INT_MAX,
FLAGS,
"sei" },
1419
1420 { "tiles", "Tile columns x rows",
1423
1425 };
1426
1428 { "b", "0" },
1429 { "bf", "2" },
1430 { "g", "120" },
1431 { "i_qfactor", "1" },
1432 { "i_qoffset", "0" },
1433 { "b_qfactor", "6/5" },
1434 { "b_qoffset", "0" },
1435 { "qmin", "-1" },
1436 { "qmax", "-1" },
1438 };
1439
1445 };
1446
1448 .
p.
name =
"hevc_vaapi",
1464 },
1466 .p.wrapper_name = "vaapi",
1467 };