FFmpeg
amfenc_av1.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 "libavutil/internal.h"
20 #include "libavutil/intreadwrite.h"
21 #include "libavutil/mem.h"
22 #include "libavutil/opt.h"
23 #include "amfenc.h"
24 #include "codec_internal.h"
25 
26 #define AMF_VIDEO_ENCODER_AV1_CAP_WIDTH_ALIGNMENT_FACTOR_LOCAL L"Av1WidthAlignmentFactor" // amf_int64; default = 1
27 #define AMF_VIDEO_ENCODER_AV1_CAP_HEIGHT_ALIGNMENT_FACTOR_LOCAL L"Av1HeightAlignmentFactor" // amf_int64; default = 1
28 
29 #define OFFSET(x) offsetof(AmfContext, x)
30 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
31 static const AVOption options[] = {
32 
33  { "usage", "Set the encoding usage", OFFSET(usage), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, AMF_VIDEO_ENCODER_AV1_USAGE_LOW_LATENCY_HIGH_QUALITY, VE, .unit = "usage" },
34  { "transcoding", "Generic Transcoding", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_USAGE_TRANSCODING }, 0, 0, VE, .unit = "usage" },
35  { "ultralowlatency", "ultra low latency trancoding", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_USAGE_ULTRA_LOW_LATENCY }, 0, 0, VE, .unit = "usage" },
36  { "lowlatency", "Low latency usecase", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_USAGE_LOW_LATENCY }, 0, 0, VE, .unit = "usage" },
37  { "webcam", "Webcam", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_USAGE_WEBCAM }, 0, 0, VE, .unit = "usage" },
38  { "high_quality", "high quality trancoding", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_USAGE_HIGH_QUALITY }, 0, 0, VE, .unit = "usage" },
39  { "lowlatency_high_quality","low latency yet high quality trancoding", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_USAGE_LOW_LATENCY_HIGH_QUALITY }, 0, 0, VE, .unit = "usage" },
40 
41  { "profile", "Set the profile", OFFSET(profile), AV_OPT_TYPE_INT,{.i64 = -1 }, -1, AMF_VIDEO_ENCODER_AV1_PROFILE_MAIN, VE, .unit = "profile" },
42  { "main", "", 0, AV_OPT_TYPE_CONST,{.i64 = AMF_VIDEO_ENCODER_AV1_PROFILE_MAIN }, 0, 0, VE, .unit = "profile" },
43 
44  { "level", "Set the encoding level (default auto)", OFFSET(level), AV_OPT_TYPE_INT,{.i64 = -1 }, -1, AMF_VIDEO_ENCODER_AV1_LEVEL_7_3, VE, .unit = "level" },
45  { "auto", "", 0, AV_OPT_TYPE_CONST, {.i64 = -1 }, 0, 0, VE, .unit = "level" },
46  { "2.0", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_2_0 }, 0, 0, VE, .unit = "level" },
47  { "2.1", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_2_1 }, 0, 0, VE, .unit = "level" },
48  { "2.2", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_2_2 }, 0, 0, VE, .unit = "level" },
49  { "2.3", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_2_3 }, 0, 0, VE, .unit = "level" },
50  { "3.0", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_3_0 }, 0, 0, VE, .unit = "level" },
51  { "3.1", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_3_1 }, 0, 0, VE, .unit = "level" },
52  { "3.2", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_3_2 }, 0, 0, VE, .unit = "level" },
53  { "3.3", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_3_3 }, 0, 0, VE, .unit = "level" },
54  { "4.0", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_4_0 }, 0, 0, VE, .unit = "level" },
55  { "4.1", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_4_1 }, 0, 0, VE, .unit = "level" },
56  { "4.2", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_4_2 }, 0, 0, VE, .unit = "level" },
57  { "4.3", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_4_3 }, 0, 0, VE, .unit = "level" },
58  { "5.0", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_5_0 }, 0, 0, VE, .unit = "level" },
59  { "5.1", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_5_1 }, 0, 0, VE, .unit = "level" },
60  { "5.2", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_5_2 }, 0, 0, VE, .unit = "level" },
61  { "5.3", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_5_3 }, 0, 0, VE, .unit = "level" },
62  { "6.0", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_6_0 }, 0, 0, VE, .unit = "level" },
63  { "6.1", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_6_1 }, 0, 0, VE, .unit = "level" },
64  { "6.2", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_6_2 }, 0, 0, VE, .unit = "level" },
65  { "6.3", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_6_3 }, 0, 0, VE, .unit = "level" },
66  { "7.0", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_7_0 }, 0, 0, VE, .unit = "level" },
67  { "7.1", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_7_1 }, 0, 0, VE, .unit = "level" },
68  { "7.2", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_7_2 }, 0, 0, VE, .unit = "level" },
69  { "7.3", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_7_3 }, 0, 0, VE, .unit = "level" },
70 
71  { "quality", "Set the encoding quality preset", OFFSET(quality), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_SPEED, VE, .unit = "quality" },
72  { "preset", "Set the encoding quality preset", OFFSET(quality), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_SPEED, VE, .unit = "quality" },
73  { "high_quality", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_HIGH_QUALITY }, 0, 0, VE, .unit = "quality" },
74  { "quality", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_QUALITY }, 0, 0, VE, .unit = "quality" },
75  { "balanced", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_BALANCED }, 0, 0, VE, .unit = "quality" },
76  { "speed", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_SPEED }, 0, 0, VE, .unit = "quality" },
77 
78  { "latency", "Set the encoding latency mode", OFFSET(latency), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, AMF_VIDEO_ENCODER_AV1_ENCODING_LATENCY_MODE_LOWEST_LATENCY, VE, .unit = "latency_mode" },
79  { "none", "No encoding latency requirement.", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_ENCODING_LATENCY_MODE_NONE }, 0, 0, VE, .unit = "latency_mode" },
80  { "power_saving_real_time", "Try the best to finish encoding a frame within 1/framerate sec.", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_ENCODING_LATENCY_MODE_POWER_SAVING_REAL_TIME }, 0, 0, VE, .unit = "latency_mode" },
81  { "real_time", "Try the best to finish encoding a frame within 1/(2 x framerate) sec.", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_ENCODING_LATENCY_MODE_REAL_TIME }, 0, 0, VE, .unit = "latency_mode" },
82  { "lowest_latency", "Encoding as fast as possible. This mode causes highest power consumption", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_ENCODING_LATENCY_MODE_LOWEST_LATENCY }, 0, 0, VE, .unit = "latency_mode" },
83 
84  { "rc", "Set the rate control mode", OFFSET(rate_control_mode), AV_OPT_TYPE_INT, {.i64 = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_UNKNOWN }, AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_UNKNOWN, AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_HIGH_QUALITY_CBR, VE, .unit = "rc" },
85  { "cqp", "Constant Quantization Parameter", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CONSTANT_QP }, 0, 0, VE, .unit = "rc" },
86  { "vbr_latency", "Latency Constrained Variable Bitrate", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR }, 0, 0, VE, .unit = "rc" },
87  { "vbr_peak", "Peak Contrained Variable Bitrate", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR }, 0, 0, VE, .unit = "rc" },
88  { "cbr", "Constant Bitrate", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CBR }, 0, 0, VE, .unit = "rc" },
89  { "qvbr", "Quality Variable Bitrate", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_QUALITY_VBR }, 0, 0, VE, .unit = "rc" },
90  { "hqvbr", "High Quality Variable Bitrate", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_HIGH_QUALITY_VBR }, 0, 0, VE, .unit = "rc" },
91  { "hqcbr", "High Quality Constant Bitrate", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_HIGH_QUALITY_CBR }, 0, 0, VE, .unit = "rc" },
92 
93  { "qvbr_quality_level", "Sets the QVBR quality level", OFFSET(qvbr_quality_level), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 51, VE },
94 
95  { "header_insertion_mode", "Set header insertion mode", OFFSET(header_insertion_mode), AV_OPT_TYPE_INT,{.i64 = -1 }, -1, AMF_VIDEO_ENCODER_AV1_HEADER_INSERTION_MODE_KEY_FRAME_ALIGNED, VE, .unit = "hdrmode" },
96  { "none", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_HEADER_INSERTION_MODE_NONE }, 0, 0, VE, .unit = "hdrmode" },
97  { "gop", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_HEADER_INSERTION_MODE_GOP_ALIGNED }, 0, 0, VE, .unit = "hdrmode" },
98  { "frame", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_HEADER_INSERTION_MODE_KEY_FRAME_ALIGNED }, 0, 0, VE, .unit = "hdrmode" },
99 
100  { "preencode", "Enable preencode", OFFSET(preencode), AV_OPT_TYPE_BOOL, {.i64 = -1 }, -1, 1, VE},
101  { "enforce_hrd", "Enforce HRD", OFFSET(enforce_hrd), AV_OPT_TYPE_BOOL, {.i64 = -1 }, -1, 1, VE},
102  { "filler_data", "Filler Data Enable", OFFSET(filler_data), AV_OPT_TYPE_BOOL, {.i64 = -1 }, -1, 1, VE},
103 
104  { "high_motion_quality_boost_enable", "Enable High motion quality boost mode", OFFSET(hw_high_motion_quality_boost), AV_OPT_TYPE_BOOL, {.i64 = -1 }, -1, 1, VE },
105 
106  // min_qp_i -> min_qp_intra, min_qp_p -> min_qp_inter
107  { "min_qp_i", "min quantization parameter for I-frame", OFFSET(min_qp_i), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 255, VE },
108  { "max_qp_i", "max quantization parameter for I-frame", OFFSET(max_qp_i), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 255, VE },
109  { "min_qp_p", "min quantization parameter for P-frame", OFFSET(min_qp_p), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 255, VE },
110  { "max_qp_p", "max quantization parameter for P-frame", OFFSET(max_qp_p), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 255, VE },
111  { "qp_p", "quantization parameter for P-frame", OFFSET(qp_p), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 255, VE },
112  { "qp_i", "quantization parameter for I-frame", OFFSET(qp_i), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 255, VE },
113  { "skip_frame", "Rate Control Based Frame Skip", OFFSET(skip_frame), AV_OPT_TYPE_BOOL,{.i64 = -1 }, -1, 1, VE },
114 
115  { "aq_mode", "adaptive quantization mode", OFFSET(aq_mode), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, AMF_VIDEO_ENCODER_AV1_AQ_MODE_CAQ, VE , .unit = "adaptive_quantisation_mode" },
116  { "none", "no adaptive quantization", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_AQ_MODE_NONE }, 0, 0, VE, .unit = "adaptive_quantisation_mode" },
117  { "caq", "context adaptive quantization", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_AQ_MODE_CAQ }, 0, 0, VE, .unit = "adaptive_quantisation_mode" },
118 
119 
120  { "align", "alignment mode", OFFSET(align), AV_OPT_TYPE_INT, {.i64 = AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_NO_RESTRICTIONS }, AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_64X16_ONLY, AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_NO_RESTRICTIONS, VE, .unit = "align" },
121  { "64x16", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_64X16_ONLY }, 0, 0, VE, .unit = "align" },
122  { "1080p", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_64X16_1080P_CODED_1082 }, 0, 0, VE, .unit = "align" },
123  { "none", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_NO_RESTRICTIONS }, 0, 0, VE, .unit = "align" },
124 
125  { "log_to_dbg", "Enable AMF logging to debug output", OFFSET(log_to_dbg), AV_OPT_TYPE_BOOL,{.i64 = 0 }, 0, 1, VE },
126 
127  //Pre Analysis options
128  { "preanalysis", "Enable preanalysis", OFFSET(preanalysis), AV_OPT_TYPE_BOOL, {.i64 = -1 }, -1, 1, VE },
129 
130  { "pa_activity_type", "Set the type of activity analysis", OFFSET(pa_activity_type), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, AMF_PA_ACTIVITY_YUV, VE, .unit = "activity_type" },
131  { "y", "activity y", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_ACTIVITY_Y }, 0, 0, VE, .unit = "activity_type" },
132  { "yuv", "activity yuv", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_ACTIVITY_YUV }, 0, 0, VE, .unit = "activity_type" },
133 
134  { "pa_scene_change_detection_enable", "Enable scene change detection", OFFSET(pa_scene_change_detection), AV_OPT_TYPE_BOOL, {.i64 = -1 }, -1, 1, VE },
135 
136  { "pa_scene_change_detection_sensitivity", "Set the sensitivity of scene change detection", OFFSET(pa_scene_change_detection_sensitivity), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, AMF_PA_SCENE_CHANGE_DETECTION_SENSITIVITY_HIGH, VE, .unit = "scene_change_sensitivity" },
137  { "low", "low scene change dectection sensitivity", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_SCENE_CHANGE_DETECTION_SENSITIVITY_LOW }, 0, 0, VE, .unit = "scene_change_sensitivity" },
138  { "medium", "medium scene change dectection sensitivity", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_SCENE_CHANGE_DETECTION_SENSITIVITY_MEDIUM }, 0, 0, VE, .unit = "scene_change_sensitivity" },
139  { "high", "high scene change dectection sensitivity", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_SCENE_CHANGE_DETECTION_SENSITIVITY_HIGH }, 0, 0, VE, .unit = "scene_change_sensitivity" },
140 
141  { "pa_static_scene_detection_enable", "Enable static scene detection", OFFSET(pa_static_scene_detection), AV_OPT_TYPE_BOOL, {.i64 = -1 }, -1, 1, VE },
142 
143  { "pa_static_scene_detection_sensitivity", "Set the sensitivity of static scene detection", OFFSET(pa_static_scene_detection_sensitivity), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, AMF_PA_STATIC_SCENE_DETECTION_SENSITIVITY_HIGH, VE , .unit = "static_scene_sensitivity" },
144  { "low", "low static scene dectection sensitivity", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_STATIC_SCENE_DETECTION_SENSITIVITY_LOW }, 0, 0, VE, .unit = "static_scene_sensitivity" },
145  { "medium", "medium static scene dectection sensitivity", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_STATIC_SCENE_DETECTION_SENSITIVITY_MEDIUM }, 0, 0, VE, .unit = "static_scene_sensitivity" },
146  { "high", "high static scene dectection sensitivity", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_STATIC_SCENE_DETECTION_SENSITIVITY_HIGH }, 0, 0, VE, .unit = "static_scene_sensitivity" },
147 
148  { "pa_initial_qp_after_scene_change", "The QP value that is used immediately after a scene change", OFFSET(pa_initial_qp), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 51, VE },
149  { "pa_max_qp_before_force_skip", "The QP threshold to allow a skip frame", OFFSET(pa_max_qp), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 51, VE },
150 
151  { "pa_caq_strength", "Content Adaptive Quantization strength", OFFSET(pa_caq_strength), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, AMF_PA_CAQ_STRENGTH_HIGH, VE , .unit = "caq_strength" },
152  { "low", "low Content Adaptive Quantization strength", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_CAQ_STRENGTH_LOW }, 0, 0, VE, .unit = "caq_strength" },
153  { "medium", "medium Content Adaptive Quantization strength", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_CAQ_STRENGTH_MEDIUM }, 0, 0, VE, .unit = "caq_strength" },
154  { "high", "high Content Adaptive Quantization strength", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_CAQ_STRENGTH_HIGH }, 0, 0, VE, .unit = "caq_strength" },
155 
156  { "pa_frame_sad_enable", "Enable Frame SAD algorithm", OFFSET(pa_frame_sad), AV_OPT_TYPE_BOOL, {.i64 = -1 }, -1, 1, VE },
157  { "pa_ltr_enable", "Enable long term reference frame management", OFFSET(pa_ltr), AV_OPT_TYPE_BOOL, {.i64 = -1 }, -1, 1, VE },
158  { "pa_lookahead_buffer_depth", "Sets the PA lookahead buffer size", OFFSET(pa_lookahead_buffer_depth), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, MAX_LOOKAHEAD_DEPTH, VE },
159 
160  { "pa_paq_mode", "Sets the perceptual adaptive quantization mode", OFFSET(pa_paq_mode), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, AMF_PA_PAQ_MODE_CAQ, VE , .unit = "paq_mode" },
161  { "none", "no perceptual adaptive quantization", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_PAQ_MODE_NONE }, 0, 0, VE, .unit = "paq_mode" },
162  { "caq", "caq perceptual adaptive quantization", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_PAQ_MODE_CAQ }, 0, 0, VE, .unit = "paq_mode" },
163 
164  { "pa_taq_mode", "Sets the temporal adaptive quantization mode", OFFSET(pa_taq_mode), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, AMF_PA_TAQ_MODE_2, VE , .unit = "taq_mode" },
165  { "none", "no temporal adaptive quantization", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_TAQ_MODE_NONE }, 0, 0, VE, .unit = "taq_mode" },
166  { "1", "temporal adaptive quantization mode 1", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_TAQ_MODE_1 }, 0, 0, VE, .unit = "taq_mode" },
167  { "2", "temporal adaptive quantization mode 2", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_TAQ_MODE_2 }, 0, 0, VE, .unit = "taq_mode" },
168 
169  { "pa_high_motion_quality_boost_mode", "Sets the PA high motion quality boost mode", OFFSET(pa_high_motion_quality_boost_mode), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, AMF_PA_HIGH_MOTION_QUALITY_BOOST_MODE_AUTO, VE , .unit = "high_motion_quality_boost_mode" },
170  { "none", "no high motion quality boost", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_HIGH_MOTION_QUALITY_BOOST_MODE_NONE }, 0, 0, VE, .unit = "high_motion_quality_boost_mode" },
171  { "auto", "auto high motion quality boost", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_HIGH_MOTION_QUALITY_BOOST_MODE_AUTO }, 0, 0, VE, .unit = "high_motion_quality_boost_mode" },
172  { NULL }
173 
174 };
175 
177 {
178  int ret = 0;
179  AMF_RESULT res = AMF_OK;
180  AmfContext* ctx = avctx->priv_data;
181  AMFVariantStruct var = { 0 };
182  amf_int64 profile = 0;
183  amf_int64 profile_level = 0;
184  AMFBuffer* buffer;
185  AMFGuid guid;
186  AMFRate framerate;
187  AMFSize framesize = AMFConstructSize(avctx->width, avctx->height);
188  amf_int64 color_depth;
189  amf_int64 color_profile;
190  enum AVPixelFormat pix_fmt;
191 
192  //for av1 alignment and crop
193  uint32_t crop_right = 0;
194  uint32_t crop_bottom = 0;
195  int width_alignment_factor = -1;
196  int height_alignment_factor = -1;
197 
198  if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
199  framerate = AMFConstructRate(avctx->framerate.num, avctx->framerate.den);
200  }
201  else {
203  framerate = AMFConstructRate(avctx->time_base.den, avctx->time_base.num
205  * avctx->ticks_per_frame
206 #endif
207  );
209  }
210 
211  if ((ret = ff_amf_encode_init(avctx)) < 0)
212  return ret;
213 
214  // init static parameters
215  if (ctx->usage != -1) {
216  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_USAGE, ctx->usage);
217  }
218 
219  AMF_ASSIGN_PROPERTY_SIZE(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_FRAMESIZE, framesize);
220 
221  AMF_ASSIGN_PROPERTY_RATE(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_FRAMERATE, framerate);
222 
223  switch (avctx->profile) {
224  case AV_PROFILE_AV1_MAIN:
225  profile = AMF_VIDEO_ENCODER_AV1_PROFILE_MAIN;
226  break;
227  default:
228  break;
229  }
230  if (profile == 0) {
231  if (ctx->profile != -1) {
232  profile = ctx->profile;
233  }
234  }
235 
236  if (profile != 0) {
237  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_PROFILE, profile);
238  }
239 
240  /// Color profile
241  color_profile = ff_amf_get_color_profile(avctx);
242  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PROFILE, color_profile);
243 
244  /// Color Depth
245  pix_fmt = avctx->hw_frames_ctx ? ((AVHWFramesContext*)avctx->hw_frames_ctx->data)->sw_format
246  : avctx->pix_fmt;
247  color_depth = AMF_COLOR_BIT_DEPTH_8;
248  if (pix_fmt == AV_PIX_FMT_P010) {
249  color_depth = AMF_COLOR_BIT_DEPTH_10;
250  }
251 
252  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_COLOR_BIT_DEPTH, color_depth);
253  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PROFILE, color_profile);
254  if (color_depth == AMF_COLOR_BIT_DEPTH_8) {
255  /// Color Transfer Characteristics (AMF matches ISO/IEC)
256  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_OUTPUT_TRANSFER_CHARACTERISTIC, AMF_COLOR_TRANSFER_CHARACTERISTIC_BT709);
257  /// Color Primaries (AMF matches ISO/IEC)
258  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PRIMARIES, AMF_COLOR_PRIMARIES_BT709);
259  } else {
260  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_OUTPUT_TRANSFER_CHARACTERISTIC, AMF_COLOR_TRANSFER_CHARACTERISTIC_SMPTE2084);
261  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PRIMARIES, AMF_COLOR_PRIMARIES_BT2020);
262  }
263 
264  profile_level = avctx->level;
265  if (profile_level == AV_LEVEL_UNKNOWN) {
266  profile_level = ctx->level;
267  }
268 
269  if (profile_level != -1) {
270  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_LEVEL, profile_level);
271  }
272 
273  if (ctx->quality != -1) {
274  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET, ctx->quality);
275  }
276 
277  // Maximum Reference Frames
278  if (avctx->refs != -1) {
279  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_MAX_NUM_REFRAMES, avctx->refs);
280  }
281 
282  // Picture control properties
283  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_GOP_SIZE, avctx->gop_size);
284 
285  // Setup header insertion mode only if this option was defined explicitly
286  if (ctx->header_insertion_mode != -1) {
287  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_HEADER_INSERTION_MODE, ctx->header_insertion_mode);
288  }
289 
290  // Rate control
291  // autodetect rate control method
292  if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_UNKNOWN) {
293  if (ctx->min_qp_i != -1 || ctx->max_qp_i != -1 ||
294  ctx->min_qp_p != -1 || ctx->max_qp_p != -1 ||
295  ctx->qp_i != -1 || ctx->qp_p != -1) {
296  ctx->rate_control_mode = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CONSTANT_QP;
297  av_log(ctx, AV_LOG_DEBUG, "Rate control turned to CQP\n");
298  }
299  else if (avctx->bit_rate > 0 && avctx->rc_max_rate == avctx->bit_rate) {
300  ctx->rate_control_mode = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CBR;
301  av_log(ctx, AV_LOG_DEBUG, "Rate control turned to CBR\n");
302  }
303  else {
304  ctx->rate_control_mode = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR;
305  av_log(ctx, AV_LOG_DEBUG, "Rate control turned to Peak VBR\n");
306  }
307  }
308 
309  // Pre-Pass, Pre-Analysis, Two-Pass
310  if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CONSTANT_QP) {
311  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_PREENCODE, 0);
312  if (ctx->preencode != -1) {
313  if (ctx->preencode) {
314  av_log(ctx, AV_LOG_WARNING, "Preencode is not supported by cqp Rate Control Method, automatically disabled\n");
315  }
316  }
317  }
318  else {
319  if (ctx->preencode != -1) {
320  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_PREENCODE, ((ctx->preencode == 0) ? false : true));
321  }
322  }
323 
324  if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_QUALITY_VBR) {
325  if (ctx->qvbr_quality_level != -1) {
326  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_QVBR_QUALITY_LEVEL, ctx->qvbr_quality_level);
327  }
328  }
329 
330  if (ctx->hw_high_motion_quality_boost != -1) {
331  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_HIGH_MOTION_QUALITY_BOOST, ((ctx->hw_high_motion_quality_boost == 0) ? false : true));
332  }
333 
334  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD, ctx->rate_control_mode);
335 
336  if (avctx->rc_buffer_size) {
337  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_VBV_BUFFER_SIZE, avctx->rc_buffer_size);
338 
339  if (avctx->rc_initial_buffer_occupancy != 0) {
340  int amf_buffer_fullness = avctx->rc_initial_buffer_occupancy * 64 / avctx->rc_buffer_size;
341  if (amf_buffer_fullness > 64)
342  amf_buffer_fullness = 64;
343  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_INITIAL_VBV_BUFFER_FULLNESS, amf_buffer_fullness);
344  }
345  }
346 
347  // init dynamic rate control params
348  if (ctx->enforce_hrd != -1) {
349  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_ENFORCE_HRD, ((ctx->enforce_hrd == 0) ? false : true));
350  }
351 
352  if (ctx->filler_data != -1) {
353  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_FILLER_DATA, ((ctx->filler_data == 0) ? false : true));
354  }
355 
356  if (avctx->bit_rate) {
357  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_TARGET_BITRATE, avctx->bit_rate);
358  }
359 
360  if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CBR) {
361  if (avctx->bit_rate) {
362  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_PEAK_BITRATE, avctx->bit_rate);
363  }
364  }
365 
366  if (avctx->rc_max_rate) {
367  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_PEAK_BITRATE, avctx->rc_max_rate);
368  }
369  else if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR) {
370  av_log(ctx, AV_LOG_WARNING, "rate control mode is PEAK_CONSTRAINED_VBR but rc_max_rate is not set\n");
371  }
372  if (avctx->bit_rate > 0) {
373  ctx->rate_control_mode = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CBR;
374  av_log(ctx, AV_LOG_DEBUG, "Rate control turned to CBR\n");
375  }
376 
377  switch (ctx->align)
378  {
379  case AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_64X16_ONLY:
380  if (avctx->width / 64 * 64 != avctx->width || avctx->height / 16 * 16 != avctx->height)
381  {
382  res = AMF_NOT_SUPPORTED;
383  av_log(ctx, AV_LOG_ERROR, "Resolution incorrect for alignment mode\n");
384  return AVERROR_EXIT;
385  }
386  break;
387  case AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_64X16_1080P_CODED_1082:
388  if ((avctx->width / 64 * 64 == avctx->width && avctx->height / 16 * 16 == avctx->height) || (avctx->width == 1920 && avctx->height == 1080))
389  {
390  res = AMF_OK;
391  }
392  else
393  {
394  res = AMF_NOT_SUPPORTED;
395  av_log(ctx, AV_LOG_ERROR, "Resolution incorrect for alignment mode\n");
396  return AVERROR_EXIT;
397  }
398  break;
399  case AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_NO_RESTRICTIONS:
400  res = AMF_OK;
401  break;
402  default:
403  res = AMF_NOT_SUPPORTED;
404  av_log(ctx, AV_LOG_ERROR, "Invalid alignment mode\n");
405  return AVERROR_EXIT;
406  }
407  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE, ctx->align);
408 
409  if (ctx->aq_mode != -1) {
410  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_AQ_MODE, ctx->aq_mode);
411  }
412 
413  if (ctx->latency != -1) {
414  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_ENCODING_LATENCY_MODE, ctx->latency);
415  }
416 
417  if (ctx->preanalysis != -1) {
418  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_PRE_ANALYSIS_ENABLE, !!((ctx->preanalysis == 0) ? false : true));
419  }
420 
421  res = ctx->encoder->pVtbl->GetProperty(ctx->encoder, AMF_VIDEO_ENCODER_AV1_PRE_ANALYSIS_ENABLE, &var);
422  if ((int)var.int64Value)
423  {
424  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_PRE_ANALYSIS_ENABLE, true);
425 
426  if (ctx->pa_activity_type != -1) {
427  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_PA_ACTIVITY_TYPE, ctx->pa_activity_type);
428  }
429  if (ctx->pa_scene_change_detection != -1) {
430  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_PA_SCENE_CHANGE_DETECTION_ENABLE, ((ctx->pa_scene_change_detection == 0) ? false : true));
431  }
432  if (ctx->pa_scene_change_detection_sensitivity != -1) {
433  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_PA_SCENE_CHANGE_DETECTION_SENSITIVITY, ctx->pa_scene_change_detection_sensitivity);
434  }
435  if (ctx->pa_static_scene_detection != -1) {
436  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_PA_STATIC_SCENE_DETECTION_ENABLE, ((ctx->pa_static_scene_detection == 0) ? false : true));
437  }
438  if (ctx->pa_static_scene_detection_sensitivity != -1) {
439  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_PA_STATIC_SCENE_DETECTION_SENSITIVITY, ctx->pa_static_scene_detection_sensitivity);
440  }
441  if (ctx->pa_initial_qp != -1) {
442  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_PA_INITIAL_QP_AFTER_SCENE_CHANGE, ctx->pa_initial_qp);
443  }
444  if (ctx->pa_max_qp != -1) {
445  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_PA_MAX_QP_BEFORE_FORCE_SKIP, ctx->pa_max_qp);
446  }
447  if (ctx->pa_caq_strength != -1) {
448  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_PA_CAQ_STRENGTH, ctx->pa_caq_strength);
449  }
450  if (ctx->pa_frame_sad != -1) {
451  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_PA_FRAME_SAD_ENABLE, ((ctx->pa_frame_sad == 0) ? false : true));
452  }
453  if (ctx->pa_paq_mode != -1) {
454  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_PA_PAQ_MODE, ctx->pa_paq_mode);
455  }
456  if (ctx->pa_taq_mode != -1) {
457  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_PA_TAQ_MODE, ctx->pa_taq_mode);
458  }
459  if (ctx->pa_ltr != -1) {
460  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_PA_LTR_ENABLE, ((ctx->pa_ltr == 0) ? false : true));
461  }
462  if (ctx->pa_lookahead_buffer_depth != -1) {
463  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_PA_LOOKAHEAD_BUFFER_DEPTH, ctx->pa_lookahead_buffer_depth);
464  }
465  if (ctx->pa_high_motion_quality_boost_mode != -1) {
466  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_PA_HIGH_MOTION_QUALITY_BOOST_MODE, ctx->pa_high_motion_quality_boost_mode);
467  }
468  }
469 
470  // init encoder
471  res = ctx->encoder->pVtbl->Init(ctx->encoder, ctx->format, avctx->width, avctx->height);
472  AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG, "encoder->Init() failed with error %d\n", res);
473 
474  // init dynamic picture control params
475  if (ctx->min_qp_i != -1) {
476  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_MIN_Q_INDEX_INTRA, ctx->min_qp_i);
477  }
478  else if (avctx->qmin != -1) {
479  int qval = avctx->qmin > 255 ? 255 : avctx->qmin;
480  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_MIN_Q_INDEX_INTRA, qval);
481  }
482  if (ctx->max_qp_i != -1) {
483  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_MAX_Q_INDEX_INTRA, ctx->max_qp_i);
484  }
485  else if (avctx->qmax != -1) {
486  int qval = avctx->qmax > 255 ? 255 : avctx->qmax;
487  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_MAX_Q_INDEX_INTRA, qval);
488  }
489  if (ctx->min_qp_p != -1) {
490  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_MIN_Q_INDEX_INTER, ctx->min_qp_p);
491  }
492  else if (avctx->qmin != -1) {
493  int qval = avctx->qmin > 255 ? 255 : avctx->qmin;
494  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_MIN_Q_INDEX_INTER, qval);
495  }
496  if (ctx->max_qp_p != -1) {
497  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_MAX_Q_INDEX_INTER, ctx->max_qp_p);
498  }
499  else if (avctx->qmax != -1) {
500  int qval = avctx->qmax > 255 ? 255 : avctx->qmax;
501  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_MAX_Q_INDEX_INTER, qval);
502  }
503 
504  if (ctx->qp_p != -1) {
505  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_Q_INDEX_INTER, ctx->qp_p);
506  }
507  if (ctx->qp_i != -1) {
508  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_Q_INDEX_INTRA, ctx->qp_i);
509  }
510 
511  if (ctx->skip_frame != -1) {
512  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_SKIP_FRAME, ((ctx->skip_frame == 0) ? false : true));
513  }
514 
515  // fill extradata
516  res = AMFVariantInit(&var);
517  AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG, "AMFVariantInit() failed with error %d\n", res);
518 
519  res = ctx->encoder->pVtbl->GetProperty(ctx->encoder, AMF_VIDEO_ENCODER_AV1_EXTRA_DATA, &var);
520  AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG, "GetProperty(AMF_VIDEO_ENCODER_EXTRADATA) failed with error %d\n", res);
521  AMF_RETURN_IF_FALSE(ctx, var.pInterface != NULL, AVERROR_BUG, "GetProperty(AMF_VIDEO_ENCODER_EXTRADATA) returned NULL\n");
522 
523  guid = IID_AMFBuffer();
524 
525  res = var.pInterface->pVtbl->QueryInterface(var.pInterface, &guid, (void**)&buffer); // query for buffer interface
526  if (res != AMF_OK) {
527  var.pInterface->pVtbl->Release(var.pInterface);
528  }
529  AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG, "QueryInterface(IID_AMFBuffer) failed with error %d\n", res);
530 
531  avctx->extradata_size = (int)buffer->pVtbl->GetSize(buffer);
533  if (!avctx->extradata) {
534  buffer->pVtbl->Release(buffer);
535  var.pInterface->pVtbl->Release(var.pInterface);
536  return AVERROR(ENOMEM);
537  }
538  memcpy(avctx->extradata, buffer->pVtbl->GetNative(buffer), avctx->extradata_size);
539 
540  buffer->pVtbl->Release(buffer);
541  var.pInterface->pVtbl->Release(var.pInterface);
542 
543  //processing crop informaiton according to alignment
544  if (ctx->encoder->pVtbl->GetProperty(ctx->encoder, AMF_VIDEO_ENCODER_AV1_CAP_WIDTH_ALIGNMENT_FACTOR_LOCAL, &var) != AMF_OK)
545  // assume older driver and Navi3x
546  width_alignment_factor = 64;
547  else
548  width_alignment_factor = (int)var.int64Value;
549 
550  if (ctx->encoder->pVtbl->GetProperty(ctx->encoder, AMF_VIDEO_ENCODER_AV1_CAP_HEIGHT_ALIGNMENT_FACTOR_LOCAL, &var) != AMF_OK)
551  // assume older driver and Navi3x
552  height_alignment_factor = 16;
553  else
554  height_alignment_factor = (int)var.int64Value;
555 
556  if (width_alignment_factor != -1 && height_alignment_factor != -1) {
557  if (avctx->width % width_alignment_factor != 0)
558  crop_right = width_alignment_factor - (avctx->width & (width_alignment_factor - 1));
559 
560  if (avctx->height % height_alignment_factor != 0)
561  crop_bottom = height_alignment_factor - (avctx->height & (height_alignment_factor - 1));
562 
563  // There is special processing for crop_bottom equal to 8 in hardware
564  if (crop_bottom == 8)
565  crop_bottom = 2;
566  }
567 
568  if (crop_right != 0 || crop_bottom != 0) {
569  AVPacketSideData* sd_crop = av_realloc_array(avctx->coded_side_data, avctx->nb_coded_side_data + 1, sizeof(*sd_crop));
570  uint32_t* crop;
571 
572  if (!sd_crop) {
573  av_log(ctx, AV_LOG_ERROR, "Can't allocate memory for amf av1 encoder crop information\n");
574  return AVERROR(ENOMEM);
575  }
576  avctx->coded_side_data = sd_crop;
577 
578  crop = av_malloc(sizeof(uint32_t) * 4);
579  if (!crop) {
580  av_log(ctx, AV_LOG_ERROR, "Can't allocate memory for amf av1 encoder crop information\n");
581  return AVERROR(ENOMEM);
582  }
583 
584  avctx->nb_coded_side_data++;
585 
586  //top, bottom, left,right
587  AV_WL32A(crop + 0, 0);
588  AV_WL32A(crop + 1, crop_bottom);
589  AV_WL32A(crop + 2, 0);
590  AV_WL32A(crop + 3, crop_right);
591 
593  avctx->coded_side_data[avctx->nb_coded_side_data - 1].data = (uint8_t*)crop;
594  avctx->coded_side_data[avctx->nb_coded_side_data - 1].size = sizeof(uint32_t) * 4;
595  }
596 
597  return 0;
598 }
599 
600 static const FFCodecDefault defaults[] = {
601  { "refs", "-1" },
602  { "aspect", "0" },
603  { "b", "0" },
604  { "g", "-1" },
605  { "qmin", "-1" },
606  { "qmax", "-1" },
607  { NULL },
608 };
609 
610 static const AVClass av1_amf_class = {
611  .class_name = "av1_amf",
612  .item_name = av_default_item_name,
613  .option = options,
614  .version = LIBAVUTIL_VERSION_INT,
615 };
616 
618  .p.name = "av1_amf",
619  CODEC_LONG_NAME("AMD AMF AV1 encoder"),
620  .p.type = AVMEDIA_TYPE_VIDEO,
621  .p.id = AV_CODEC_ID_AV1,
622  .init = amf_encode_init_av1,
624  .close = ff_amf_encode_close,
625  .priv_data_size = sizeof(AmfContext),
626  .p.priv_class = &av1_amf_class,
627  .defaults = defaults,
628  .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
630  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
631  .p.pix_fmts = ff_amf_pix_fmts,
632  .color_ranges = AVCOL_RANGE_MPEG, /* FIXME: implement tagging */
633  .p.wrapper_name = "amf",
634  .hw_configs = ff_amfenc_hw_configs,
635 };
OFFSET
#define OFFSET(x)
Definition: amfenc_av1.c:29
FF_ENABLE_DEPRECATION_WARNINGS
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:73
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
level
uint8_t level
Definition: svq3.c:205
FF_CODEC_CAP_INIT_CLEANUP
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: codec_internal.h:43
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
defaults
static const FFCodecDefault defaults[]
Definition: amfenc_av1.c:600
AV_PKT_DATA_FRAME_CROPPING
@ AV_PKT_DATA_FRAME_CROPPING
The number of pixels to discard from the top/bottom/left/right border of the decoded frame to obtain ...
Definition: packet.h:340
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
AV_CODEC_CAP_HARDWARE
#define AV_CODEC_CAP_HARDWARE
Codec is backed by a hardware implementation.
Definition: codec.h:145
AVCodecContext::coded_side_data
AVPacketSideData * coded_side_data
Additional data associated with the entire coded stream.
Definition: avcodec.h:1920
AVPacketSideData
This structure stores auxiliary information for decoding, presenting, or otherwise processing the cod...
Definition: packet.h:390
AVOption
AVOption.
Definition: opt.h:429
FFCodec
Definition: codec_internal.h:127
AMF_VIDEO_ENCODER_AV1_CAP_HEIGHT_ALIGNMENT_FACTOR_LOCAL
#define AMF_VIDEO_ENCODER_AV1_CAP_HEIGHT_ALIGNMENT_FACTOR_LOCAL
Definition: amfenc_av1.c:27
AMF_RETURN_IF_FALSE
#define AMF_RETURN_IF_FALSE(avctx, exp, ret_value,...)
Error handling helper.
Definition: amfenc.h:181
AVCodecContext::qmax
int qmax
maximum quantizer
Definition: avcodec.h:1267
quality
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about quality
Definition: rate_distortion.txt:12
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
AVCodecContext::framerate
AVRational framerate
Definition: avcodec.h:560
AVPacketSideData::size
size_t size
Definition: packet.h:392
FFCodecDefault
Definition: codec_internal.h:97
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
ff_amf_encode_close
int av_cold ff_amf_encode_close(AVCodecContext *avctx)
Common encoder termination function.
Definition: amfenc.c:432
AVCodecContext::refs
int refs
number of reference frames
Definition: avcodec.h:715
ff_amf_encode_init
int ff_amf_encode_init(AVCodecContext *avctx)
Common encoder initization function.
Definition: amfenc.c:558
AVRational::num
int num
Numerator.
Definition: rational.h:59
options
static const AVOption options[]
Definition: amfenc_av1.c:31
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
AVCodecContext::rc_initial_buffer_occupancy
int rc_initial_buffer_occupancy
Number of bits which should be loaded into the rc buffer before decoding starts.
Definition: avcodec.h:1324
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:524
intreadwrite.h
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:217
pix_fmt
static enum AVPixelFormat pix_fmt
Definition: demux_decode.c:41
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
AVPacketSideData::data
uint8_t * data
Definition: packet.h:391
ctx
AVFormatContext * ctx
Definition: movenc.c:49
AVCodecContext::rc_max_rate
int64_t rc_max_rate
maximum bitrate
Definition: avcodec.h:1296
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:296
if
if(ret)
Definition: filter_design.txt:179
AVCodecContext::rc_buffer_size
int rc_buffer_size
decoder bitstream buffer size
Definition: avcodec.h:1281
amf_encode_init_av1
static av_cold int amf_encode_init_av1(AVCodecContext *avctx)
Definition: amfenc_av1.c:176
framerate
float framerate
Definition: av1_levels.c:29
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NULL
#define NULL
Definition: coverity.c:32
AV_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:280
AV_LEVEL_UNKNOWN
#define AV_LEVEL_UNKNOWN
Definition: defs.h:198
AVCodecContext::nb_coded_side_data
int nb_coded_side_data
Definition: avcodec.h:1921
FF_CODEC_RECEIVE_PACKET_CB
#define FF_CODEC_RECEIVE_PACKET_CB(func)
Definition: codec_internal.h:326
AVCodecContext::bit_rate
int64_t bit_rate
the average bitrate
Definition: avcodec.h:495
AVPacketSideData::type
enum AVPacketSideDataType type
Definition: packet.h:393
ff_amf_receive_packet
int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
Ecoding one frame - common function for all AMF encoders.
Definition: amfenc.c:643
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
AVCodecContext::level
int level
Encoding level descriptor.
Definition: avcodec.h:1788
usage
const char * usage
Definition: floatimg_cmp.c:60
AVCodecContext::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avcodec.h:544
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
AVCodecContext::gop_size
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
Definition: avcodec.h:1031
codec_internal.h
ff_amf_pix_fmts
enum AVPixelFormat ff_amf_pix_fmts[]
Supported formats.
Definition: amfenc.c:105
AV_WL32A
#define AV_WL32A(p, v)
Definition: intreadwrite.h:571
AMF_VIDEO_ENCODER_AV1_CAP_WIDTH_ALIGNMENT_FACTOR_LOCAL
#define AMF_VIDEO_ENCODER_AV1_CAP_WIDTH_ALIGNMENT_FACTOR_LOCAL
Definition: amfenc_av1.c:26
FF_API_TICKS_PER_FRAME
#define FF_API_TICKS_PER_FRAME
Definition: version_major.h:42
align
static const uint8_t *BS_FUNC() align(BSCTX *bc)
Skip bits to a byte boundary.
Definition: bitstream_template.h:411
AVCodecContext::extradata
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:523
internal.h
ff_amfenc_hw_configs
const AVCodecHWConfigInternal *const ff_amfenc_hw_configs[]
Definition: amfenc.c:916
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:194
profile
int profile
Definition: mxfenc.c:2228
AVCodecContext::height
int height
Definition: avcodec.h:618
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:657
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:669
AVCodecContext::hw_frames_ctx
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames.
Definition: avcodec.h:1479
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:115
ret
ret
Definition: filter_design.txt:187
AVClass::class_name
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:71
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
AVCodecContext
main external API structure.
Definition: avcodec.h:445
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
av1_amf_class
static const AVClass av1_amf_class
Definition: amfenc_av1.c:610
AVCodecContext::qmin
int qmin
minimum quantizer
Definition: avcodec.h:1260
AVRational::den
int den
Denominator.
Definition: rational.h:60
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1644
AVCodecContext::ticks_per_frame
attribute_deprecated int ticks_per_frame
For some codecs, the time base is closer to the field rate than the frame rate.
Definition: avcodec.h:576
AV_CODEC_CAP_DELAY
#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: codec.h:76
amfenc.h
AV_PIX_FMT_P010
#define AV_PIX_FMT_P010
Definition: pixfmt.h:528
FF_DISABLE_DEPRECATION_WARNINGS
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:72
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
mem.h
ff_amf_get_color_profile
int ff_amf_get_color_profile(AVCodecContext *avctx)
Definition: amfenc.c:881
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:472
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:618
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AmfContext
AMF encoder context.
Definition: amfenc.h:50
VE
#define VE
Definition: amfenc_av1.c:30
AVERROR_EXIT
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition: error.h:58
AV_PROFILE_AV1_MAIN
#define AV_PROFILE_AV1_MAIN
Definition: defs.h:169
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
ff_av1_amf_encoder
const FFCodec ff_av1_amf_encoder
Definition: amfenc_av1.c:617
MAX_LOOKAHEAD_DEPTH
#define MAX_LOOKAHEAD_DEPTH
Definition: amfenc.h:34