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 
20 #include "libavutil/internal.h"
21 #include "libavutil/opt.h"
22 #include "amfenc.h"
23 #include "internal.h"
24 
25 #define OFFSET(x) offsetof(AmfContext, x)
26 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
27 
28 static const AVOption options[] = {
29  // Static
30  /// Usage
31  { "usage", "Encoder Usage", OFFSET(usage), AV_OPT_TYPE_INT, { .i64 = AMF_VIDEO_ENCODER_USAGE_TRANSCONDING }, AMF_VIDEO_ENCODER_USAGE_TRANSCONDING, AMF_VIDEO_ENCODER_USAGE_WEBCAM, VE, "usage" },
32  { "transcoding", "Generic Transcoding", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_TRANSCONDING }, 0, 0, VE, "usage" },
33  { "ultralowlatency","", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_ULTRA_LOW_LATENCY }, 0, 0, VE, "usage" },
34  { "lowlatency", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY }, 0, 0, VE, "usage" },
35  { "webcam", "Webcam", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_WEBCAM }, 0, 0, VE, "usage" },
36 
37  /// Profile,
38  { "profile", "Profile", OFFSET(profile),AV_OPT_TYPE_INT, { .i64 = AMF_VIDEO_ENCODER_PROFILE_MAIN }, AMF_VIDEO_ENCODER_PROFILE_BASELINE, AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_HIGH, VE, "profile" },
39  { "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_MAIN }, 0, 0, VE, "profile" },
40  { "high", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_HIGH }, 0, 0, VE, "profile" },
41  { "constrained_baseline", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_BASELINE }, 0, 0, VE, "profile" },
42  { "constrained_high", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_HIGH }, 0, 0, VE, "profile" },
43 
44  /// Profile Level
45  { "level", "Profile Level", OFFSET(level), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 62, VE, "level" },
46  { "auto", "", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, VE, "level" },
47  { "1.0", "", 0, AV_OPT_TYPE_CONST, { .i64 = 10 }, 0, 0, VE, "level" },
48  { "1.1", "", 0, AV_OPT_TYPE_CONST, { .i64 = 11 }, 0, 0, VE, "level" },
49  { "1.2", "", 0, AV_OPT_TYPE_CONST, { .i64 = 12 }, 0, 0, VE, "level" },
50  { "1.3", "", 0, AV_OPT_TYPE_CONST, { .i64 = 13 }, 0, 0, VE, "level" },
51  { "2.0", "", 0, AV_OPT_TYPE_CONST, { .i64 = 20 }, 0, 0, VE, "level" },
52  { "2.1", "", 0, AV_OPT_TYPE_CONST, { .i64 = 21 }, 0, 0, VE, "level" },
53  { "2.2", "", 0, AV_OPT_TYPE_CONST, { .i64 = 22 }, 0, 0, VE, "level" },
54  { "3.0", "", 0, AV_OPT_TYPE_CONST, { .i64 = 30 }, 0, 0, VE, "level" },
55  { "3.1", "", 0, AV_OPT_TYPE_CONST, { .i64 = 31 }, 0, 0, VE, "level" },
56  { "3.2", "", 0, AV_OPT_TYPE_CONST, { .i64 = 32 }, 0, 0, VE, "level" },
57  { "4.0", "", 0, AV_OPT_TYPE_CONST, { .i64 = 40 }, 0, 0, VE, "level" },
58  { "4.1", "", 0, AV_OPT_TYPE_CONST, { .i64 = 41 }, 0, 0, VE, "level" },
59  { "4.2", "", 0, AV_OPT_TYPE_CONST, { .i64 = 42 }, 0, 0, VE, "level" },
60  { "5.0", "", 0, AV_OPT_TYPE_CONST, { .i64 = 50 }, 0, 0, VE, "level" },
61  { "5.1", "", 0, AV_OPT_TYPE_CONST, { .i64 = 51 }, 0, 0, VE, "level" },
62  { "5.2", "", 0, AV_OPT_TYPE_CONST, { .i64 = 52 }, 0, 0, VE, "level" },
63  { "6.0", "", 0, AV_OPT_TYPE_CONST, { .i64 = 60 }, 0, 0, VE, "level" },
64  { "6.1", "", 0, AV_OPT_TYPE_CONST, { .i64 = 61 }, 0, 0, VE, "level" },
65  { "6.2", "", 0, AV_OPT_TYPE_CONST, { .i64 = 62 }, 0, 0, VE, "level" },
66 
67 
68  /// Quality Preset
69  { "quality", "Quality Preference", OFFSET(quality), AV_OPT_TYPE_INT, { .i64 = AMF_VIDEO_ENCODER_QUALITY_PRESET_SPEED }, AMF_VIDEO_ENCODER_QUALITY_PRESET_BALANCED, AMF_VIDEO_ENCODER_QUALITY_PRESET_QUALITY, VE, "quality" },
70  { "speed", "Prefer Speed", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_QUALITY_PRESET_SPEED }, 0, 0, VE, "quality" },
71  { "balanced", "Balanced", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_QUALITY_PRESET_BALANCED }, 0, 0, VE, "quality" },
72  { "quality", "Prefer Quality", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_QUALITY_PRESET_QUALITY }, 0, 0, VE, "quality" },
73 
74  // Dynamic
75  /// Rate Control Method
76  { "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_LATENCY_CONSTRAINED_VBR, VE, "rc" },
77  { "cqp", "Constant Quantization Parameter", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP }, 0, 0, VE, "rc" },
78  { "cbr", "Constant Bitrate", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR }, 0, 0, VE, "rc" },
79  { "vbr_peak", "Peak Contrained Variable Bitrate", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR }, 0, 0, VE, "rc" },
80  { "vbr_latency", "Latency Constrained Variable Bitrate", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR }, 0, 0, VE, "rc" },
81 
82  /// Enforce HRD, Filler Data, VBAQ, Frame Skipping
83  { "enforce_hrd", "Enforce HRD", OFFSET(enforce_hrd), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
84  { "filler_data", "Filler Data Enable", OFFSET(filler_data), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
85  { "vbaq", "Enable VBAQ", OFFSET(enable_vbaq), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
86  { "frame_skipping", "Rate Control Based Frame Skip", OFFSET(skip_frame), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
87 
88  /// QP Values
89  { "qp_i", "Quantization Parameter for I-Frame", OFFSET(qp_i), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE },
90  { "qp_p", "Quantization Parameter for P-Frame", OFFSET(qp_p), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE },
91  { "qp_b", "Quantization Parameter for B-Frame", OFFSET(qp_b), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE },
92 
93  /// Pre-Pass, Pre-Analysis, Two-Pass
94  { "preanalysis", "Pre-Analysis Mode", OFFSET(preanalysis), AV_OPT_TYPE_BOOL,{ .i64 = 0 }, 0, 1, VE, NULL },
95 
96  /// Maximum Access Unit Size
97  { "max_au_size", "Maximum Access Unit Size for rate control (in bits)", OFFSET(max_au_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
98 
99  /// Header Insertion Spacing
100  { "header_spacing", "Header Insertion Spacing", OFFSET(header_spacing), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1000, VE },
101 
102  /// B-Frames
103  // BPicturesPattern=bf
104  { "bf_delta_qp", "B-Picture Delta QP", OFFSET(b_frame_delta_qp), AV_OPT_TYPE_INT, { .i64 = 4 }, -10, 10, VE },
105  { "bf_ref", "Enable Reference to B-Frames", OFFSET(b_frame_ref), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE },
106  { "bf_ref_delta_qp","Reference B-Picture Delta QP", OFFSET(ref_b_frame_delta_qp), AV_OPT_TYPE_INT, { .i64 = 4 }, -10, 10, VE },
107 
108  /// Intra-Refresh
109  { "intra_refresh_mb","Intra Refresh MBs Number Per Slot in Macroblocks", OFFSET(intra_refresh_mb), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
110 
111  /// coder
112  { "coder", "Coding Type", OFFSET(coding_mode), AV_OPT_TYPE_INT, { .i64 = AMF_VIDEO_ENCODER_UNDEFINED }, AMF_VIDEO_ENCODER_UNDEFINED, AMF_VIDEO_ENCODER_CALV, VE, "coder" },
113  { "auto", "Automatic", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_UNDEFINED }, 0, 0, VE, "coder" },
114  { "cavlc", "Context Adaptive Variable-Length Coding", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_CALV }, 0, 0, VE, "coder" },
115  { "cabac", "Context Adaptive Binary Arithmetic Coding", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_CABAC }, 0, 0, VE, "coder" },
116 
117  { "me_half_pel", "Enable ME Half Pixel", OFFSET(me_half_pel), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE },
118  { "me_quarter_pel", "Enable ME Quarter Pixel", OFFSET(me_quarter_pel),AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE },
119 
120  { "aud", "Inserts AU Delimiter NAL unit", OFFSET(aud) ,AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
121 
122  { "log_to_dbg", "Enable AMF logging to debug output", OFFSET(log_to_dbg) , AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
123 
124  { NULL }
125 };
126 
128 {
129  int ret = 0;
130  AMF_RESULT res = AMF_OK;
131  AmfContext *ctx = avctx->priv_data;
132  AMFVariantStruct var = { 0 };
133  amf_int64 profile = 0;
134  amf_int64 profile_level = 0;
135  AMFBuffer *buffer;
136  AMFGuid guid;
137  AMFRate framerate;
138  AMFSize framesize = AMFConstructSize(avctx->width, avctx->height);
139  int deblocking_filter = (avctx->flags & AV_CODEC_FLAG_LOOP_FILTER) ? 1 : 0;
140 
141  if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
142  framerate = AMFConstructRate(avctx->framerate.num, avctx->framerate.den);
143  } else {
144  framerate = AMFConstructRate(avctx->time_base.den, avctx->time_base.num * avctx->ticks_per_frame);
145  }
146 
147  if ((ret = ff_amf_encode_init(avctx)) != 0)
148  return ret;
149 
150  // Static parameters
151  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_USAGE, ctx->usage);
152 
153  AMF_ASSIGN_PROPERTY_SIZE(res, ctx->encoder, AMF_VIDEO_ENCODER_FRAMESIZE, framesize);
154 
155  AMF_ASSIGN_PROPERTY_RATE(res, ctx->encoder, AMF_VIDEO_ENCODER_FRAMERATE, framerate);
156 
157  switch (avctx->profile) {
159  profile = AMF_VIDEO_ENCODER_PROFILE_BASELINE;
160  break;
162  profile = AMF_VIDEO_ENCODER_PROFILE_MAIN;
163  break;
165  profile = AMF_VIDEO_ENCODER_PROFILE_HIGH;
166  break;
168  profile = AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_BASELINE;
169  break;
171  profile = AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_HIGH;
172  break;
173  }
174  if (profile == 0) {
175  profile = ctx->profile;
176  }
177 
178  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_PROFILE, profile);
179 
180  profile_level = avctx->level;
181  if (profile_level == FF_LEVEL_UNKNOWN) {
182  profile_level = ctx->level;
183  }
184  if (profile_level != 0) {
185  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_PROFILE_LEVEL, profile_level);
186  }
187 
188  // Maximum Reference Frames
189  if (avctx->refs != -1) {
190  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_MAX_NUM_REFRAMES, avctx->refs);
191  }
192  if (avctx->sample_aspect_ratio.den && avctx->sample_aspect_ratio.num) {
193  AMFRatio ratio = AMFConstructRatio(avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den);
194  AMF_ASSIGN_PROPERTY_RATIO(res, ctx->encoder, AMF_VIDEO_ENCODER_ASPECT_RATIO, ratio);
195  }
196 
197  /// Color Range (Partial/TV/MPEG or Full/PC/JPEG)
198  if (avctx->color_range == AVCOL_RANGE_JPEG) {
199  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_FULL_RANGE_COLOR, 1);
200  }
201 
202  // autodetect rate control method
203  if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_UNKNOWN) {
204  if (ctx->qp_i != -1 || ctx->qp_p != -1 || ctx->qp_b != -1) {
205  ctx->rate_control_mode = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP;
206  av_log(ctx, AV_LOG_DEBUG, "Rate control turned to CQP\n");
207  } else if (avctx->rc_max_rate > 0 ) {
208  ctx->rate_control_mode = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR;
209  av_log(ctx, AV_LOG_DEBUG, "Rate control turned to Peak VBR\n");
210  } else {
211  ctx->rate_control_mode = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR;
212  av_log(ctx, AV_LOG_DEBUG, "Rate control turned to CBR\n");
213  }
214  }
215 
216  if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP) {
217  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_RATE_CONTROL_PREANALYSIS_ENABLE, AMF_VIDEO_ENCODER_PREENCODE_DISABLED);
218  if (ctx->preanalysis)
219  av_log(ctx, AV_LOG_WARNING, "Pre-Analysis is not supported by cqp Rate Control Method, automatically disabled\n");
220  } else {
221  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_RATE_CONTROL_PREANALYSIS_ENABLE, ctx->preanalysis);
222  }
223 
224  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_QUALITY_PRESET, ctx->quality);
225 
226  // Dynamic parmaters
227  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD, ctx->rate_control_mode);
228 
229  /// VBV Buffer
230  if (avctx->rc_buffer_size != 0) {
231  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_VBV_BUFFER_SIZE, avctx->rc_buffer_size);
232  if (avctx->rc_initial_buffer_occupancy != 0) {
233  int amf_buffer_fullness = avctx->rc_initial_buffer_occupancy * 64 / avctx->rc_buffer_size;
234  if (amf_buffer_fullness > 64)
235  amf_buffer_fullness = 64;
236  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_INITIAL_VBV_BUFFER_FULLNESS, amf_buffer_fullness);
237  }
238  }
239  /// Maximum Access Unit Size
240  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_MAX_AU_SIZE, ctx->max_au_size);
241 
242  if (ctx->max_au_size)
243  ctx->enforce_hrd = 1;
244 
245  // QP Minimum / Maximum
246  if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP) {
247  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_MIN_QP, 0);
248  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_MAX_QP, 51);
249  } else {
250  if (avctx->qmin != -1) {
251  int qval = avctx->qmin > 51 ? 51 : avctx->qmin;
252  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_MIN_QP, qval);
253  }
254  if (avctx->qmax != -1) {
255  int qval = avctx->qmax > 51 ? 51 : avctx->qmax;
256  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_MAX_QP, qval);
257  }
258  }
259  // QP Values
260  if (ctx->qp_i != -1)
261  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_QP_I, ctx->qp_i);
262  if (ctx->qp_p != -1)
263  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_QP_P, ctx->qp_p);
264  if (ctx->qp_b != -1)
265  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_QP_B, ctx->qp_b);
266 
267  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_TARGET_BITRATE, avctx->bit_rate);
268 
269  if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR) {
270  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_PEAK_BITRATE, avctx->bit_rate);
271  }
272  if (avctx->rc_max_rate) {
273  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_PEAK_BITRATE, avctx->rc_max_rate);
274  } else if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR) {
275  av_log(ctx, AV_LOG_WARNING, "rate control mode is PEAK_CONSTRAINED_VBR but rc_max_rate is not set\n");
276  }
277 
278  // Initialize Encoder
279  res = ctx->encoder->pVtbl->Init(ctx->encoder, ctx->format, avctx->width, avctx->height);
280  AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG, "encoder->Init() failed with error %d\n", res);
281 
282  // Enforce HRD, Filler Data, VBAQ, Frame Skipping, Deblocking Filter
283  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_ENFORCE_HRD, !!ctx->enforce_hrd);
284  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_FILLER_DATA_ENABLE, !!ctx->filler_data);
285  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_RATE_CONTROL_SKIP_FRAME_ENABLE, !!ctx->skip_frame);
286  if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP) {
287  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_ENABLE_VBAQ, 0);
288  if (ctx->enable_vbaq)
289  av_log(ctx, AV_LOG_WARNING, "VBAQ is not supported by cqp Rate Control Method, automatically disabled\n");
290  } else {
291  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_ENABLE_VBAQ, !!ctx->enable_vbaq);
292  }
293  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_DE_BLOCKING_FILTER, !!deblocking_filter);
294 
295  // B-Frames
296  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_B_PIC_PATTERN, avctx->max_b_frames);
297  if (res != AMF_OK) {
298  res = ctx->encoder->pVtbl->GetProperty(ctx->encoder, AMF_VIDEO_ENCODER_B_PIC_PATTERN, &var);
299  av_log(ctx, AV_LOG_WARNING, "B-frames=%d is not supported by this GPU, switched to %d\n",
300  avctx->max_b_frames, (int)var.int64Value);
301  avctx->max_b_frames = (int)var.int64Value;
302  }
303  if (avctx->max_b_frames) {
304  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_B_PIC_DELTA_QP, ctx->b_frame_delta_qp);
305  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_B_REFERENCE_ENABLE, !!ctx->b_frame_ref);
306  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_REF_B_PIC_DELTA_QP, ctx->ref_b_frame_delta_qp);
307  }
308 
309  // Keyframe Interval
310  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_IDR_PERIOD, avctx->gop_size);
311 
312  // Header Insertion Spacing
313  if (ctx->header_spacing >= 0)
314  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEADER_INSERTION_SPACING, ctx->header_spacing);
315 
316  // Intra-Refresh, Slicing
317  if (ctx->intra_refresh_mb > 0)
318  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_INTRA_REFRESH_NUM_MBS_PER_SLOT, ctx->intra_refresh_mb);
319  if (avctx->slices > 1)
320  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_SLICES_PER_FRAME, avctx->slices);
321 
322  // Coding
323  if (ctx->coding_mode != 0)
324  AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_CABAC_ENABLE, ctx->coding_mode);
325 
326  // Motion Estimation
327  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_MOTION_HALF_PIXEL, !!ctx->me_half_pel);
328  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_MOTION_QUARTERPIXEL, !!ctx->me_quarter_pel);
329 
330  // fill extradata
331  res = AMFVariantInit(&var);
332  AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG, "AMFVariantInit() failed with error %d\n", res);
333 
334  res = ctx->encoder->pVtbl->GetProperty(ctx->encoder, AMF_VIDEO_ENCODER_EXTRADATA, &var);
335  AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG, "GetProperty(AMF_VIDEO_ENCODER_EXTRADATA) failed with error %d\n", res);
336  AMF_RETURN_IF_FALSE(ctx, var.pInterface != NULL, AVERROR_BUG, "GetProperty(AMF_VIDEO_ENCODER_EXTRADATA) returned NULL\n");
337 
338  guid = IID_AMFBuffer();
339 
340  res = var.pInterface->pVtbl->QueryInterface(var.pInterface, &guid, (void**)&buffer); // query for buffer interface
341  if (res != AMF_OK) {
342  var.pInterface->pVtbl->Release(var.pInterface);
343  }
344  AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG, "QueryInterface(IID_AMFBuffer) failed with error %d\n", res);
345 
346  avctx->extradata_size = (int)buffer->pVtbl->GetSize(buffer);
348  if (!avctx->extradata) {
349  buffer->pVtbl->Release(buffer);
350  var.pInterface->pVtbl->Release(var.pInterface);
351  return AVERROR(ENOMEM);
352  }
353  memcpy(avctx->extradata, buffer->pVtbl->GetNative(buffer), avctx->extradata_size);
354 
355  buffer->pVtbl->Release(buffer);
356  var.pInterface->pVtbl->Release(var.pInterface);
357 
358  return 0;
359 }
360 
361 static const AVCodecDefault defaults[] = {
362  { "refs", "-1" },
363  { "aspect", "0" },
364  { "qmin", "-1" },
365  { "qmax", "-1" },
366  { "b", "2M" },
367  { "g", "250" },
368  { "slices", "1" },
369  { NULL },
370 };
371 
372 static const AVClass h264_amf_class = {
373  .class_name = "h264_amf",
374  .item_name = av_default_item_name,
375  .option = options,
376  .version = LIBAVUTIL_VERSION_INT,
377 };
378 
380  .name = "h264_amf",
381  .long_name = NULL_IF_CONFIG_SMALL("AMD AMF H.264 Encoder"),
382  .type = AVMEDIA_TYPE_VIDEO,
383  .id = AV_CODEC_ID_H264,
384  .init = amf_encode_init_h264,
385  .send_frame = ff_amf_send_frame,
386  .receive_packet = ff_amf_receive_packet,
387  .close = ff_amf_encode_close,
388  .priv_data_size = sizeof(AmfContext),
389  .priv_class = &h264_amf_class,
390  .defaults = defaults,
391  .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE,
392  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
394  .wrapper_name = "amf",
395 };
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: internal.h:48
#define FF_PROFILE_H264_MAIN
Definition: avcodec.h:2940
#define NULL
Definition: coverity.c:32
AVRational framerate
Definition: avcodec.h:3106
ptrdiff_t const GLvoid GLenum usage
Definition: opengl_enc.c:100
int usage
Definition: amfenc.h:82
AVOption.
Definition: opt.h:246
#define AV_CODEC_FLAG_LOOP_FILTER
loop filter.
Definition: avcodec.h:880
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
int64_t bit_rate
the average bitrate
Definition: avcodec.h:1616
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
int max_b_frames
maximum number of B-frames between non-B-frames Note: The output will be delayed by max_b_frames+1 re...
Definition: avcodec.h:1826
int skip_frame
Definition: amfenc.h:96
int rc_initial_buffer_occupancy
Number of bits which should be loaded into the rc buffer before decoding starts.
Definition: avcodec.h:2472
#define AV_CODEC_CAP_HARDWARE
Codec is backed by a hardware implementation.
Definition: avcodec.h:1079
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: avcodec.h:2201
int num
Numerator.
Definition: rational.h:59
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
int b_frame_ref
Definition: amfenc.h:102
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:1945
int me_half_pel
Definition: amfenc.h:105
int level
Definition: amfenc.h:84
#define AMF_RETURN_IF_FALSE(avctx, exp, ret_value,...)
Error handling helper.
Definition: amfenc.h:144
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:236
int coding_mode
Definition: amfenc.h:104
int profile
profile
Definition: avcodec.h:2899
AVCodec.
Definition: avcodec.h:3482
int framerate
Definition: h264_levels.c:65
AMF_SURFACE_FORMAT format
AMF surface format.
Definition: amfenc.h:60
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avcodec.h:1689
int b_frame_delta_qp
Definition: amfenc.h:87
#define FF_LEVEL_UNKNOWN
Definition: avcodec.h:3020
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
#define AV_CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
Definition: avcodec.h:1007
int enforce_hrd
Definition: amfenc.h:93
#define FF_PROFILE_H264_BASELINE
Definition: avcodec.h:2938
#define av_cold
Definition: attributes.h:82
AVCodec ff_h264_amf_encoder
Definition: amfenc_h264.c:379
AVOptions.
int ff_amf_send_frame(AVCodecContext *avctx, const AVFrame *frame)
Ecoding one frame - common function for all AMF encoders.
Definition: amfenc.c:591
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1667
int me_quarter_pel
Definition: amfenc.h:106
#define av_log(a,...)
#define VE
Definition: amfenc_h264.c:26
int qp_b
Definition: amfenc.h:99
int av_cold ff_amf_encode_close(AVCodecContext *avctx)
Common encoder termination function.
Definition: amfenc.c:369
int max_au_size
Definition: amfenc.h:100
int qmax
maximum quantizer
Definition: avcodec.h:2415
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
int rate_control_mode
Definition: amfenc.h:92
int quality
Definition: amfenc.h:86
#define FF_PROFILE_H264_HIGH
Definition: avcodec.h:2942
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:1646
int filler_data
Definition: amfenc.h:94
const char * name
Name of the codec implementation.
Definition: avcodec.h:3489
static const AVCodecDefault defaults[]
Definition: amfenc_h264.c:361
int qp_p
Definition: amfenc.h:98
enum AVPixelFormat ff_amf_pix_fmts[]
Supported formats.
Definition: amfenc.c:52
int rc_buffer_size
decoder bitstream buffer size
Definition: avcodec.h:2429
common internal API header
int refs
number of reference frames
Definition: avcodec.h:2154
#define OFFSET(x)
Definition: amfenc_h264.c:25
int ff_amf_encode_init(AVCodecContext *avctx)
Common encoder initization function.
Definition: amfenc.c:506
int width
picture width / height.
Definition: avcodec.h:1739
AVFormatContext * ctx
Definition: movenc.c:48
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about quality
int level
level
Definition: avcodec.h:3019
int ticks_per_frame
For some codecs, the time base is closer to the field rate than the frame rate.
Definition: avcodec.h:1698
the normal 2^n-1 "JPEG" YUV ranges
Definition: pixfmt.h:523
int preanalysis
Definition: amfenc.h:85
AMFComponent * encoder
AMF encoder object.
Definition: amfenc.h:58
int ref_b_frame_delta_qp
Definition: amfenc.h:88
static const AVClass h264_amf_class
Definition: amfenc_h264.c:372
int intra_refresh_mb
Definition: amfenc.h:103
int enable_vbaq
Definition: amfenc.h:95
int qp_i
Definition: amfenc.h:97
main external API structure.
Definition: avcodec.h:1566
int qmin
minimum quantizer
Definition: avcodec.h:2408
int profile
Definition: amfenc.h:83
static const AVOption options[]
Definition: amfenc_h264.c:28
int extradata_size
Definition: avcodec.h:1668
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:50
static int FUNC() aud(CodedBitstreamContext *ctx, RWContext *rw, H264RawAUD *current)
Describe the class of an AVClass context structure.
Definition: log.h:67
int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
Definition: amfenc.c:717
AMF encoder context.
Definition: amfenc.h:46
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:275
mfxU16 profile
Definition: qsvenc.c:44
uint8_t level
Definition: svq3.c:207
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
Definition: avcodec.h:1761
int
common internal api header.
int den
Denominator.
Definition: rational.h:60
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
Definition: avcodec.h:791
int slices
Number of slices.
Definition: avcodec.h:2217
void * priv_data
Definition: avcodec.h:1593
static av_cold int amf_encode_init_h264(AVCodecContext *avctx)
Definition: amfenc_h264.c:127
#define FF_PROFILE_H264_CONSTRAINED
Definition: avcodec.h:2935
#define FF_PROFILE_H264_CONSTRAINED_BASELINE
Definition: avcodec.h:2939
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
GLuint buffer
Definition: opengl_enc.c:101
int64_t rc_max_rate
maximum bitrate
Definition: avcodec.h:2444
int header_spacing
Definition: amfenc.h:101