Commit | Line | Data |
---|---|---|
6662ec29 MN |
1 | /* |
2 | * H.264 encoding using the x264 library | |
f2250162 | 3 | * Copyright (C) 2005 Mans Rullgard <mans@mansr.com> |
6662ec29 | 4 | * |
2912e87a | 5 | * This file is part of Libav. |
b78e7197 | 6 | * |
2912e87a | 7 | * Libav is free software; you can redistribute it and/or |
6662ec29 MN |
8 | * modify it under the terms of the GNU Lesser General Public |
9 | * License as published by the Free Software Foundation; either | |
b78e7197 | 10 | * version 2.1 of the License, or (at your option) any later version. |
6662ec29 | 11 | * |
2912e87a | 12 | * Libav is distributed in the hope that it will be useful, |
6662ec29 MN |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | * Lesser General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public | |
2912e87a | 18 | * License along with Libav; if not, write to the Free Software |
5509bffa | 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
6662ec29 MN |
20 | */ |
21 | ||
1d9c2dc8 | 22 | #include "libavutil/internal.h" |
07a227b4 | 23 | #include "libavutil/opt.h" |
1d9c2dc8 | 24 | #include "libavutil/mem.h" |
d97efd7f | 25 | #include "libavutil/pixdesc.h" |
09cb75cd | 26 | #include "libavutil/stereo3d.h" |
6662ec29 | 27 | #include "avcodec.h" |
ae60927a | 28 | #include "internal.h" |
4719040c DB |
29 | |
30 | #if defined(_MSC_VER) | |
31 | #define X264_API_IMPORTS 1 | |
32 | #endif | |
33 | ||
6662ec29 | 34 | #include <x264.h> |
d5dc8cc2 | 35 | #include <float.h> |
337afd14 | 36 | #include <math.h> |
58f7833e RS |
37 | #include <stdio.h> |
38 | #include <stdlib.h> | |
39 | #include <string.h> | |
6662ec29 MN |
40 | |
41 | typedef struct X264Context { | |
07a227b4 | 42 | AVClass *class; |
8a8720c1 DB |
43 | x264_param_t params; |
44 | x264_t *enc; | |
45 | x264_picture_t pic; | |
46 | uint8_t *sei; | |
47 | int sei_size; | |
07a227b4 BC |
48 | char *preset; |
49 | char *tune; | |
50 | char *profile; | |
51 | int fastfirstpass; | |
d5dc8cc2 | 52 | float crf; |
4ae30cac | 53 | float crf_max; |
9d508e49 | 54 | int cqp; |
85254fcb | 55 | int aq_mode; |
5c75b2a0 | 56 | float aq_strength; |
3b81636f | 57 | char *psy_rd; |
38934f19 | 58 | int psy; |
d4b96713 | 59 | int rc_lookahead; |
c5dd0bc4 | 60 | int weightp; |
0f29699d | 61 | int weightb; |
faaecd47 | 62 | int ssim; |
5d4a1048 | 63 | int intra_refresh; |
bc54c2ae | 64 | int bluray_compat; |
f83c4518 | 65 | int b_bias; |
34dda125 | 66 | int b_pyramid; |
eab21c32 | 67 | int mixed_refs; |
373257fa | 68 | int dct8x8; |
3b82aeee | 69 | int fast_pskip; |
cf90c5d0 | 70 | int aud; |
0dc5e12f | 71 | int mbtree; |
71b5f442 | 72 | char *deblock; |
70423376 | 73 | float cplxblur; |
0635a8aa | 74 | char *partitions; |
9c684fea | 75 | int direct_pred; |
3a78fb57 | 76 | int slice_max_size; |
d533e395 | 77 | char *stats; |
e52e4fe1 | 78 | int nal_hrd; |
29b553c1 | 79 | char *x264_params; |
6662ec29 MN |
80 | } X264Context; |
81 | ||
8a8720c1 | 82 | static void X264_log(void *p, int level, const char *fmt, va_list args) |
6662ec29 MN |
83 | { |
84 | static const int level_map[] = { | |
bb270c08 | 85 | [X264_LOG_ERROR] = AV_LOG_ERROR, |
3709f0d7 | 86 | [X264_LOG_WARNING] = AV_LOG_WARNING, |
bb270c08 DB |
87 | [X264_LOG_INFO] = AV_LOG_INFO, |
88 | [X264_LOG_DEBUG] = AV_LOG_DEBUG | |
6662ec29 MN |
89 | }; |
90 | ||
8a8720c1 | 91 | if (level < 0 || level > X264_LOG_DEBUG) |
bb270c08 | 92 | return; |
6662ec29 MN |
93 | |
94 | av_vlog(p, level_map[level], fmt, args); | |
95 | } | |
96 | ||
97 | ||
06484d0b AK |
98 | static int encode_nals(AVCodecContext *ctx, AVPacket *pkt, |
99 | x264_nal_t *nals, int nnal) | |
6662ec29 | 100 | { |
fe022ce2 | 101 | X264Context *x4 = ctx->priv_data; |
06484d0b AK |
102 | uint8_t *p; |
103 | int i, size = x4->sei_size, ret; | |
104 | ||
105 | if (!nnal) | |
106 | return 0; | |
107 | ||
108 | for (i = 0; i < nnal; i++) | |
109 | size += nals[i].i_payload; | |
110 | ||
111 | if ((ret = ff_alloc_packet(pkt, size)) < 0) | |
112 | return ret; | |
113 | ||
114 | p = pkt->data; | |
fe022ce2 JGG |
115 | |
116 | /* Write the SEI as part of the first frame. */ | |
8a8720c1 | 117 | if (x4->sei_size > 0 && nnal > 0) { |
fe022ce2 JGG |
118 | memcpy(p, x4->sei, x4->sei_size); |
119 | p += x4->sei_size; | |
120 | x4->sei_size = 0; | |
121 | } | |
6662ec29 | 122 | |
8a8720c1 | 123 | for (i = 0; i < nnal; i++){ |
2d3beede JGG |
124 | memcpy(p, nals[i].p_payload, nals[i].i_payload); |
125 | p += nals[i].i_payload; | |
6662ec29 MN |
126 | } |
127 | ||
06484d0b | 128 | return 1; |
6662ec29 MN |
129 | } |
130 | ||
03ca6d70 LB |
131 | static void reconfig_encoder(AVCodecContext *ctx, const AVFrame *frame) |
132 | { | |
133 | X264Context *x4 = ctx->priv_data; | |
134 | AVFrameSideData *side_data; | |
135 | ||
136 | ||
137 | if (x4->params.b_tff != frame->top_field_first) { | |
138 | x4->params.b_tff = frame->top_field_first; | |
139 | x264_encoder_reconfig(x4->enc, &x4->params); | |
140 | } | |
141 | if (x4->params.vui.i_sar_height != ctx->sample_aspect_ratio.den || | |
142 | x4->params.vui.i_sar_width != ctx->sample_aspect_ratio.num) { | |
143 | x4->params.vui.i_sar_height = ctx->sample_aspect_ratio.den; | |
144 | x4->params.vui.i_sar_width = ctx->sample_aspect_ratio.num; | |
145 | x264_encoder_reconfig(x4->enc, &x4->params); | |
146 | } | |
147 | ||
148 | if (x4->params.rc.i_vbv_buffer_size != ctx->rc_buffer_size / 1000 || | |
149 | x4->params.rc.i_vbv_max_bitrate != ctx->rc_max_rate / 1000) { | |
150 | x4->params.rc.i_vbv_buffer_size = ctx->rc_buffer_size / 1000; | |
151 | x4->params.rc.i_vbv_max_bitrate = ctx->rc_max_rate / 1000; | |
152 | x264_encoder_reconfig(x4->enc, &x4->params); | |
153 | } | |
154 | ||
155 | if (x4->params.rc.i_rc_method == X264_RC_ABR && | |
156 | x4->params.rc.i_bitrate != ctx->bit_rate / 1000) { | |
157 | x4->params.rc.i_bitrate = ctx->bit_rate / 1000; | |
158 | x264_encoder_reconfig(x4->enc, &x4->params); | |
159 | } | |
160 | ||
161 | if (x4->crf >= 0 && | |
162 | x4->params.rc.i_rc_method == X264_RC_CRF && | |
163 | x4->params.rc.f_rf_constant != x4->crf) { | |
164 | x4->params.rc.f_rf_constant = x4->crf; | |
165 | x264_encoder_reconfig(x4->enc, &x4->params); | |
166 | } | |
167 | ||
168 | if (x4->params.rc.i_rc_method == X264_RC_CQP && | |
169 | x4->params.rc.i_qp_constant != x4->cqp) { | |
170 | x4->params.rc.i_qp_constant = x4->cqp; | |
171 | x264_encoder_reconfig(x4->enc, &x4->params); | |
172 | } | |
173 | ||
174 | if (x4->crf_max >= 0 && | |
175 | x4->params.rc.f_rf_constant_max != x4->crf_max) { | |
176 | x4->params.rc.f_rf_constant_max = x4->crf_max; | |
177 | x264_encoder_reconfig(x4->enc, &x4->params); | |
178 | } | |
179 | ||
180 | side_data = av_frame_get_side_data(frame, AV_FRAME_DATA_STEREO3D); | |
181 | if (side_data) { | |
182 | AVStereo3D *stereo = (AVStereo3D *)side_data->data; | |
183 | int fpa_type; | |
184 | ||
185 | switch (stereo->type) { | |
186 | case AV_STEREO3D_CHECKERBOARD: | |
187 | fpa_type = 0; | |
188 | break; | |
189 | case AV_STEREO3D_COLUMNS: | |
190 | fpa_type = 1; | |
191 | break; | |
192 | case AV_STEREO3D_LINES: | |
193 | fpa_type = 2; | |
194 | break; | |
195 | case AV_STEREO3D_SIDEBYSIDE: | |
196 | fpa_type = 3; | |
197 | break; | |
198 | case AV_STEREO3D_TOPBOTTOM: | |
199 | fpa_type = 4; | |
200 | break; | |
201 | case AV_STEREO3D_FRAMESEQUENCE: | |
202 | fpa_type = 5; | |
203 | break; | |
204 | default: | |
205 | fpa_type = -1; | |
206 | break; | |
207 | } | |
208 | ||
209 | if (fpa_type != x4->params.i_frame_packing) { | |
210 | x4->params.i_frame_packing = fpa_type; | |
211 | x264_encoder_reconfig(x4->enc, &x4->params); | |
212 | } | |
213 | } | |
214 | } | |
215 | ||
06484d0b AK |
216 | static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, |
217 | int *got_packet) | |
6662ec29 MN |
218 | { |
219 | X264Context *x4 = ctx->priv_data; | |
6662ec29 | 220 | x264_nal_t *nal; |
06484d0b | 221 | int nnal, i, ret; |
6662ec29 MN |
222 | x264_picture_t pic_out; |
223 | ||
652d9d24 | 224 | x264_picture_init( &x4->pic ); |
46c3c53b | 225 | x4->pic.img.i_csp = x4->params.i_csp; |
d97efd7f AK |
226 | if (x264_bit_depth > 8) |
227 | x4->pic.img.i_csp |= X264_CSP_HIGH_DEPTH; | |
6662ec29 MN |
228 | x4->pic.img.i_plane = 3; |
229 | ||
8a8720c1 DB |
230 | if (frame) { |
231 | for (i = 0; i < 3; i++) { | |
232 | x4->pic.img.plane[i] = frame->data[i]; | |
67bcc870 MR |
233 | x4->pic.img.i_stride[i] = frame->linesize[i]; |
234 | } | |
6662ec29 | 235 | |
8a8720c1 | 236 | x4->pic.i_pts = frame->pts; |
3ab354d7 | 237 | x4->pic.i_type = |
975a1447 SS |
238 | frame->pict_type == AV_PICTURE_TYPE_I ? X264_TYPE_KEYFRAME : |
239 | frame->pict_type == AV_PICTURE_TYPE_P ? X264_TYPE_P : | |
240 | frame->pict_type == AV_PICTURE_TYPE_B ? X264_TYPE_B : | |
3ab354d7 | 241 | X264_TYPE_AUTO; |
03ca6d70 | 242 | reconfig_encoder(ctx, frame); |
09cb75cd | 243 | } |
d545fa56 | 244 | do { |
e15e2a6d | 245 | if (x264_encoder_encode(x4->enc, &nal, &nnal, frame? &x4->pic: NULL, &pic_out) < 0) |
913aa9a4 | 246 | return AVERROR_UNKNOWN; |
6662ec29 | 247 | |
06484d0b AK |
248 | ret = encode_nals(ctx, pkt, nal, nnal); |
249 | if (ret < 0) | |
913aa9a4 | 250 | return ret; |
06484d0b | 251 | } while (!ret && !frame && x264_encoder_delayed_frames(x4->enc)); |
6662ec29 | 252 | |
06484d0b AK |
253 | pkt->pts = pic_out.i_pts; |
254 | pkt->dts = pic_out.i_dts; | |
6662ec29 | 255 | |
8a8720c1 | 256 | switch (pic_out.i_type) { |
6662ec29 MN |
257 | case X264_TYPE_IDR: |
258 | case X264_TYPE_I: | |
d2287740 | 259 | ctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; |
6662ec29 MN |
260 | break; |
261 | case X264_TYPE_P: | |
d2287740 | 262 | ctx->coded_frame->pict_type = AV_PICTURE_TYPE_P; |
6662ec29 MN |
263 | break; |
264 | case X264_TYPE_B: | |
265 | case X264_TYPE_BREF: | |
d2287740 | 266 | ctx->coded_frame->pict_type = AV_PICTURE_TYPE_B; |
6662ec29 MN |
267 | break; |
268 | } | |
269 | ||
06484d0b AK |
270 | pkt->flags |= AV_PKT_FLAG_KEY*pic_out.b_keyframe; |
271 | if (ret) | |
d2287740 | 272 | ctx->coded_frame->quality = (pic_out.i_qpplus1 - 1) * FF_QP2LAMBDA; |
6662ec29 | 273 | |
06484d0b AK |
274 | *got_packet = ret; |
275 | return 0; | |
6662ec29 MN |
276 | } |
277 | ||
8a8720c1 | 278 | static av_cold int X264_close(AVCodecContext *avctx) |
6662ec29 MN |
279 | { |
280 | X264Context *x4 = avctx->priv_data; | |
281 | ||
5c4e9728 | 282 | av_freep(&avctx->extradata); |
eae7338e | 283 | av_freep(&x4->sei); |
5c4e9728 | 284 | |
eae7338e | 285 | if (x4->enc) { |
bb270c08 | 286 | x264_encoder_close(x4->enc); |
eae7338e VG |
287 | x4->enc = NULL; |
288 | } | |
6662ec29 | 289 | |
d2287740 AK |
290 | av_frame_free(&avctx->coded_frame); |
291 | ||
6662ec29 MN |
292 | return 0; |
293 | } | |
294 | ||
716d413c | 295 | static int convert_pix_fmt(enum AVPixelFormat pix_fmt) |
46c3c53b AK |
296 | { |
297 | switch (pix_fmt) { | |
716d413c AK |
298 | case AV_PIX_FMT_YUV420P: |
299 | case AV_PIX_FMT_YUVJ420P: | |
300 | case AV_PIX_FMT_YUV420P9: | |
301 | case AV_PIX_FMT_YUV420P10: return X264_CSP_I420; | |
302 | case AV_PIX_FMT_YUV422P: | |
c0f504e9 | 303 | case AV_PIX_FMT_YUVJ422P: |
716d413c AK |
304 | case AV_PIX_FMT_YUV422P10: return X264_CSP_I422; |
305 | case AV_PIX_FMT_YUV444P: | |
c0f504e9 | 306 | case AV_PIX_FMT_YUVJ444P: |
716d413c AK |
307 | case AV_PIX_FMT_YUV444P9: |
308 | case AV_PIX_FMT_YUV444P10: return X264_CSP_I444; | |
58894ab3 KK |
309 | case AV_PIX_FMT_NV12: return X264_CSP_NV12; |
310 | case AV_PIX_FMT_NV16: | |
311 | case AV_PIX_FMT_NV20: return X264_CSP_NV16; | |
46c3c53b AK |
312 | }; |
313 | return 0; | |
314 | } | |
315 | ||
71b5f442 AK |
316 | #define PARSE_X264_OPT(name, var)\ |
317 | if (x4->var && x264_param_parse(&x4->params, name, x4->var) < 0) {\ | |
318 | av_log(avctx, AV_LOG_ERROR, "Error parsing option '%s' with value '%s'.\n", name, x4->var);\ | |
319 | return AVERROR(EINVAL);\ | |
320 | } | |
321 | ||
8a8720c1 | 322 | static av_cold int X264_init(AVCodecContext *avctx) |
6662ec29 MN |
323 | { |
324 | X264Context *x4 = avctx->priv_data; | |
325 | ||
e1319aa1 LB |
326 | #if CONFIG_LIBX262_ENCODER |
327 | if (avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO) { | |
328 | x4->params.b_mpeg2 = 1; | |
329 | x264_param_default_mpeg2(&x4->params); | |
330 | } else | |
331 | #else | |
6662ec29 | 332 | x264_param_default(&x4->params); |
e1319aa1 | 333 | #endif |
6662ec29 | 334 | |
f543f636 | 335 | x4->params.b_deblocking_filter = avctx->flags & CODEC_FLAG_LOOP_FILTER; |
f9791751 | 336 | |
07a227b4 BC |
337 | if (x4->preset || x4->tune) |
338 | if (x264_param_default_preset(&x4->params, x4->preset, x4->tune) < 0) { | |
339 | av_log(avctx, AV_LOG_ERROR, "Error setting preset/tune %s/%s.\n", x4->preset, x4->tune); | |
340 | return AVERROR(EINVAL); | |
341 | } | |
342 | ||
2bb5d637 AP |
343 | if (avctx->level > 0) |
344 | x4->params.i_level_idc = avctx->level; | |
345 | ||
07a227b4 BC |
346 | x4->params.pf_log = X264_log; |
347 | x4->params.p_log_private = avctx; | |
348 | x4->params.i_log_level = X264_LOG_DEBUG; | |
46c3c53b | 349 | x4->params.i_csp = convert_pix_fmt(avctx->pix_fmt); |
07a227b4 | 350 | |
ae60927a AK |
351 | if (avctx->bit_rate) { |
352 | x4->params.rc.i_bitrate = avctx->bit_rate / 1000; | |
353 | x4->params.rc.i_rc_method = X264_RC_ABR; | |
354 | } | |
07a227b4 BC |
355 | x4->params.rc.i_vbv_buffer_size = avctx->rc_buffer_size / 1000; |
356 | x4->params.rc.i_vbv_max_bitrate = avctx->rc_max_rate / 1000; | |
357 | x4->params.rc.b_stat_write = avctx->flags & CODEC_FLAG_PASS1; | |
358 | if (avctx->flags & CODEC_FLAG_PASS2) { | |
359 | x4->params.rc.b_stat_read = 1; | |
360 | } else { | |
d5dc8cc2 AK |
361 | if (x4->crf >= 0) { |
362 | x4->params.rc.i_rc_method = X264_RC_CRF; | |
363 | x4->params.rc.f_rf_constant = x4->crf; | |
9d508e49 AK |
364 | } else if (x4->cqp >= 0) { |
365 | x4->params.rc.i_rc_method = X264_RC_CQP; | |
366 | x4->params.rc.i_qp_constant = x4->cqp; | |
d5dc8cc2 | 367 | } |
4ae30cac AK |
368 | |
369 | if (x4->crf_max >= 0) | |
370 | x4->params.rc.f_rf_constant_max = x4->crf_max; | |
07a227b4 BC |
371 | } |
372 | ||
47812070 | 373 | if (avctx->rc_buffer_size && avctx->rc_initial_buffer_occupancy > 0 && |
8a8720c1 | 374 | (avctx->rc_initial_buffer_occupancy <= avctx->rc_buffer_size)) { |
58f7833e | 375 | x4->params.rc.f_vbv_buffer_init = |
8a8720c1 | 376 | (float)avctx->rc_initial_buffer_occupancy / avctx->rc_buffer_size; |
f7f8120f | 377 | } |
58f7833e | 378 | |
2f325a6f JVS |
379 | if (avctx->i_quant_factor > 0) |
380 | x4->params.rc.f_ip_factor = 1 / fabs(avctx->i_quant_factor); | |
8a8720c1 | 381 | x4->params.rc.f_pb_factor = avctx->b_quant_factor; |
58f7833e | 382 | x4->params.analyse.i_chroma_qp_offset = avctx->chromaoffset; |
58f7833e | 383 | |
0962f23b AK |
384 | if (avctx->me_method == ME_EPZS) |
385 | x4->params.analyse.i_me_method = X264_ME_DIA; | |
386 | else if (avctx->me_method == ME_HEX) | |
387 | x4->params.analyse.i_me_method = X264_ME_HEX; | |
388 | else if (avctx->me_method == ME_UMH) | |
389 | x4->params.analyse.i_me_method = X264_ME_UMH; | |
390 | else if (avctx->me_method == ME_FULL) | |
391 | x4->params.analyse.i_me_method = X264_ME_ESA; | |
392 | else if (avctx->me_method == ME_TESA) | |
393 | x4->params.analyse.i_me_method = X264_ME_TESA; | |
394 | ||
bb73cda2 AK |
395 | if (avctx->gop_size >= 0) |
396 | x4->params.i_keyint_max = avctx->gop_size; | |
397 | if (avctx->max_b_frames >= 0) | |
398 | x4->params.i_bframe = avctx->max_b_frames; | |
399 | if (avctx->scenechange_threshold >= 0) | |
400 | x4->params.i_scenecut_threshold = avctx->scenechange_threshold; | |
401 | if (avctx->qmin >= 0) | |
402 | x4->params.rc.i_qp_min = avctx->qmin; | |
403 | if (avctx->qmax >= 0) | |
404 | x4->params.rc.i_qp_max = avctx->qmax; | |
405 | if (avctx->max_qdiff >= 0) | |
406 | x4->params.rc.i_qp_step = avctx->max_qdiff; | |
407 | if (avctx->qblur >= 0) | |
408 | x4->params.rc.f_qblur = avctx->qblur; /* temporally blur quants */ | |
409 | if (avctx->qcompress >= 0) | |
410 | x4->params.rc.f_qcompress = avctx->qcompress; /* 0.0 => cbr, 1.0 => constant qp */ | |
411 | if (avctx->refs >= 0) | |
412 | x4->params.i_frame_reference = avctx->refs; | |
0962f23b AK |
413 | if (avctx->trellis >= 0) |
414 | x4->params.analyse.i_trellis = avctx->trellis; | |
415 | if (avctx->me_range >= 0) | |
416 | x4->params.analyse.i_me_range = avctx->me_range; | |
417 | if (avctx->noise_reduction >= 0) | |
418 | x4->params.analyse.i_noise_reduction = avctx->noise_reduction; | |
419 | if (avctx->me_subpel_quality >= 0) | |
420 | x4->params.analyse.i_subpel_refine = avctx->me_subpel_quality; | |
421 | if (avctx->b_frame_strategy >= 0) | |
422 | x4->params.i_bframe_adaptive = avctx->b_frame_strategy; | |
423 | if (avctx->keyint_min >= 0) | |
424 | x4->params.i_keyint_min = avctx->keyint_min; | |
425 | if (avctx->coder_type >= 0) | |
426 | x4->params.b_cabac = avctx->coder_type == FF_CODER_TYPE_AC; | |
427 | if (avctx->me_cmp >= 0) | |
428 | x4->params.analyse.b_chroma_me = avctx->me_cmp & FF_CMP_CHROMA; | |
bb73cda2 | 429 | |
85254fcb AK |
430 | if (x4->aq_mode >= 0) |
431 | x4->params.rc.i_aq_mode = x4->aq_mode; | |
5c75b2a0 AK |
432 | if (x4->aq_strength >= 0) |
433 | x4->params.rc.f_aq_strength = x4->aq_strength; | |
71b5f442 AK |
434 | PARSE_X264_OPT("psy-rd", psy_rd); |
435 | PARSE_X264_OPT("deblock", deblock); | |
0635a8aa | 436 | PARSE_X264_OPT("partitions", partitions); |
d533e395 | 437 | PARSE_X264_OPT("stats", stats); |
38934f19 AK |
438 | if (x4->psy >= 0) |
439 | x4->params.analyse.b_psy = x4->psy; | |
d4b96713 AK |
440 | if (x4->rc_lookahead >= 0) |
441 | x4->params.rc.i_lookahead = x4->rc_lookahead; | |
c5dd0bc4 AK |
442 | if (x4->weightp >= 0) |
443 | x4->params.analyse.i_weighted_pred = x4->weightp; | |
0f29699d AK |
444 | if (x4->weightb >= 0) |
445 | x4->params.analyse.b_weighted_bipred = x4->weightb; | |
70423376 AK |
446 | if (x4->cplxblur >= 0) |
447 | x4->params.rc.f_complexity_blur = x4->cplxblur; | |
c5dd0bc4 | 448 | |
faaecd47 AK |
449 | if (x4->ssim >= 0) |
450 | x4->params.analyse.b_ssim = x4->ssim; | |
5d4a1048 AK |
451 | if (x4->intra_refresh >= 0) |
452 | x4->params.b_intra_refresh = x4->intra_refresh; | |
bc54c2ae LB |
453 | if (x4->bluray_compat >= 0) { |
454 | x4->params.b_bluray_compat = x4->bluray_compat; | |
455 | x4->params.b_vfr_input = 0; | |
456 | } | |
f83c4518 AK |
457 | if (x4->b_bias != INT_MIN) |
458 | x4->params.i_bframe_bias = x4->b_bias; | |
34dda125 AK |
459 | if (x4->b_pyramid >= 0) |
460 | x4->params.i_bframe_pyramid = x4->b_pyramid; | |
eab21c32 AK |
461 | if (x4->mixed_refs >= 0) |
462 | x4->params.analyse.b_mixed_references = x4->mixed_refs; | |
373257fa AK |
463 | if (x4->dct8x8 >= 0) |
464 | x4->params.analyse.b_transform_8x8 = x4->dct8x8; | |
3b82aeee AK |
465 | if (x4->fast_pskip >= 0) |
466 | x4->params.analyse.b_fast_pskip = x4->fast_pskip; | |
cf90c5d0 AK |
467 | if (x4->aud >= 0) |
468 | x4->params.b_aud = x4->aud; | |
0dc5e12f AK |
469 | if (x4->mbtree >= 0) |
470 | x4->params.rc.b_mb_tree = x4->mbtree; | |
9c684fea AK |
471 | if (x4->direct_pred >= 0) |
472 | x4->params.analyse.i_direct_mv_pred = x4->direct_pred; | |
85254fcb | 473 | |
3a78fb57 LB |
474 | if (x4->slice_max_size >= 0) |
475 | x4->params.i_slice_max_size = x4->slice_max_size; | |
476 | ||
07a227b4 BC |
477 | if (x4->fastfirstpass) |
478 | x264_param_apply_fastfirstpass(&x4->params); | |
479 | ||
9bf41210 JVS |
480 | if (x4->nal_hrd >= 0) |
481 | x4->params.i_nal_hrd = x4->nal_hrd; | |
482 | ||
07a227b4 BC |
483 | if (x4->profile) |
484 | if (x264_param_apply_profile(&x4->params, x4->profile) < 0) { | |
485 | av_log(avctx, AV_LOG_ERROR, "Error setting profile %s.\n", x4->profile); | |
486 | return AVERROR(EINVAL); | |
487 | } | |
488 | ||
489 | x4->params.i_width = avctx->width; | |
490 | x4->params.i_height = avctx->height; | |
491 | x4->params.vui.i_sar_width = avctx->sample_aspect_ratio.num; | |
492 | x4->params.vui.i_sar_height = avctx->sample_aspect_ratio.den; | |
493 | x4->params.i_fps_num = x4->params.i_timebase_den = avctx->time_base.den; | |
494 | x4->params.i_fps_den = x4->params.i_timebase_num = avctx->time_base.num; | |
495 | ||
f543f636 | 496 | x4->params.analyse.b_psnr = avctx->flags & CODEC_FLAG_PSNR; |
58f7833e | 497 | |
8a8720c1 | 498 | x4->params.i_threads = avctx->thread_count; |
338978a7 MS |
499 | if (avctx->thread_type) |
500 | x4->params.b_sliced_threads = avctx->thread_type == FF_THREAD_SLICE; | |
568d4b81 | 501 | |
f543f636 | 502 | x4->params.b_interlaced = avctx->flags & CODEC_FLAG_INTERLACED_DCT; |
d9e5c9b7 | 503 | |
e25c6710 JM |
504 | x4->params.b_open_gop = !(avctx->flags & CODEC_FLAG_CLOSED_GOP); |
505 | ||
2aa72ecc JZ |
506 | x4->params.i_slice_count = avctx->slices; |
507 | ||
75177b2f | 508 | x4->params.vui.b_fullrange = avctx->pix_fmt == AV_PIX_FMT_YUVJ420P || |
c0f504e9 CEH |
509 | avctx->pix_fmt == AV_PIX_FMT_YUVJ422P || |
510 | avctx->pix_fmt == AV_PIX_FMT_YUVJ444P || | |
75177b2f | 511 | avctx->color_range == AVCOL_RANGE_JPEG; |
3cf8db94 | 512 | |
0cbb1473 LB |
513 | // x264 validates the values internally |
514 | x4->params.vui.i_colorprim = avctx->color_primaries; | |
515 | x4->params.vui.i_transfer = avctx->color_trc; | |
516 | x4->params.vui.i_colmatrix = avctx->colorspace; | |
517 | ||
8a8720c1 | 518 | if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) |
806011f2 | 519 | x4->params.b_repeat_headers = 0; |
806011f2 | 520 | |
29b553c1 GEA |
521 | if (x4->x264_params) { |
522 | AVDictionary *dict = NULL; | |
523 | AVDictionaryEntry *en = NULL; | |
524 | ||
525 | if (!av_dict_parse_string(&dict, x4->x264_params, "=", ":", 0)) { | |
526 | while ((en = av_dict_get(dict, "", en, AV_DICT_IGNORE_SUFFIX))) { | |
527 | if (x264_param_parse(&x4->params, en->key, en->value) < 0) | |
528 | av_log(avctx, AV_LOG_WARNING, | |
529 | "Error parsing option '%s = %s'.\n", | |
530 | en->key, en->value); | |
531 | } | |
532 | ||
533 | av_dict_free(&dict); | |
534 | } | |
535 | } | |
536 | ||
07a227b4 BC |
537 | // update AVCodecContext with x264 parameters |
538 | avctx->has_b_frames = x4->params.i_bframe ? | |
539 | x4->params.i_bframe_pyramid ? 2 : 1 : 0; | |
57facb73 MS |
540 | if (avctx->max_b_frames < 0) |
541 | avctx->max_b_frames = 0; | |
542 | ||
07a227b4 | 543 | avctx->bit_rate = x4->params.rc.i_bitrate*1000; |
07a227b4 | 544 | |
6662ec29 | 545 | x4->enc = x264_encoder_open(&x4->params); |
8a8720c1 | 546 | if (!x4->enc) |
913aa9a4 | 547 | return AVERROR_UNKNOWN; |
6662ec29 | 548 | |
d2287740 AK |
549 | avctx->coded_frame = av_frame_alloc(); |
550 | if (!avctx->coded_frame) | |
551 | return AVERROR(ENOMEM); | |
6662ec29 | 552 | |
8a8720c1 | 553 | if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) { |
4f59b684 | 554 | x264_nal_t *nal; |
05d69922 | 555 | uint8_t *p; |
f3b3b489 | 556 | int nnal, s, i; |
806011f2 | 557 | |
2d3beede | 558 | s = x264_encoder_headers(x4->enc, &nal, &nnal); |
05d69922 | 559 | avctx->extradata = p = av_malloc(s); |
9fb483fe VG |
560 | if (!p) |
561 | return AVERROR(ENOMEM); | |
806011f2 | 562 | |
05d69922 AK |
563 | for (i = 0; i < nnal; i++) { |
564 | /* Don't put the SEI in extradata. */ | |
565 | if (nal[i].i_type == NAL_SEI) { | |
f3b3b489 | 566 | av_log(avctx, AV_LOG_INFO, "%s\n", nal[i].p_payload+25); |
05d69922 AK |
567 | x4->sei_size = nal[i].i_payload; |
568 | x4->sei = av_malloc(x4->sei_size); | |
9fb483fe VG |
569 | if (!x4->sei) |
570 | return AVERROR(ENOMEM); | |
05d69922 AK |
571 | memcpy(x4->sei, nal[i].p_payload, nal[i].i_payload); |
572 | continue; | |
573 | } | |
574 | memcpy(p, nal[i].p_payload, nal[i].i_payload); | |
575 | p += nal[i].i_payload; | |
576 | } | |
577 | avctx->extradata_size = p - avctx->extradata; | |
806011f2 MR |
578 | } |
579 | ||
6662ec29 MN |
580 | return 0; |
581 | } | |
582 | ||
716d413c AK |
583 | static const enum AVPixelFormat pix_fmts_8bit[] = { |
584 | AV_PIX_FMT_YUV420P, | |
585 | AV_PIX_FMT_YUVJ420P, | |
586 | AV_PIX_FMT_YUV422P, | |
c0f504e9 | 587 | AV_PIX_FMT_YUVJ422P, |
716d413c | 588 | AV_PIX_FMT_YUV444P, |
c0f504e9 | 589 | AV_PIX_FMT_YUVJ444P, |
58894ab3 KK |
590 | AV_PIX_FMT_NV12, |
591 | AV_PIX_FMT_NV16, | |
716d413c | 592 | AV_PIX_FMT_NONE |
d97efd7f | 593 | }; |
716d413c AK |
594 | static const enum AVPixelFormat pix_fmts_9bit[] = { |
595 | AV_PIX_FMT_YUV420P9, | |
596 | AV_PIX_FMT_YUV444P9, | |
597 | AV_PIX_FMT_NONE | |
d97efd7f | 598 | }; |
716d413c AK |
599 | static const enum AVPixelFormat pix_fmts_10bit[] = { |
600 | AV_PIX_FMT_YUV420P10, | |
601 | AV_PIX_FMT_YUV422P10, | |
602 | AV_PIX_FMT_YUV444P10, | |
58894ab3 | 603 | AV_PIX_FMT_NV20, |
716d413c | 604 | AV_PIX_FMT_NONE |
d97efd7f AK |
605 | }; |
606 | ||
607 | static av_cold void X264_init_static(AVCodec *codec) | |
608 | { | |
609 | if (x264_bit_depth == 8) | |
610 | codec->pix_fmts = pix_fmts_8bit; | |
611 | else if (x264_bit_depth == 9) | |
612 | codec->pix_fmts = pix_fmts_9bit; | |
613 | else if (x264_bit_depth == 10) | |
614 | codec->pix_fmts = pix_fmts_10bit; | |
615 | } | |
616 | ||
07a227b4 BC |
617 | #define OFFSET(x) offsetof(X264Context, x) |
618 | #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM | |
619 | static const AVOption options[] = { | |
145f741e AK |
620 | { "preset", "Set the encoding preset (cf. x264 --fullhelp)", OFFSET(preset), AV_OPT_TYPE_STRING, { .str = "medium" }, 0, 0, VE}, |
621 | { "tune", "Tune the encoding params (cf. x264 --fullhelp)", OFFSET(tune), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE}, | |
622 | { "profile", "Set profile restrictions (cf. x264 --fullhelp) ", OFFSET(profile), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE}, | |
e6153f17 | 623 | { "fastfirstpass", "Use fast settings when encoding first pass", OFFSET(fastfirstpass), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, VE}, |
c7b610aa MS |
624 | { "crf", "Select the quality for constant quality mode", OFFSET(crf), AV_OPT_TYPE_FLOAT, {.dbl = -1 }, -1, FLT_MAX, VE }, |
625 | { "crf_max", "In CRF mode, prevents VBV from lowering quality beyond this point.",OFFSET(crf_max), AV_OPT_TYPE_FLOAT, {.dbl = -1 }, -1, FLT_MAX, VE }, | |
e6153f17 MS |
626 | { "qp", "Constant quantization parameter rate control method",OFFSET(cqp), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE }, |
627 | { "aq-mode", "AQ method", OFFSET(aq_mode), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE, "aq_mode"}, | |
124134e4 MS |
628 | { "none", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_AQ_NONE}, INT_MIN, INT_MAX, VE, "aq_mode" }, |
629 | { "variance", "Variance AQ (complexity mask)", 0, AV_OPT_TYPE_CONST, {.i64 = X264_AQ_VARIANCE}, INT_MIN, INT_MAX, VE, "aq_mode" }, | |
630 | { "autovariance", "Auto-variance AQ (experimental)", 0, AV_OPT_TYPE_CONST, {.i64 = X264_AQ_AUTOVARIANCE}, INT_MIN, INT_MAX, VE, "aq_mode" }, | |
c7b610aa | 631 | { "aq-strength", "AQ strength. Reduces blocking and blurring in flat and textured areas.", OFFSET(aq_strength), AV_OPT_TYPE_FLOAT, {.dbl = -1}, -1, FLT_MAX, VE}, |
e6153f17 | 632 | { "psy", "Use psychovisual optimizations.", OFFSET(psy), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, |
145f741e | 633 | { "psy-rd", "Strength of psychovisual optimization, in <psy-rd>:<psy-trellis> format.", OFFSET(psy_rd), AV_OPT_TYPE_STRING, {0 }, 0, 0, VE}, |
e6153f17 MS |
634 | { "rc-lookahead", "Number of frames to look ahead for frametype and ratecontrol", OFFSET(rc_lookahead), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE }, |
635 | { "weightb", "Weighted prediction for B-frames.", OFFSET(weightb), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, | |
636 | { "weightp", "Weighted prediction analysis method.", OFFSET(weightp), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE, "weightp" }, | |
124134e4 MS |
637 | { "none", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_WEIGHTP_NONE}, INT_MIN, INT_MAX, VE, "weightp" }, |
638 | { "simple", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_WEIGHTP_SIMPLE}, INT_MIN, INT_MAX, VE, "weightp" }, | |
639 | { "smart", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_WEIGHTP_SMART}, INT_MIN, INT_MAX, VE, "weightp" }, | |
e6153f17 MS |
640 | { "ssim", "Calculate and print SSIM stats.", OFFSET(ssim), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, |
641 | { "intra-refresh", "Use Periodic Intra Refresh instead of IDR frames.",OFFSET(intra_refresh),AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, | |
bc54c2ae | 642 | { "bluray-compat", "Bluray compatibility workarounds.", OFFSET(bluray_compat) ,AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, |
e6153f17 MS |
643 | { "b-bias", "Influences how often B-frames are used", OFFSET(b_bias), AV_OPT_TYPE_INT, { .i64 = INT_MIN}, INT_MIN, INT_MAX, VE }, |
644 | { "b-pyramid", "Keep some B-frames as references.", OFFSET(b_pyramid), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE, "b_pyramid" }, | |
124134e4 MS |
645 | { "none", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_B_PYRAMID_NONE}, INT_MIN, INT_MAX, VE, "b_pyramid" }, |
646 | { "strict", "Strictly hierarchical pyramid", 0, AV_OPT_TYPE_CONST, {.i64 = X264_B_PYRAMID_STRICT}, INT_MIN, INT_MAX, VE, "b_pyramid" }, | |
647 | { "normal", "Non-strict (not Blu-ray compatible)", 0, AV_OPT_TYPE_CONST, {.i64 = X264_B_PYRAMID_NORMAL}, INT_MIN, INT_MAX, VE, "b_pyramid" }, | |
e6153f17 MS |
648 | { "mixed-refs", "One reference per partition, as opposed to one reference per macroblock", OFFSET(mixed_refs), AV_OPT_TYPE_INT, { .i64 = -1}, -1, 1, VE }, |
649 | { "8x8dct", "High profile 8x8 transform.", OFFSET(dct8x8), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE}, | |
650 | { "fast-pskip", NULL, OFFSET(fast_pskip), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE}, | |
651 | { "aud", "Use access unit delimiters.", OFFSET(aud), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE}, | |
652 | { "mbtree", "Use macroblock tree ratecontrol.", OFFSET(mbtree), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE}, | |
145f741e | 653 | { "deblock", "Loop filter parameters, in <alpha:beta> form.", OFFSET(deblock), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE}, |
c7b610aa | 654 | { "cplxblur", "Reduce fluctuations in QP (before curve compression)", OFFSET(cplxblur), AV_OPT_TYPE_FLOAT, {.dbl = -1 }, -1, FLT_MAX, VE}, |
0635a8aa | 655 | { "partitions", "A comma-separated list of partitions to consider. " |
145f741e | 656 | "Possible values: p8x8, p4x4, b8x8, i8x8, i4x4, none, all", OFFSET(partitions), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE}, |
e6153f17 | 657 | { "direct-pred", "Direct MV prediction mode", OFFSET(direct_pred), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE, "direct-pred" }, |
124134e4 MS |
658 | { "none", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = X264_DIRECT_PRED_NONE }, 0, 0, VE, "direct-pred" }, |
659 | { "spatial", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = X264_DIRECT_PRED_SPATIAL }, 0, 0, VE, "direct-pred" }, | |
660 | { "temporal", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = X264_DIRECT_PRED_TEMPORAL }, 0, 0, VE, "direct-pred" }, | |
661 | { "auto", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = X264_DIRECT_PRED_AUTO }, 0, 0, VE, "direct-pred" }, | |
e6153f17 | 662 | { "slice-max-size","Limit the size of each slice in bytes", OFFSET(slice_max_size),AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE }, |
d533e395 | 663 | { "stats", "Filename for 2 pass stats", OFFSET(stats), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE }, |
9bf41210 JVS |
664 | { "nal-hrd", "Signal HRD information (requires vbv-bufsize; " |
665 | "cbr not allowed in .mp4)", OFFSET(nal_hrd), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE, "nal-hrd" }, | |
666 | { "none", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_NAL_HRD_NONE}, INT_MIN, INT_MAX, VE, "nal-hrd" }, | |
667 | { "vbr", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_NAL_HRD_VBR}, INT_MIN, INT_MAX, VE, "nal-hrd" }, | |
668 | { "cbr", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_NAL_HRD_CBR}, INT_MIN, INT_MAX, VE, "nal-hrd" }, | |
29b553c1 | 669 | { "x264-params", "Override the x264 configuration using a :-separated list of key=value parameters", OFFSET(x264_params), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE }, |
07a227b4 BC |
670 | { NULL }, |
671 | }; | |
672 | ||
ae60927a AK |
673 | static const AVCodecDefault x264_defaults[] = { |
674 | { "b", "0" }, | |
bb73cda2 AK |
675 | { "bf", "-1" }, |
676 | { "g", "-1" }, | |
2f325a6f | 677 | { "i_qfactor", "-1" }, |
bb73cda2 AK |
678 | { "qmin", "-1" }, |
679 | { "qmax", "-1" }, | |
680 | { "qdiff", "-1" }, | |
681 | { "qblur", "-1" }, | |
682 | { "qcomp", "-1" }, | |
683 | { "refs", "-1" }, | |
684 | { "sc_threshold", "-1" }, | |
0962f23b AK |
685 | { "trellis", "-1" }, |
686 | { "nr", "-1" }, | |
687 | { "me_range", "-1" }, | |
688 | { "me_method", "-1" }, | |
689 | { "subq", "-1" }, | |
690 | { "b_strategy", "-1" }, | |
691 | { "keyint_min", "-1" }, | |
692 | { "coder", "-1" }, | |
693 | { "cmp", "-1" }, | |
14400374 | 694 | { "threads", AV_STRINGIFY(X264_THREADS_AUTO) }, |
338978a7 | 695 | { "thread_type", "0" }, |
a716006a | 696 | { "flags", "+cgop" }, |
47812070 | 697 | { "rc_init_occupancy","-1" }, |
ae60927a AK |
698 | { NULL }, |
699 | }; | |
700 | ||
e1319aa1 LB |
701 | #if CONFIG_LIBX264_ENCODER |
702 | static const AVClass class = { | |
703 | .class_name = "libx264", | |
704 | .item_name = av_default_item_name, | |
705 | .option = options, | |
706 | .version = LIBAVUTIL_VERSION_INT, | |
707 | }; | |
708 | ||
d36beb3f | 709 | AVCodec ff_libx264_encoder = { |
00c3b67b | 710 | .name = "libx264", |
b2bed932 | 711 | .long_name = NULL_IF_CONFIG_SMALL("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"), |
00c3b67b | 712 | .type = AVMEDIA_TYPE_VIDEO, |
36ef5369 | 713 | .id = AV_CODEC_ID_H264, |
00c3b67b MS |
714 | .priv_data_size = sizeof(X264Context), |
715 | .init = X264_init, | |
716 | .encode2 = X264_frame, | |
717 | .close = X264_close, | |
718 | .capabilities = CODEC_CAP_DELAY | CODEC_CAP_AUTO_THREADS, | |
00c3b67b MS |
719 | .priv_class = &class, |
720 | .defaults = x264_defaults, | |
d97efd7f | 721 | .init_static_data = X264_init_static, |
eae7338e VG |
722 | .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | |
723 | FF_CODEC_CAP_INIT_CLEANUP, | |
6662ec29 | 724 | }; |
e1319aa1 LB |
725 | #endif |
726 | ||
727 | #if CONFIG_LIBX262_ENCODER | |
728 | static const AVClass X262_class = { | |
729 | .class_name = "libx262", | |
730 | .item_name = av_default_item_name, | |
731 | .option = options, | |
732 | .version = LIBAVUTIL_VERSION_INT, | |
733 | }; | |
734 | ||
735 | AVCodec ff_libx262_encoder = { | |
736 | .name = "libx262", | |
737 | .long_name = NULL_IF_CONFIG_SMALL("libx262 MPEG2VIDEO"), | |
738 | .type = AVMEDIA_TYPE_VIDEO, | |
739 | .id = AV_CODEC_ID_MPEG2VIDEO, | |
740 | .priv_data_size = sizeof(X264Context), | |
741 | .init = X264_init, | |
742 | .encode2 = X264_frame, | |
743 | .close = X264_close, | |
744 | .capabilities = CODEC_CAP_DELAY | CODEC_CAP_AUTO_THREADS, | |
745 | .priv_class = &X262_class, | |
746 | .defaults = x264_defaults, | |
747 | .pix_fmts = pix_fmts_8bit, | |
748 | .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | | |
749 | FF_CODEC_CAP_INIT_CLEANUP, | |
750 | }; | |
751 | #endif |