FFmpeg
amfenc_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 
21 #include "libavutil/internal.h"
22 #include "libavutil/mem.h"
23 #include "libavutil/opt.h"
24 #include "amfenc.h"
25 #include "codec_internal.h"
26 #include <AMF/components/PreAnalysis.h>
27 
28 #define OFFSET(x) offsetof(AMFEncoderContext, x)
29 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
30 
31 static const AVOption options[] = {
32  // Static
33  /// Usage
34  { "usage", "Encoder Usage", OFFSET(usage), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY_HIGH_QUALITY, VE, .unit = "usage" },
35  { "transcoding", "Generic Transcoding", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_TRANSCODING }, 0, 0, VE, .unit = "usage" },
36  { "ultralowlatency","Ultra low latency usecase", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_ULTRA_LOW_LATENCY }, 0, 0, VE, .unit = "usage" },
37  { "lowlatency", "Low latency usecase", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY }, 0, 0, VE, .unit = "usage" },
38  { "webcam", "Webcam", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_WEBCAM }, 0, 0, VE, .unit = "usage" },
39  { "high_quality", "High quality usecase", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_HIGH_QUALITY }, 0, 0, VE, .unit = "usage" },
40  { "lowlatency_high_quality", "Low latency yet high quality usecase", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY_HIGH_QUALITY }, 0, 0, VE, .unit = "usage" },
41 
42  /// Profile,
43  { "profile", "Profile", OFFSET(profile),AV_OPT_TYPE_INT, { .i64 = -1 }, -1, AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_HIGH, VE, .unit = "profile" },
44  { "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_MAIN }, 0, 0, VE, .unit = "profile" },
45  { "high", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_HIGH }, 0, 0, VE, .unit = "profile" },
46  { "constrained_baseline", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_BASELINE }, 0, 0, VE, .unit = "profile" },
47  { "constrained_high", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_HIGH }, 0, 0, VE, .unit = "profile" },
48 
49  /// Profile Level
50  { "level", "Profile Level", OFFSET(level), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 62, VE, .unit = "level" },
51  { "auto", "", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, VE, .unit = "level" },
52  { "1.0", "", 0, AV_OPT_TYPE_CONST, { .i64 = 10 }, 0, 0, VE, .unit = "level" },
53  { "1.1", "", 0, AV_OPT_TYPE_CONST, { .i64 = 11 }, 0, 0, VE, .unit = "level" },
54  { "1.2", "", 0, AV_OPT_TYPE_CONST, { .i64 = 12 }, 0, 0, VE, .unit = "level" },
55  { "1.3", "", 0, AV_OPT_TYPE_CONST, { .i64 = 13 }, 0, 0, VE, .unit = "level" },
56  { "2.0", "", 0, AV_OPT_TYPE_CONST, { .i64 = 20 }, 0, 0, VE, .unit = "level" },
57  { "2.1", "", 0, AV_OPT_TYPE_CONST, { .i64 = 21 }, 0, 0, VE, .unit = "level" },
58  { "2.2", "", 0, AV_OPT_TYPE_CONST, { .i64 = 22 }, 0, 0, VE, .unit = "level" },
59  { "3.0", "", 0, AV_OPT_TYPE_CONST, { .i64 = 30 }, 0, 0, VE, .unit = "level" },
60  { "3.1", "", 0, AV_OPT_TYPE_CONST, { .i64 = 31 }, 0, 0, VE, .unit = "level" },
61  { "3.2", "", 0, AV_OPT_TYPE_CONST, { .i64 = 32 }, 0, 0, VE, .unit = "level" },
62  { "4.0", "", 0, AV_OPT_TYPE_CONST, { .i64 = 40 }, 0, 0, VE, .unit = "level" },
63  { "4.1", "", 0, AV_OPT_TYPE_CONST, { .i64 = 41 }, 0, 0, VE, .unit = "level" },
64  { "4.2", "", 0, AV_OPT_TYPE_CONST, { .i64 = 42 }, 0, 0, VE, .unit = "level" },
65  { "5.0", "", 0, AV_OPT_TYPE_CONST, { .i64 = 50 }, 0, 0, VE, .unit = "level" },
66  { "5.1", "", 0, AV_OPT_TYPE_CONST, { .i64 = 51 }, 0, 0, VE, .unit = "level" },
67  { "5.2", "", 0, AV_OPT_TYPE_CONST, { .i64 = 52 }, 0, 0, VE, .unit = "level" },
68  { "6.0", "", 0, AV_OPT_TYPE_CONST, { .i64 = 60 }, 0, 0, VE, .unit = "level" },
69  { "6.1", "", 0, AV_OPT_TYPE_CONST, { .i64 = 61 }, 0, 0, VE, .unit = "level" },
70  { "6.2", "", 0, AV_OPT_TYPE_CONST, { .i64 = 62 }, 0, 0, VE, .unit = "level" },
71 
72  { "latency", "enables low latency mode", OFFSET(latency), AV_OPT_TYPE_BOOL, {.i64 = -1 }, -1, 1, VE },
73 
74  /// Quality Preset
75  { "quality", "Set the encoding quality preset", OFFSET(quality), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, AMF_VIDEO_ENCODER_QUALITY_PRESET_QUALITY, VE, .unit = "quality" },
76  { "preset", "Set the encoding quality preset", OFFSET(quality), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, AMF_VIDEO_ENCODER_QUALITY_PRESET_QUALITY, VE, .unit = "quality" },
77  { "balanced", "Balanced", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_QUALITY_PRESET_BALANCED }, 0, 0, VE, .unit = "quality" },
78  { "speed", "Prefer Speed", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_QUALITY_PRESET_SPEED }, 0, 0, VE, .unit = "quality" },
79  { "quality", "Prefer Quality", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_QUALITY_PRESET_QUALITY }, 0, 0, VE, .unit = "quality" },
80 
81  // Dynamic
82  /// Rate Control Method
83  { "rc", "Rate Control Method", OFFSET(rate_control_mode), AV_OPT_TYPE_INT, { .i64 = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_UNKNOWN }, AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_UNKNOWN, AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_HIGH_QUALITY_CBR, VE, .unit = "rc" },
84  { "cqp", "Constant Quantization Parameter", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP }, 0, 0, VE, .unit = "rc" },
85  { "cbr", "Constant Bitrate", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR }, 0, 0, VE, .unit = "rc" },
86  { "vbr_peak", "Peak Constrained Variable Bitrate", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR }, 0, 0, VE, .unit = "rc" },
87  { "vbr_latency", "Latency Constrained Variable Bitrate", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR }, 0, 0, VE, .unit = "rc" },
88  { "qvbr", "Quality Variable Bitrate", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_QUALITY_VBR }, 0, 0, VE, .unit = "rc" },
89  { "hqvbr", "High Quality Variable Bitrate", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_HIGH_QUALITY_VBR }, 0, 0, VE, .unit = "rc" },
90  { "hqcbr", "High Quality Constant Bitrate", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_HIGH_QUALITY_CBR }, 0, 0, VE, .unit = "rc" },
91 
92  { "qvbr_quality_level", "Sets the QVBR quality level", OFFSET(qvbr_quality_level),AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE },
93 
94  /// Enforce HRD, Filler Data, VBAQ, Frame Skipping
95  { "enforce_hrd", "Enforce HRD", OFFSET(enforce_hrd), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE },
96  { "filler_data", "Filler Data Enable", OFFSET(filler_data), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE },
97  { "vbaq", "Enable VBAQ", OFFSET(enable_vbaq), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE },
98  { "frame_skipping", "Rate Control Based Frame Skip", OFFSET(skip_frame), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE },
99 
100  /// QP Values
101  { "qp_i", "Quantization Parameter for I-Frame", OFFSET(qp_i), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE },
102  { "qp_p", "Quantization Parameter for P-Frame", OFFSET(qp_p), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE },
103  { "qp_b", "Quantization Parameter for B-Frame", OFFSET(qp_b), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE },
104 
105  /// Pre-Pass, Pre-Analysis, Two-Pass
106  { "preencode", "Pre-encode assisted rate control", OFFSET(preencode), AV_OPT_TYPE_BOOL,{ .i64 = -1 }, -1, 1, VE, NULL },
107 
108  /// Maximum Access Unit Size
109  { "max_au_size", "Maximum Access Unit Size for rate control (in bits)", OFFSET(max_au_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE },
110 
111  /// Header Insertion Spacing
112  { "header_spacing", "Header Insertion Spacing", OFFSET(header_spacing), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1000, VE },
113 
114  /// Maximum queued frames
115  { "async_depth", "Set maximum encoding parallelism. Higher values increase output latency.", OFFSET(hwsurfaces_in_queue_max), AV_OPT_TYPE_INT, {.i64 = 16 }, 1, MAX_LOOKAHEAD_DEPTH + 1, VE },
116 
117  /// B-Frames
118  // BPicturesPattern=bf
119  { "bf_delta_qp", "B-Picture Delta QP", OFFSET(b_frame_delta_qp), AV_OPT_TYPE_INT, { .i64 = 4 }, -10, 10, VE },
120  { "bf_ref", "Enable Reference to B-Frames", OFFSET(b_frame_ref), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE },
121  { "bf_ref_delta_qp","Reference B-Picture Delta QP", OFFSET(ref_b_frame_delta_qp), AV_OPT_TYPE_INT, { .i64 = 4 }, -10, 10, VE },
122 
123  { "max_b_frames", "Maximum number of consecutive B Pictures", OFFSET(max_consecutive_b_frames), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 3, VE },
124  { "bf", "B Picture Pattern", OFFSET(max_b_frames), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 3, VE },
125 
126  /// Intra-Refresh
127  { "intra_refresh_mb","Intra Refresh MBs Number Per Slot in Macroblocks", OFFSET(intra_refresh_mb), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE },
128 
129  /// coder
130  { "coder", "Coding Type", OFFSET(coding_mode), AV_OPT_TYPE_INT, { .i64 = AMF_VIDEO_ENCODER_UNDEFINED }, AMF_VIDEO_ENCODER_UNDEFINED, AMF_VIDEO_ENCODER_CALV, VE, .unit = "coder" },
131  { "auto", "Automatic", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_UNDEFINED }, 0, 0, VE, .unit = "coder" },
132  { "cavlc", "Context Adaptive Variable-Length Coding", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_CALV }, 0, 0, VE, .unit = "coder" },
133  { "cabac", "Context Adaptive Binary Arithmetic Coding", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_CABAC }, 0, 0, VE, .unit = "coder" },
134 
135  { "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 },
136 
137  { "me_half_pel", "Enable ME Half Pixel", OFFSET(me_half_pel), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE },
138  { "me_quarter_pel", "Enable ME Quarter Pixel", OFFSET(me_quarter_pel),AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE },
139 
140  { "forced_idr", "Force I frames to be IDR frames", OFFSET(forced_idr) , AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
141  { "aud", "Inserts AU Delimiter NAL unit", OFFSET(aud) , AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE },
142 
143  { "smart_access_video", "Enable Smart Access Video to enhance performance by utilizing both APU and dGPU memory access", OFFSET(smart_access_video), AV_OPT_TYPE_BOOL, {.i64 = -1 }, -1, 1, VE},
144 
145  //Pre Analysis options
146  { "preanalysis", "Enable preanalysis", OFFSET(preanalysis), AV_OPT_TYPE_BOOL, {.i64 = -1 }, -1, 1, VE },
147 
148  { "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" },
149  { "y", "activity y", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_ACTIVITY_Y }, 0, 0, VE, .unit = "activity_type" },
150  { "yuv", "activity yuv", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_ACTIVITY_YUV }, 0, 0, VE, .unit = "activity_type" },
151 
152  { "pa_scene_change_detection_enable", "Enable scene change detection", OFFSET(pa_scene_change_detection), AV_OPT_TYPE_BOOL, {.i64 = -1 }, -1, 1, VE },
153 
154  { "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" },
155  { "low", "low scene change detection sensitivity", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_SCENE_CHANGE_DETECTION_SENSITIVITY_LOW }, 0, 0, VE, .unit = "scene_change_sensitivity" },
156  { "medium", "medium scene change detection sensitivity", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_SCENE_CHANGE_DETECTION_SENSITIVITY_MEDIUM }, 0, 0, VE, .unit = "scene_change_sensitivity" },
157  { "high", "high scene change detection sensitivity", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_SCENE_CHANGE_DETECTION_SENSITIVITY_HIGH }, 0, 0, VE, .unit = "scene_change_sensitivity" },
158 
159  { "pa_static_scene_detection_enable", "Enable static scene detection", OFFSET(pa_static_scene_detection), AV_OPT_TYPE_BOOL, {.i64 = -1 }, -1, 1, VE },
160 
161  { "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" },
162  { "low", "low static scene detection sensitivity", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_STATIC_SCENE_DETECTION_SENSITIVITY_LOW }, 0, 0, VE, .unit = "static_scene_sensitivity" },
163  { "medium", "medium static scene detection sensitivity", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_STATIC_SCENE_DETECTION_SENSITIVITY_MEDIUM }, 0, 0, VE, .unit = "static_scene_sensitivity" },
164  { "high", "high static scene detection sensitivity", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_STATIC_SCENE_DETECTION_SENSITIVITY_HIGH }, 0, 0, VE, .unit = "static_scene_sensitivity" },
165 
166  { "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 },
167  { "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 },
168 
169  { "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" },
170  { "low", "low Content Adaptive Quantization strength", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_CAQ_STRENGTH_LOW }, 0, 0, VE, .unit = "caq_strength" },
171  { "medium", "medium Content Adaptive Quantization strength", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_CAQ_STRENGTH_MEDIUM }, 0, 0, VE, .unit = "caq_strength" },
172  { "high", "high Content Adaptive Quantization strength", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_CAQ_STRENGTH_HIGH }, 0, 0, VE, .unit = "caq_strength" },
173 
174  { "pa_frame_sad_enable", "Enable Frame SAD algorithm", OFFSET(pa_frame_sad), AV_OPT_TYPE_BOOL, {.i64 = -1 }, -1, 1, VE },
175  { "pa_ltr_enable", "Enable long term reference frame management", OFFSET(pa_ltr), AV_OPT_TYPE_BOOL, {.i64 = -1 }, -1, 1, VE },
176  { "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 },
177 
178  { "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" },
179  { "none", "no perceptual adaptive quantization", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_PAQ_MODE_NONE }, 0, 0, VE, .unit = "paq_mode" },
180  { "caq", "caq perceptual adaptive quantization", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_PAQ_MODE_CAQ }, 0, 0, VE, .unit = "paq_mode" },
181 
182  { "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" },
183  { "none", "no temporal adaptive quantization", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_TAQ_MODE_NONE }, 0, 0, VE, .unit = "taq_mode" },
184  { "1", "temporal adaptive quantization mode 1", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_TAQ_MODE_1 }, 0, 0, VE, .unit = "taq_mode" },
185  { "2", "temporal adaptive quantization mode 2", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_TAQ_MODE_2 }, 0, 0, VE, .unit = "taq_mode" },
186 
187  { "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" },
188  { "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" },
189  { "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" },
190 
191  { "pa_adaptive_mini_gop", "Enable Adaptive MiniGOP", OFFSET(pa_adaptive_mini_gop), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE },
192  { NULL }
193 };
194 
196 {
197  int ret = 0;
198  AMF_RESULT res = AMF_OK;
199  AMFEncoderContext *ctx = avctx->priv_data;
200  AMFVariantStruct var = { 0 };
201  amf_int64 profile = 0;
202  amf_int64 profile_level = 0;
203  AMFBuffer *buffer;
204  AMFGuid guid;
205  AMFRate framerate;
206  AMFSize framesize = AMFConstructSize(avctx->width, avctx->height);
207  int deblocking_filter = (avctx->flags & AV_CODEC_FLAG_LOOP_FILTER) ? 1 : 0;
208  amf_int64 color_profile;
209  enum AVPixelFormat pix_fmt;
210 
211  if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
212  framerate = AMFConstructRate(avctx->framerate.num, avctx->framerate.den);
213  } else {
214  framerate = AMFConstructRate(avctx->time_base.den, avctx->time_base.num);
215  }
216 
217  if ((ret = ff_amf_encode_init(avctx)) != 0)
218  return ret;
219 
220  // init static parameters
221  if (ctx->usage != -1) {
222  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_USAGE, ctx->usage);
223  }
224 
225  AMF_ASSIGN_PROPERTY_SIZE(res, ctx->encoder, AMF_VIDEO_ENCODER_FRAMESIZE, framesize);
226 
227  AMF_ASSIGN_PROPERTY_RATE(res, ctx->encoder, AMF_VIDEO_ENCODER_FRAMERATE, framerate);
228 
229  switch (avctx->profile) {
231  profile = AMF_VIDEO_ENCODER_PROFILE_BASELINE;
232  break;
234  profile = AMF_VIDEO_ENCODER_PROFILE_MAIN;
235  break;
237  profile = AMF_VIDEO_ENCODER_PROFILE_HIGH;
238  break;
240  profile = AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_BASELINE;
241  break;
243  profile = AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_HIGH;
244  break;
245  }
246  if (profile == 0) {
247  if (ctx->profile != -1) {
248  profile = ctx->profile;
249  }
250  }
251 
252  if (profile != 0) {
253  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_PROFILE, profile);
254  }
255 
256  profile_level = avctx->level;
257  if (profile_level == AV_LEVEL_UNKNOWN) {
258  profile_level = ctx->level;
259  }
260 
261  if (profile_level != 0) {
262  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_PROFILE_LEVEL, profile_level);
263  }
264 
265  // Maximum Reference Frames
266  if (avctx->refs != -1) {
267  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_MAX_NUM_REFRAMES, avctx->refs);
268  }
269  if (avctx->sample_aspect_ratio.den && avctx->sample_aspect_ratio.num) {
270  AMFRatio ratio = AMFConstructRatio(avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den);
271  AMF_ASSIGN_PROPERTY_RATIO(res, ctx->encoder, AMF_VIDEO_ENCODER_ASPECT_RATIO, ratio);
272  }
273 
274  color_profile = av_amf_get_color_profile(avctx->color_range, avctx->colorspace);
275  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_OUTPUT_COLOR_PROFILE, color_profile);
276 
277  /// Color Range (Support for older Drivers)
278  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_FULL_RANGE_COLOR, !!(avctx->color_range == AVCOL_RANGE_JPEG));
279 
280  /// Color Depth
281  pix_fmt = avctx->hw_frames_ctx ? ((AVHWFramesContext*)avctx->hw_frames_ctx->data)->sw_format
282  : avctx->pix_fmt;
283 
284  // 10 bit input video is not supported by AMF H264 encoder
285  AMF_RETURN_IF_FALSE(ctx, pix_fmt != AV_PIX_FMT_P010, AVERROR_INVALIDDATA, "10-bit input video is not supported by AMF H264 encoder\n");
286 
287  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_COLOR_BIT_DEPTH, AMF_COLOR_BIT_DEPTH_8);
288  /// Color Transfer Characteristics (AMF matches ISO/IEC)
289  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_OUTPUT_TRANSFER_CHARACTERISTIC, (amf_int64)avctx->color_trc);
290  /// Color Primaries (AMF matches ISO/IEC)
291  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_OUTPUT_COLOR_PRIMARIES, (amf_int64)avctx->color_primaries);
292 
293  // autodetect rate control method
294  if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_UNKNOWN) {
295  if (ctx->qp_i != -1 || ctx->qp_p != -1 || ctx->qp_b != -1) {
296  ctx->rate_control_mode = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP;
297  av_log(ctx, AV_LOG_DEBUG, "Rate control turned to CQP\n");
298  } else if (avctx->bit_rate > 0 && avctx->rc_max_rate == avctx->bit_rate) {
299  ctx->rate_control_mode = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR;
300  av_log(ctx, AV_LOG_DEBUG, "Rate control turned to CBR\n");
301  } else {
302  ctx->rate_control_mode = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR;
303  av_log(ctx, AV_LOG_DEBUG, "Rate control turned to Peak VBR\n");
304  }
305  }
306 
307  if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP) {
308  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_PREENCODE_ENABLE, AMF_VIDEO_ENCODER_PREENCODE_DISABLED);
309  if (ctx->preencode != -1) {
310  if (ctx->preencode) {
311  av_log(ctx, AV_LOG_WARNING, "Preencode is not supported by cqp Rate Control Method, automatically disabled\n");
312  }
313  }
314  }
315  else {
316  if (ctx->preencode != -1) {
317  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_PREENCODE_ENABLE, ctx->preencode);
318  }
319  }
320 
321  if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_QUALITY_VBR) {
322  if (ctx->qvbr_quality_level != -1) {
323  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_QVBR_QUALITY_LEVEL, ctx->qvbr_quality_level);
324  }
325  }
326 
327  if (ctx->hw_high_motion_quality_boost != -1) {
328  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HIGH_MOTION_QUALITY_BOOST_ENABLE, ((ctx->hw_high_motion_quality_boost == 0) ? false : true));
329  }
330 
331  if (ctx->quality != -1) {
332  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_QUALITY_PRESET, ctx->quality);
333  }
334 
335  // Dynamic parameters
336  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD, ctx->rate_control_mode);
337 
338  /// VBV Buffer
339  if (avctx->rc_buffer_size != 0) {
340  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_VBV_BUFFER_SIZE, avctx->rc_buffer_size);
341  if (avctx->rc_initial_buffer_occupancy != 0) {
342  int amf_buffer_fullness = avctx->rc_initial_buffer_occupancy * 64 / avctx->rc_buffer_size;
343  if (amf_buffer_fullness > 64)
344  amf_buffer_fullness = 64;
345  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_INITIAL_VBV_BUFFER_FULLNESS, amf_buffer_fullness);
346  }
347  }
348  /// Maximum Access Unit Size and AUD
349  if (ctx->max_au_size != -1) {
350  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_MAX_AU_SIZE, ctx->max_au_size);
351  }
352 
353  if (ctx->aud != -1) {
354  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_INSERT_AUD, ctx->aud);
355  }
356 
357  // QP Minimum / Maximum
358  if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP) {
359  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_MIN_QP, 0);
360  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_MAX_QP, 51);
361  } else {
362  if (avctx->qmin != -1) {
363  int qval = avctx->qmin > 51 ? 51 : avctx->qmin;
364  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_MIN_QP, qval);
365  }
366  if (avctx->qmax != -1) {
367  int qval = avctx->qmax > 51 ? 51 : avctx->qmax;
368  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_MAX_QP, qval);
369  }
370  }
371  // QP Values
372  if (ctx->qp_i != -1)
373  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_QP_I, ctx->qp_i);
374  if (ctx->qp_p != -1)
375  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_QP_P, ctx->qp_p);
376  if (ctx->qp_b != -1)
377  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_QP_B, ctx->qp_b);
378 
379  if (avctx->bit_rate) {
380  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_TARGET_BITRATE, avctx->bit_rate);
381  }
382 
383  if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR) {
384  if (avctx->bit_rate) {
385  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_PEAK_BITRATE, avctx->bit_rate);
386  }
387  }
388 
389  if (avctx->rc_max_rate) {
390  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_PEAK_BITRATE, avctx->rc_max_rate);
391  } else if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR) {
392  av_log(ctx, AV_LOG_DEBUG, "rate control mode is vbr_peak but max_rate is not set, default max_rate will be applied.\n");
393  }
394 
395  if (ctx->latency != -1) {
396  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_LOWLATENCY_MODE, ((ctx->latency == 0) ? false : true));
397  }
398 
399  if (ctx->smart_access_video != -1) {
400  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_ENABLE_SMART_ACCESS_VIDEO, ctx->smart_access_video != 0);
401  if (res != AMF_OK) {
402  av_log(avctx, AV_LOG_ERROR, "The Smart Access Video is not supported by AMF.\n");
403  if (ctx->smart_access_video != 0)
404  return AVERROR(ENOSYS);
405  } else {
406  av_log(avctx, AV_LOG_INFO, "The Smart Access Video (%d) is set.\n", ctx->smart_access_video);
407  // Set low latency mode if Smart Access Video is enabled
408  if (ctx->smart_access_video != 0) {
409  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_LOWLATENCY_MODE, true);
410  av_log(avctx, AV_LOG_INFO, "The Smart Access Video set low latency mode.\n");
411  }
412  }
413  }
414 
415  if (ctx->preanalysis != -1) {
416  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_PRE_ANALYSIS_ENABLE, !!((ctx->preanalysis == 0) ? false : true));
417  }
418 
419  res = ctx->encoder->pVtbl->GetProperty(ctx->encoder, AMF_VIDEO_ENCODER_PRE_ANALYSIS_ENABLE, &var);
420  if ((int)var.int64Value)
421  {
422  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_PRE_ANALYSIS_ENABLE, true);
423 
424  if (ctx->pa_activity_type != -1) {
425  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_PA_ACTIVITY_TYPE, ctx->pa_activity_type);
426  }
427  if (ctx->pa_scene_change_detection != -1) {
428  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_PA_SCENE_CHANGE_DETECTION_ENABLE, ((ctx->pa_scene_change_detection == 0) ? false : true));
429  }
430  if (ctx->pa_scene_change_detection_sensitivity != -1) {
431  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_PA_SCENE_CHANGE_DETECTION_SENSITIVITY, ctx->pa_scene_change_detection_sensitivity);
432  }
433  if (ctx->pa_static_scene_detection != -1) {
434  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_PA_STATIC_SCENE_DETECTION_ENABLE, ((ctx->pa_static_scene_detection == 0) ? false : true));
435  }
436  if (ctx->pa_static_scene_detection_sensitivity != -1) {
437  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_PA_STATIC_SCENE_DETECTION_SENSITIVITY, ctx->pa_static_scene_detection_sensitivity);
438  }
439  if (ctx->pa_initial_qp != -1) {
440  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_PA_INITIAL_QP_AFTER_SCENE_CHANGE, ctx->pa_initial_qp);
441  }
442  if (ctx->pa_max_qp != -1) {
443  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_PA_MAX_QP_BEFORE_FORCE_SKIP, ctx->pa_max_qp);
444  }
445  if (ctx->pa_caq_strength != -1) {
446  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_PA_CAQ_STRENGTH, ctx->pa_caq_strength);
447  }
448  if (ctx->pa_frame_sad != -1) {
449  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_PA_FRAME_SAD_ENABLE, ((ctx->pa_frame_sad == 0) ? false : true));
450  }
451  if (ctx->pa_paq_mode != -1) {
452  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_PA_PAQ_MODE, ctx->pa_paq_mode);
453  }
454  if (ctx->pa_taq_mode != -1) {
455  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_PA_TAQ_MODE, ctx->pa_taq_mode);
456  }
457  if (ctx->pa_adaptive_mini_gop != -1) {
458  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_ADAPTIVE_MINIGOP, ((ctx->pa_adaptive_mini_gop == 0) ? false : true));
459  }
460  if (ctx->pa_ltr != -1) {
461  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_PA_LTR_ENABLE, ((ctx->pa_ltr == 0) ? false : true));
462  }
463  if (ctx->pa_lookahead_buffer_depth != -1) {
464  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_PA_LOOKAHEAD_BUFFER_DEPTH, ctx->pa_lookahead_buffer_depth);
465  }
466  if (ctx->pa_high_motion_quality_boost_mode != -1) {
467  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_PA_HIGH_MOTION_QUALITY_BOOST_MODE, ctx->pa_high_motion_quality_boost_mode);
468  }
469  }
470 
471  // B-Frames
472  AMFVariantStruct is_adaptive_b_frames = { 0 };
473  res = ctx->encoder->pVtbl->GetProperty(ctx->encoder, AMF_VIDEO_ENCODER_ADAPTIVE_MINIGOP, &is_adaptive_b_frames);
474  if (ctx->max_consecutive_b_frames != -1 || ctx->max_b_frames != -1 || is_adaptive_b_frames.boolValue == true) {
475 
476  //Get the capability of encoder
477  AMFCaps *encoder_caps = NULL;
478  ctx->encoder->pVtbl->GetCaps(ctx->encoder, &encoder_caps);
479  if (encoder_caps != NULL)
480  {
481  res = encoder_caps->pVtbl->GetProperty(encoder_caps, AMF_VIDEO_ENCODER_CAP_BFRAMES, &var);
482  if (res == AMF_OK) {
483 
484  //encoder supports H.264 B-frame
485  if(var.boolValue == true){
486  //adaptive b-frames is higher priority than max_b_frames
487  if (is_adaptive_b_frames.boolValue == true)
488  {
489  //force AMF_VIDEO_ENCODER_MAX_CONSECUTIVE_BPICTURES to 3
490  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_MAX_CONSECUTIVE_BPICTURES, 3);
491 
492  if(ctx->pa_lookahead_buffer_depth < 1)
493  {
494  //force AMF_PA_LOOKAHEAD_BUFFER_DEPTH to 1 if not set or smaller than 1
495  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_PA_LOOKAHEAD_BUFFER_DEPTH, 1);
496  }
497  }
498  else {
499  if (ctx->max_b_frames != -1) {
500  //in case user sets B-frames
501  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_B_PIC_PATTERN, ctx->max_b_frames);
502  if (res != AMF_OK) {
503  res = ctx->encoder->pVtbl->GetProperty(ctx->encoder, AMF_VIDEO_ENCODER_B_PIC_PATTERN, &var);
504  av_log(ctx, AV_LOG_WARNING, "B-frames=%d is not supported by this GPU, switched to %d\n", ctx->max_b_frames, (int)var.int64Value);
505  ctx->max_b_frames = (int)var.int64Value;
506  }
507  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_MAX_CONSECUTIVE_BPICTURES, ctx->max_b_frames);
508  }
509  }
510 
511  }
512  //encoder doesn't support H.264 B-frame
513  else {
514  av_log(ctx, AV_LOG_WARNING, "The current GPU in use does not support H.264 B-frame encoding, there will be no B-frame in bitstream.\n");
515  }
516  } else {
517  //Can't get the capability of encoder
518  av_log(ctx, AV_LOG_WARNING, "Unable to get H.264 B-frame capability.\n");
519  av_log(ctx, AV_LOG_WARNING, "There will be no B-frame in bitstream.\n");
520  }
521 
522  encoder_caps->pVtbl->Release(encoder_caps);
523  encoder_caps = NULL;
524  }
525  }
526 
527  res = ctx->encoder->pVtbl->GetProperty(ctx->encoder, AMF_VIDEO_ENCODER_B_PIC_PATTERN, &var);
528  if ((int)var.int64Value) {
529  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_B_PIC_DELTA_QP, ctx->b_frame_delta_qp);
530  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_B_REFERENCE_ENABLE, !!ctx->b_frame_ref);
531  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_REF_B_PIC_DELTA_QP, ctx->ref_b_frame_delta_qp);
532  }
533 
534  if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP) {
535  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_ENABLE_VBAQ, 0);
536  if (ctx->enable_vbaq)
537  av_log(ctx, AV_LOG_WARNING, "VBAQ is not supported by cqp Rate Control Method, automatically disabled\n");
538  } else {
539  if (ctx->enable_vbaq != -1) {
540  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_ENABLE_VBAQ, !!ctx->enable_vbaq);
541  }
542  }
543 
544  // Wait inside QueryOutput() if supported by the driver
545  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_QUERY_TIMEOUT, 1);
546  res = ctx->encoder->pVtbl->GetProperty(ctx->encoder, AMF_VIDEO_ENCODER_QUERY_TIMEOUT, &var);
547  ctx->query_timeout_supported = res == AMF_OK && var.int64Value;
548 
549  // Initialize Encoder
550  res = ctx->encoder->pVtbl->Init(ctx->encoder, ctx->format, avctx->width, avctx->height);
551  AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG, "encoder->Init() failed with error %d\n", res);
552 
553  // Enforce HRD, Filler Data, VBAQ, Frame Skipping, Deblocking Filter
554  if (ctx->enforce_hrd != -1) {
555  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_ENFORCE_HRD, ((ctx->enforce_hrd == 0) ? false : true));
556  }
557 
558  if (ctx->filler_data != -1) {
559  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_FILLER_DATA_ENABLE, ((ctx->filler_data == 0) ? false : true));
560  }
561 
562  if (ctx->skip_frame != -1) {
563  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_RATE_CONTROL_SKIP_FRAME_ENABLE, ((ctx->skip_frame == 0) ? false : true));
564  }
565 
566  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_DE_BLOCKING_FILTER, !!deblocking_filter);
567 
568  // Keyframe Interval
569  if (avctx->gop_size != -1) {
570  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_IDR_PERIOD, avctx->gop_size);
571  }
572 
573  // Header Insertion Spacing
574  if (ctx->header_spacing >= 0)
575  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEADER_INSERTION_SPACING, ctx->header_spacing);
576 
577  // Intra-Refresh, Slicing
578  if (ctx->intra_refresh_mb != -1)
579  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_INTRA_REFRESH_NUM_MBS_PER_SLOT, ctx->intra_refresh_mb);
580  if (avctx->slices > 1)
581  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_SLICES_PER_FRAME, avctx->slices);
582 
583  // Coding
584  if (ctx->coding_mode != 0)
585  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_CABAC_ENABLE, ctx->coding_mode);
586 
587  // Motion Estimation
588  if (ctx->me_half_pel != -1) {
589  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_MOTION_HALF_PIXEL, !!ctx->me_half_pel);
590  }
591 
592  if (ctx->me_quarter_pel != -1) {
593  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_MOTION_QUARTERPIXEL, !!ctx->me_quarter_pel);
594  }
595 
596  // fill extradata
597  res = AMFVariantInit(&var);
598  AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG, "AMFVariantInit() failed with error %d\n", res);
599 
600  res = ctx->encoder->pVtbl->GetProperty(ctx->encoder, AMF_VIDEO_ENCODER_EXTRADATA, &var);
601  AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG, "GetProperty(AMF_VIDEO_ENCODER_EXTRADATA) failed with error %d\n", res);
602  AMF_RETURN_IF_FALSE(ctx, var.pInterface != NULL, AVERROR_BUG, "GetProperty(AMF_VIDEO_ENCODER_EXTRADATA) returned NULL\n");
603 
604  guid = IID_AMFBuffer();
605 
606  res = var.pInterface->pVtbl->QueryInterface(var.pInterface, &guid, (void**)&buffer); // query for buffer interface
607  if (res != AMF_OK) {
608  var.pInterface->pVtbl->Release(var.pInterface);
609  }
610  AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG, "QueryInterface(IID_AMFBuffer) failed with error %d\n", res);
611 
612  avctx->extradata_size = (int)buffer->pVtbl->GetSize(buffer);
614  if (!avctx->extradata) {
615  buffer->pVtbl->Release(buffer);
616  var.pInterface->pVtbl->Release(var.pInterface);
617  return AVERROR(ENOMEM);
618  }
619  memcpy(avctx->extradata, buffer->pVtbl->GetNative(buffer), avctx->extradata_size);
620 
621  buffer->pVtbl->Release(buffer);
622  var.pInterface->pVtbl->Release(var.pInterface);
623 
624  return 0;
625 }
626 
627 static const FFCodecDefault defaults[] = {
628  { "refs", "-1" },
629  { "aspect", "0" },
630  { "qmin", "-1" },
631  { "qmax", "-1" },
632  { "b", "0" },
633  { "g", "-1" },
634  { "slices", "1" },
635  { "flags", "+loop"},
636  { NULL },
637 };
638 
639 static const AVClass h264_amf_class = {
640  .class_name = "h264_amf",
641  .item_name = av_default_item_name,
642  .option = options,
643  .version = LIBAVUTIL_VERSION_INT,
644 };
645 
647  .p.name = "h264_amf",
648  CODEC_LONG_NAME("AMD AMF H.264 Encoder"),
649  .p.type = AVMEDIA_TYPE_VIDEO,
650  .p.id = AV_CODEC_ID_H264,
651  .init = amf_encode_init_h264,
653  .close = ff_amf_encode_close,
654  .priv_data_size = sizeof(AMFEncoderContext),
655  .p.priv_class = &h264_amf_class,
656  .defaults = defaults,
657  .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
659  .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
662  .color_ranges = AVCOL_RANGE_MPEG | AVCOL_RANGE_JPEG,
663  .p.wrapper_name = "amf",
664  .hw_configs = ff_amfenc_hw_configs,
665 };
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
level
uint8_t level
Definition: svq3.c:208
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:42
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
AVCodecContext::colorspace
enum AVColorSpace colorspace
YUV colorspace type.
Definition: avcodec.h:667
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:130
AV_PROFILE_H264_MAIN
#define AV_PROFILE_H264_MAIN
Definition: defs.h:112
AVCodecContext::color_trc
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition: avcodec.h:660
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:777
AVOption
AVOption.
Definition: opt.h:429
FF_CODEC_CAP_NOT_INIT_THREADSAFE
#define FF_CODEC_CAP_NOT_INIT_THREADSAFE
The codec is not known to be init-threadsafe (i.e.
Definition: codec_internal.h:34
FFCodec
Definition: codec_internal.h:127
AMF_RETURN_IF_FALSE
#define AMF_RETURN_IF_FALSE(avctx, exp, ret_value,...)
Error handling helper.
Definition: amfenc.h:169
AVCodecContext::qmax
int qmax
maximum quantizer
Definition: avcodec.h:1253
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
AVCodecContext::framerate
AVRational framerate
Definition: avcodec.h:559
FFCodecDefault
Definition: codec_internal.h:96
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:140
AVCodecContext::refs
int refs
number of reference frames
Definition: avcodec.h:697
ff_amf_encode_init
int ff_amf_encode_init(AVCodecContext *avctx)
Common encoder initization function.
Definition: amfenc.c:253
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:496
AV_CODEC_FLAG_LOOP_FILTER
#define AV_CODEC_FLAG_LOOP_FILTER
loop filter.
Definition: avcodec.h:298
AVRational::num
int num
Numerator.
Definition: rational.h:59
AVCodecContext::color_primaries
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition: avcodec.h:653
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
av_cold
#define av_cold
Definition: attributes.h:106
av_amf_get_color_profile
enum AMF_VIDEO_CONVERTER_COLOR_PROFILE_ENUM av_amf_get_color_profile(enum AVColorRange color_range, enum AVColorSpace color_space)
Definition: hwcontext_amf.c:155
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:1310
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:523
AMFEncoderContext
AMF encoder context.
Definition: amfenc.h:40
pix_fmt
static enum AVPixelFormat pix_fmt
Definition: demux_decode.c:41
h264_amf_class
static const AVClass h264_amf_class
Definition: amfenc_h264.c:639
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
hwcontext_amf.h
AVCodecContext::rc_max_rate
int64_t rc_max_rate
maximum bitrate
Definition: avcodec.h:1282
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:332
AVCodecContext::rc_buffer_size
int rc_buffer_size
decoder bitstream buffer size
Definition: avcodec.h:1267
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:76
NULL
#define NULL
Definition: coverity.c:32
AVCodecContext::color_range
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: avcodec.h:677
CODEC_PIXFMTS_ARRAY
#define CODEC_PIXFMTS_ARRAY(array)
Definition: codec_internal.h:393
AV_LEVEL_UNKNOWN
#define AV_LEVEL_UNKNOWN
Definition: defs.h:209
FF_CODEC_RECEIVE_PACKET_CB
#define FF_CODEC_RECEIVE_PACKET_CB(func)
Definition: codec_internal.h:367
AVCodecContext::bit_rate
int64_t bit_rate
the average bitrate
Definition: avcodec.h:489
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:547
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:242
amf_encode_init_h264
static av_cold int amf_encode_init_h264(AVCodecContext *avctx)
Definition: amfenc_h264.c:195
options
Definition: swscale.c:44
VE
#define VE
Definition: amfenc_h264.c:29
AVCodecContext::level
int level
Encoding level descriptor.
Definition: avcodec.h:1640
usage
const char * usage
Definition: floatimg_cmp.c:62
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:543
aud
static int FUNC() aud(CodedBitstreamContext *ctx, RWContext *rw, H264RawAUD *current)
Definition: cbs_h264_syntax_template.c:875
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
defaults
static const FFCodecDefault defaults[]
Definition: amfenc_h264.c:627
AVCodecContext::gop_size
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
Definition: avcodec.h:1017
codec_internal.h
ff_amf_pix_fmts
enum AVPixelFormat ff_amf_pix_fmts[]
Supported formats.
Definition: amfenc.c:55
OFFSET
#define OFFSET(x)
Definition: amfenc_h264.c:28
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
AVCodecContext::extradata
uint8_t * extradata
Out-of-band global headers that may be used by some codecs.
Definition: avcodec.h:522
internal.h
ff_amfenc_hw_configs
const AVCodecHWConfigInternal *const ff_amfenc_hw_configs[]
Definition: amfenc.c:682
ff_h264_amf_encoder
const FFCodec ff_h264_amf_encoder
Definition: amfenc_h264.c:646
options
static const AVOption options[]
Definition: amfenc_h264.c:31
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:179
profile
int profile
Definition: mxfenc.c:2297
AVCodecContext::height
int height
Definition: avcodec.h:600
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:639
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:760
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:1465
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:118
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:81
AV_PROFILE_H264_BASELINE
#define AV_PROFILE_H264_BASELINE
Definition: defs.h:110
AV_PROFILE_H264_CONSTRAINED
#define AV_PROFILE_H264_CONSTRAINED
Definition: defs.h:107
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
AVCodecContext
main external API structure.
Definition: avcodec.h:439
AV_PROFILE_H264_HIGH
#define AV_PROFILE_H264_HIGH
Definition: defs.h:114
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
AVCodecContext::qmin
int qmin
minimum quantizer
Definition: avcodec.h:1246
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:1630
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
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
AV_PROFILE_H264_CONSTRAINED_BASELINE
#define AV_PROFILE_H264_CONSTRAINED_BASELINE
Definition: defs.h:111
AV_PIX_FMT_P010
#define AV_PIX_FMT_P010
Definition: pixfmt.h:602
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
mem.h
AVCodecContext::slices
int slices
Number of slices.
Definition: avcodec.h:1033
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:466
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:600
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
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
MAX_LOOKAHEAD_DEPTH
#define MAX_LOOKAHEAD_DEPTH
Definition: amfenc.h:34
AVCodecContext::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown) That is the width of a pixel divided by the height of the pixel.
Definition: avcodec.h:624