Line | Count | Source |
1 | | /***************************************************************************** |
2 | | * base.c: misc common functions (bit depth independent) |
3 | | ***************************************************************************** |
4 | | * Copyright (C) 2003-2025 x264 project |
5 | | * |
6 | | * Authors: Loren Merritt <lorenm@u.washington.edu> |
7 | | * Laurent Aimar <fenrir@via.ecp.fr> |
8 | | * |
9 | | * This program is free software; you can redistribute it and/or modify |
10 | | * it under the terms of the GNU General Public License as published by |
11 | | * the Free Software Foundation; either version 2 of the License, or |
12 | | * (at your option) any later version. |
13 | | * |
14 | | * This program is distributed in the hope that it will be useful, |
15 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | | * GNU General Public License for more details. |
18 | | * |
19 | | * You should have received a copy of the GNU General Public License |
20 | | * along with this program; if not, write to the Free Software |
21 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. |
22 | | * |
23 | | * This program is also available under a commercial proprietary license. |
24 | | * For more information, contact us at licensing@x264.com. |
25 | | *****************************************************************************/ |
26 | | |
27 | | #include "base.h" |
28 | | |
29 | | #include <ctype.h> |
30 | | |
31 | | #if HAVE_MALLOC_H |
32 | | #include <malloc.h> |
33 | | #endif |
34 | | #if HAVE_THP |
35 | | #include <sys/mman.h> |
36 | | #endif |
37 | | |
38 | 0 | #define X264_ISDIGIT(x) isdigit((unsigned char)(x)) |
39 | | |
40 | | /**************************************************************************** |
41 | | * x264_reduce_fraction: |
42 | | ****************************************************************************/ |
43 | | #define REDUCE_FRACTION( name, type )\ |
44 | 0 | void name( type *n, type *d )\ |
45 | 0 | { \ |
46 | 0 | type a = *n; \ |
47 | 0 | type b = *d; \ |
48 | 0 | type c; \ |
49 | 0 | if( !a || !b ) \ |
50 | 0 | return; \ |
51 | 0 | c = a % b; \ |
52 | 0 | while( c ) \ |
53 | 0 | { \ |
54 | 0 | a = b; \ |
55 | 0 | b = c; \ |
56 | 0 | c = a % b; \ |
57 | 0 | } \ |
58 | 0 | *n /= b; \ |
59 | 0 | *d /= b; \ |
60 | 0 | } Unexecuted instantiation: x264_reduce_fraction Unexecuted instantiation: x264_reduce_fraction64 |
61 | | |
62 | | REDUCE_FRACTION( x264_reduce_fraction , uint32_t ) |
63 | | REDUCE_FRACTION( x264_reduce_fraction64, uint64_t ) |
64 | | |
65 | | /**************************************************************************** |
66 | | * x264_log: |
67 | | ****************************************************************************/ |
68 | | void x264_log_default( void *p_unused, int i_level, const char *psz_fmt, va_list arg ) |
69 | 0 | { |
70 | 0 | char *psz_prefix; |
71 | 0 | switch( i_level ) |
72 | 0 | { |
73 | 0 | case X264_LOG_ERROR: |
74 | 0 | psz_prefix = "error"; |
75 | 0 | break; |
76 | 0 | case X264_LOG_WARNING: |
77 | 0 | psz_prefix = "warning"; |
78 | 0 | break; |
79 | 0 | case X264_LOG_INFO: |
80 | 0 | psz_prefix = "info"; |
81 | 0 | break; |
82 | 0 | case X264_LOG_DEBUG: |
83 | 0 | psz_prefix = "debug"; |
84 | 0 | break; |
85 | 0 | default: |
86 | 0 | psz_prefix = "unknown"; |
87 | 0 | break; |
88 | 0 | } |
89 | 0 | fprintf( stderr, "x264 [%s]: ", psz_prefix ); |
90 | 0 | x264_vfprintf( stderr, psz_fmt, arg ); |
91 | 0 | } |
92 | | |
93 | | void x264_log_internal( int i_level, const char *psz_fmt, ... ) |
94 | 0 | { |
95 | 0 | va_list arg; |
96 | 0 | va_start( arg, psz_fmt ); |
97 | 0 | x264_log_default( NULL, i_level, psz_fmt, arg ); |
98 | 0 | va_end( arg ); |
99 | 0 | } |
100 | | |
101 | | /**************************************************************************** |
102 | | * x264_malloc: |
103 | | ****************************************************************************/ |
104 | | void *x264_malloc( int64_t i_size ) |
105 | 0 | { |
106 | 0 | #define HUGE_PAGE_SIZE 2*1024*1024 |
107 | 0 | #define HUGE_PAGE_THRESHOLD HUGE_PAGE_SIZE*7/8 /* FIXME: Is this optimal? */ |
108 | 0 | if( i_size < 0 || (uint64_t)i_size > (SIZE_MAX - HUGE_PAGE_SIZE) /*|| (uint64_t)i_size > (SIZE_MAX - NATIVE_ALIGN - sizeof(void **))*/ ) |
109 | 0 | { |
110 | 0 | x264_log_internal( X264_LOG_ERROR, "invalid size of malloc: %"PRId64"\n", i_size ); |
111 | 0 | return NULL; |
112 | 0 | } |
113 | 0 | uint8_t *align_buf = NULL; |
114 | 0 | #if HAVE_MALLOC_H |
115 | 0 | #if HAVE_THP |
116 | | /* Attempt to allocate huge pages to reduce TLB misses. */ |
117 | 0 | if( i_size >= HUGE_PAGE_THRESHOLD ) |
118 | 0 | { |
119 | 0 | align_buf = memalign( HUGE_PAGE_SIZE, i_size ); |
120 | 0 | if( align_buf ) |
121 | 0 | { |
122 | | /* Round up to the next huge page boundary if we are close enough. */ |
123 | 0 | size_t madv_size = (i_size + HUGE_PAGE_SIZE - HUGE_PAGE_THRESHOLD) & ~(HUGE_PAGE_SIZE-1); |
124 | 0 | madvise( align_buf, madv_size, MADV_HUGEPAGE ); |
125 | 0 | } |
126 | 0 | } |
127 | 0 | else |
128 | 0 | #endif |
129 | 0 | align_buf = memalign( NATIVE_ALIGN, i_size ); |
130 | | #else |
131 | | uint8_t *buf = malloc( i_size + (NATIVE_ALIGN-1) + sizeof(void **) ); |
132 | | if( buf ) |
133 | | { |
134 | | align_buf = buf + (NATIVE_ALIGN-1) + sizeof(void **); |
135 | | align_buf -= (intptr_t) align_buf & (NATIVE_ALIGN-1); |
136 | | *( (void **) ( align_buf - sizeof(void **) ) ) = buf; |
137 | | } |
138 | | #endif |
139 | 0 | if( !align_buf ) |
140 | 0 | x264_log_internal( X264_LOG_ERROR, "malloc of size %"PRId64" failed\n", i_size ); |
141 | 0 | return align_buf; |
142 | 0 | #undef HUGE_PAGE_SIZE |
143 | 0 | #undef HUGE_PAGE_THRESHOLD |
144 | 0 | } |
145 | | |
146 | | /**************************************************************************** |
147 | | * x264_free: |
148 | | ****************************************************************************/ |
149 | | void x264_free( void *p ) |
150 | 0 | { |
151 | 0 | if( p ) |
152 | 0 | { |
153 | 0 | #if HAVE_MALLOC_H |
154 | 0 | free( p ); |
155 | | #else |
156 | | free( *( ( ( void **) p ) - 1 ) ); |
157 | | #endif |
158 | 0 | } |
159 | 0 | } |
160 | | |
161 | | /**************************************************************************** |
162 | | * x264_slurp_file: |
163 | | ****************************************************************************/ |
164 | | char *x264_slurp_file( const char *filename ) |
165 | 0 | { |
166 | 0 | int b_error = 0; |
167 | 0 | int64_t i_size; |
168 | 0 | char *buf; |
169 | 0 | FILE *fh = x264_fopen( filename, "rb" ); |
170 | 0 | if( !fh ) |
171 | 0 | return NULL; |
172 | | |
173 | 0 | b_error |= fseek( fh, 0, SEEK_END ) < 0; |
174 | 0 | b_error |= ( i_size = ftell( fh ) ) <= 0; |
175 | 0 | if( WORD_SIZE == 4 ) |
176 | 0 | b_error |= i_size > INT32_MAX; |
177 | 0 | b_error |= fseek( fh, 0, SEEK_SET ) < 0; |
178 | 0 | if( b_error ) |
179 | 0 | goto error; |
180 | | |
181 | 0 | buf = x264_malloc( i_size+2 ); |
182 | 0 | if( !buf ) |
183 | 0 | goto error; |
184 | | |
185 | 0 | b_error |= fread( buf, 1, i_size, fh ) != (uint64_t)i_size; |
186 | 0 | fclose( fh ); |
187 | 0 | if( b_error ) |
188 | 0 | { |
189 | 0 | x264_free( buf ); |
190 | 0 | return NULL; |
191 | 0 | } |
192 | | |
193 | 0 | if( buf[i_size-1] != '\n' ) |
194 | 0 | buf[i_size++] = '\n'; |
195 | 0 | buf[i_size] = '\0'; |
196 | |
|
197 | 0 | return buf; |
198 | 0 | error: |
199 | 0 | fclose( fh ); |
200 | 0 | return NULL; |
201 | 0 | } |
202 | | |
203 | | /**************************************************************************** |
204 | | * x264_param_strdup: |
205 | | ****************************************************************************/ |
206 | | typedef struct { |
207 | | int size; |
208 | | int count; |
209 | | void *ptr[]; |
210 | | } strdup_buffer; |
211 | | |
212 | 0 | #define BUFFER_OFFSET (int)offsetof(strdup_buffer, ptr) |
213 | 0 | #define BUFFER_DEFAULT_SIZE 16 |
214 | | |
215 | | char *x264_param_strdup( x264_param_t *param, const char *src ) |
216 | 0 | { |
217 | 0 | strdup_buffer *buf = param->opaque; |
218 | 0 | if( !buf ) |
219 | 0 | { |
220 | 0 | buf = malloc( BUFFER_OFFSET + BUFFER_DEFAULT_SIZE * sizeof(void *) ); |
221 | 0 | if( !buf ) |
222 | 0 | goto fail; |
223 | 0 | buf->size = BUFFER_DEFAULT_SIZE; |
224 | 0 | buf->count = 0; |
225 | 0 | param->opaque = buf; |
226 | 0 | } |
227 | 0 | else if( buf->count == buf->size ) |
228 | 0 | { |
229 | 0 | if( buf->size > (INT_MAX - BUFFER_OFFSET) / 2 / (int)sizeof(void *) ) |
230 | 0 | goto fail; |
231 | 0 | int new_size = buf->size * 2; |
232 | 0 | buf = realloc( buf, BUFFER_OFFSET + new_size * sizeof(void *) ); |
233 | 0 | if( !buf ) |
234 | 0 | goto fail; |
235 | 0 | buf->size = new_size; |
236 | 0 | param->opaque = buf; |
237 | 0 | } |
238 | 0 | char *res = strdup( src ); |
239 | 0 | if( !res ) |
240 | 0 | goto fail; |
241 | 0 | buf->ptr[buf->count++] = res; |
242 | 0 | return res; |
243 | 0 | fail: |
244 | 0 | x264_log_internal( X264_LOG_ERROR, "x264_param_strdup failed\n" ); |
245 | 0 | return NULL; |
246 | 0 | } |
247 | | |
248 | | /**************************************************************************** |
249 | | * x264_param_cleanup: |
250 | | ****************************************************************************/ |
251 | | REALIGN_STACK void x264_param_cleanup( x264_param_t *param ) |
252 | 0 | { |
253 | 0 | strdup_buffer *buf = param->opaque; |
254 | 0 | if( buf ) |
255 | 0 | { |
256 | 0 | for( int i = 0; i < buf->count; i++ ) |
257 | 0 | free( buf->ptr[i] ); |
258 | 0 | free( buf ); |
259 | 0 | param->opaque = NULL; |
260 | 0 | } |
261 | 0 | } |
262 | | |
263 | | /**************************************************************************** |
264 | | * x264_picture_init: |
265 | | ****************************************************************************/ |
266 | | REALIGN_STACK void x264_picture_init( x264_picture_t *pic ) |
267 | 0 | { |
268 | 0 | memset( pic, 0, sizeof( x264_picture_t ) ); |
269 | 0 | pic->i_type = X264_TYPE_AUTO; |
270 | 0 | pic->i_qpplus1 = X264_QP_AUTO; |
271 | 0 | pic->i_pic_struct = PIC_STRUCT_AUTO; |
272 | 0 | } |
273 | | |
274 | | /**************************************************************************** |
275 | | * x264_picture_alloc: |
276 | | ****************************************************************************/ |
277 | | REALIGN_STACK int x264_picture_alloc( x264_picture_t *pic, int i_csp, int i_width, int i_height ) |
278 | 0 | { |
279 | 0 | typedef struct |
280 | 0 | { |
281 | 0 | int planes; |
282 | 0 | int width_fix8[3]; |
283 | 0 | int height_fix8[3]; |
284 | 0 | } x264_csp_tab_t; |
285 | |
|
286 | 0 | static const x264_csp_tab_t csp_tab[] = |
287 | 0 | { |
288 | 0 | [X264_CSP_I400] = { 1, { 256*1 }, { 256*1 } }, |
289 | 0 | [X264_CSP_I420] = { 3, { 256*1, 256/2, 256/2 }, { 256*1, 256/2, 256/2 } }, |
290 | 0 | [X264_CSP_YV12] = { 3, { 256*1, 256/2, 256/2 }, { 256*1, 256/2, 256/2 } }, |
291 | 0 | [X264_CSP_NV12] = { 2, { 256*1, 256*1 }, { 256*1, 256/2 }, }, |
292 | 0 | [X264_CSP_NV21] = { 2, { 256*1, 256*1 }, { 256*1, 256/2 }, }, |
293 | 0 | [X264_CSP_I422] = { 3, { 256*1, 256/2, 256/2 }, { 256*1, 256*1, 256*1 } }, |
294 | 0 | [X264_CSP_YV16] = { 3, { 256*1, 256/2, 256/2 }, { 256*1, 256*1, 256*1 } }, |
295 | 0 | [X264_CSP_NV16] = { 2, { 256*1, 256*1 }, { 256*1, 256*1 }, }, |
296 | 0 | [X264_CSP_YUYV] = { 1, { 256*2 }, { 256*1 }, }, |
297 | 0 | [X264_CSP_UYVY] = { 1, { 256*2 }, { 256*1 }, }, |
298 | 0 | [X264_CSP_I444] = { 3, { 256*1, 256*1, 256*1 }, { 256*1, 256*1, 256*1 } }, |
299 | 0 | [X264_CSP_YV24] = { 3, { 256*1, 256*1, 256*1 }, { 256*1, 256*1, 256*1 } }, |
300 | 0 | [X264_CSP_BGR] = { 1, { 256*3 }, { 256*1 }, }, |
301 | 0 | [X264_CSP_BGRA] = { 1, { 256*4 }, { 256*1 }, }, |
302 | 0 | [X264_CSP_RGB] = { 1, { 256*3 }, { 256*1 }, }, |
303 | 0 | }; |
304 | |
|
305 | 0 | int csp = i_csp & X264_CSP_MASK; |
306 | 0 | if( csp <= X264_CSP_NONE || csp >= X264_CSP_MAX || csp == X264_CSP_V210 ) |
307 | 0 | return -1; |
308 | 0 | x264_picture_init( pic ); |
309 | 0 | pic->img.i_csp = i_csp; |
310 | 0 | pic->img.i_plane = csp_tab[csp].planes; |
311 | 0 | int depth_factor = i_csp & X264_CSP_HIGH_DEPTH ? 2 : 1; |
312 | 0 | int64_t plane_offset[3] = {0}; |
313 | 0 | int64_t frame_size = 0; |
314 | 0 | for( int i = 0; i < pic->img.i_plane; i++ ) |
315 | 0 | { |
316 | 0 | int stride = (((int64_t)i_width * csp_tab[csp].width_fix8[i]) >> 8) * depth_factor; |
317 | 0 | int64_t plane_size = (((int64_t)i_height * csp_tab[csp].height_fix8[i]) >> 8) * stride; |
318 | 0 | pic->img.i_stride[i] = stride; |
319 | 0 | plane_offset[i] = frame_size; |
320 | 0 | frame_size += plane_size; |
321 | 0 | } |
322 | 0 | pic->img.plane[0] = x264_malloc( frame_size ); |
323 | 0 | if( !pic->img.plane[0] ) |
324 | 0 | return -1; |
325 | 0 | for( int i = 1; i < pic->img.i_plane; i++ ) |
326 | 0 | pic->img.plane[i] = pic->img.plane[0] + plane_offset[i]; |
327 | 0 | return 0; |
328 | 0 | } |
329 | | |
330 | | /**************************************************************************** |
331 | | * x264_picture_clean: |
332 | | ****************************************************************************/ |
333 | | REALIGN_STACK void x264_picture_clean( x264_picture_t *pic ) |
334 | 0 | { |
335 | 0 | x264_free( pic->img.plane[0] ); |
336 | | |
337 | | /* just to be safe */ |
338 | 0 | memset( pic, 0, sizeof( x264_picture_t ) ); |
339 | 0 | } |
340 | | |
341 | | /**************************************************************************** |
342 | | * x264_param_default: |
343 | | ****************************************************************************/ |
344 | | REALIGN_STACK void x264_param_default( x264_param_t *param ) |
345 | 0 | { |
346 | | /* */ |
347 | 0 | memset( param, 0, sizeof( x264_param_t ) ); |
348 | | |
349 | | /* CPU autodetect */ |
350 | 0 | param->cpu = x264_cpu_detect(); |
351 | 0 | param->i_threads = X264_THREADS_AUTO; |
352 | 0 | param->i_lookahead_threads = X264_THREADS_AUTO; |
353 | 0 | param->b_deterministic = 1; |
354 | 0 | param->i_sync_lookahead = X264_SYNC_LOOKAHEAD_AUTO; |
355 | | |
356 | | /* Video properties */ |
357 | 0 | param->i_csp = X264_CHROMA_FORMAT ? X264_CHROMA_FORMAT : X264_CSP_I420; |
358 | 0 | param->i_width = 0; |
359 | 0 | param->i_height = 0; |
360 | 0 | param->vui.i_sar_width = 0; |
361 | 0 | param->vui.i_sar_height= 0; |
362 | 0 | param->vui.i_overscan = 0; /* undef */ |
363 | 0 | param->vui.i_vidformat = 5; /* undef */ |
364 | 0 | param->vui.b_fullrange = -1; /* default depends on input */ |
365 | 0 | param->vui.i_colorprim = 2; /* undef */ |
366 | 0 | param->vui.i_transfer = 2; /* undef */ |
367 | 0 | param->vui.i_colmatrix = -1; /* default depends on input */ |
368 | 0 | param->vui.i_chroma_loc= 0; /* left center */ |
369 | 0 | param->i_fps_num = 25; |
370 | 0 | param->i_fps_den = 1; |
371 | 0 | param->i_level_idc = -1; |
372 | 0 | param->i_slice_max_size = 0; |
373 | 0 | param->i_slice_max_mbs = 0; |
374 | 0 | param->i_slice_count = 0; |
375 | 0 | #if HAVE_BITDEPTH8 |
376 | 0 | param->i_bitdepth = 8; |
377 | | #elif HAVE_BITDEPTH10 |
378 | | param->i_bitdepth = 10; |
379 | | #else |
380 | | param->i_bitdepth = 8; |
381 | | #endif |
382 | | |
383 | | /* Encoder parameters */ |
384 | 0 | param->i_frame_reference = 3; |
385 | 0 | param->i_keyint_max = 250; |
386 | 0 | param->i_keyint_min = X264_KEYINT_MIN_AUTO; |
387 | 0 | param->i_bframe = 3; |
388 | 0 | param->i_scenecut_threshold = 40; |
389 | 0 | param->i_bframe_adaptive = X264_B_ADAPT_FAST; |
390 | 0 | param->i_bframe_bias = 0; |
391 | 0 | param->i_bframe_pyramid = X264_B_PYRAMID_NORMAL; |
392 | 0 | param->b_interlaced = 0; |
393 | 0 | param->b_constrained_intra = 0; |
394 | |
|
395 | 0 | param->b_deblocking_filter = 1; |
396 | 0 | param->i_deblocking_filter_alphac0 = 0; |
397 | 0 | param->i_deblocking_filter_beta = 0; |
398 | |
|
399 | 0 | param->b_cabac = 1; |
400 | 0 | param->i_cabac_init_idc = 0; |
401 | |
|
402 | 0 | param->rc.i_rc_method = X264_RC_CRF; |
403 | 0 | param->rc.i_bitrate = 0; |
404 | 0 | param->rc.f_rate_tolerance = 1.0; |
405 | 0 | param->rc.i_vbv_max_bitrate = 0; |
406 | 0 | param->rc.i_vbv_buffer_size = 0; |
407 | 0 | param->rc.f_vbv_buffer_init = 0.9; |
408 | 0 | param->rc.i_qp_constant = -1; |
409 | 0 | param->rc.f_rf_constant = 23; |
410 | 0 | param->rc.i_qp_min = 0; |
411 | 0 | param->rc.i_qp_max = INT_MAX; |
412 | 0 | param->rc.i_qp_step = 4; |
413 | 0 | param->rc.f_ip_factor = 1.4; |
414 | 0 | param->rc.f_pb_factor = 1.3; |
415 | 0 | param->rc.i_aq_mode = X264_AQ_VARIANCE; |
416 | 0 | param->rc.f_aq_strength = 1.0; |
417 | 0 | param->rc.i_lookahead = 40; |
418 | |
|
419 | 0 | param->rc.b_stat_write = 0; |
420 | 0 | param->rc.psz_stat_out = "x264_2pass.log"; |
421 | 0 | param->rc.b_stat_read = 0; |
422 | 0 | param->rc.psz_stat_in = "x264_2pass.log"; |
423 | 0 | param->rc.f_qcompress = 0.6; |
424 | 0 | param->rc.f_qblur = 0.5; |
425 | 0 | param->rc.f_complexity_blur = 20; |
426 | 0 | param->rc.i_zones = 0; |
427 | 0 | param->rc.b_mb_tree = 1; |
428 | | |
429 | | /* Log */ |
430 | 0 | param->pf_log = x264_log_default; |
431 | 0 | param->p_log_private = NULL; |
432 | 0 | param->i_log_level = X264_LOG_INFO; |
433 | | |
434 | | /* */ |
435 | 0 | param->analyse.intra = X264_ANALYSE_I4x4 | X264_ANALYSE_I8x8; |
436 | 0 | param->analyse.inter = X264_ANALYSE_I4x4 | X264_ANALYSE_I8x8 |
437 | 0 | | X264_ANALYSE_PSUB16x16 | X264_ANALYSE_BSUB16x16; |
438 | 0 | param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_SPATIAL; |
439 | 0 | param->analyse.i_me_method = X264_ME_HEX; |
440 | 0 | param->analyse.f_psy_rd = 1.0; |
441 | 0 | param->analyse.b_psy = 1; |
442 | 0 | param->analyse.f_psy_trellis = 0; |
443 | 0 | param->analyse.i_me_range = 16; |
444 | 0 | param->analyse.i_subpel_refine = 7; |
445 | 0 | param->analyse.b_mixed_references = 1; |
446 | 0 | param->analyse.b_chroma_me = 1; |
447 | 0 | param->analyse.i_mv_range_thread = -1; |
448 | 0 | param->analyse.i_mv_range = -1; // set from level_idc |
449 | 0 | param->analyse.i_chroma_qp_offset = 0; |
450 | 0 | param->analyse.b_fast_pskip = 1; |
451 | 0 | param->analyse.b_weighted_bipred = 1; |
452 | 0 | param->analyse.i_weighted_pred = X264_WEIGHTP_SMART; |
453 | 0 | param->analyse.b_dct_decimate = 1; |
454 | 0 | param->analyse.b_transform_8x8 = 1; |
455 | 0 | param->analyse.i_trellis = 1; |
456 | 0 | param->analyse.i_luma_deadzone[0] = 21; |
457 | 0 | param->analyse.i_luma_deadzone[1] = 11; |
458 | 0 | param->analyse.b_psnr = 0; |
459 | 0 | param->analyse.b_ssim = 0; |
460 | |
|
461 | 0 | param->i_cqm_preset = X264_CQM_FLAT; |
462 | 0 | memset( param->cqm_4iy, 16, sizeof( param->cqm_4iy ) ); |
463 | 0 | memset( param->cqm_4py, 16, sizeof( param->cqm_4py ) ); |
464 | 0 | memset( param->cqm_4ic, 16, sizeof( param->cqm_4ic ) ); |
465 | 0 | memset( param->cqm_4pc, 16, sizeof( param->cqm_4pc ) ); |
466 | 0 | memset( param->cqm_8iy, 16, sizeof( param->cqm_8iy ) ); |
467 | 0 | memset( param->cqm_8py, 16, sizeof( param->cqm_8py ) ); |
468 | 0 | memset( param->cqm_8ic, 16, sizeof( param->cqm_8ic ) ); |
469 | 0 | memset( param->cqm_8pc, 16, sizeof( param->cqm_8pc ) ); |
470 | |
|
471 | 0 | param->b_repeat_headers = 1; |
472 | 0 | param->b_annexb = 1; |
473 | 0 | param->b_aud = 0; |
474 | 0 | param->b_vfr_input = 1; |
475 | 0 | param->i_nal_hrd = X264_NAL_HRD_NONE; |
476 | 0 | param->b_tff = 1; |
477 | 0 | param->b_pic_struct = 0; |
478 | 0 | param->b_fake_interlaced = 0; |
479 | 0 | param->i_frame_packing = -1; |
480 | 0 | param->i_alternative_transfer = 2; /* undef */ |
481 | 0 | param->b_opencl = 0; |
482 | 0 | param->i_opencl_device = 0; |
483 | 0 | param->opencl_device_id = NULL; |
484 | 0 | param->psz_clbin_file = NULL; |
485 | 0 | param->i_avcintra_class = 0; |
486 | 0 | param->i_avcintra_flavor = X264_AVCINTRA_FLAVOR_PANASONIC; |
487 | 0 | } |
488 | | |
489 | | static int param_apply_preset( x264_param_t *param, const char *preset ) |
490 | 0 | { |
491 | 0 | char *end; |
492 | 0 | int i = strtol( preset, &end, 10 ); |
493 | 0 | if( *end == 0 && i >= 0 && i < ARRAY_ELEMS(x264_preset_names)-1 ) |
494 | 0 | preset = x264_preset_names[i]; |
495 | |
|
496 | 0 | if( !strcasecmp( preset, "ultrafast" ) ) |
497 | 0 | { |
498 | 0 | param->i_frame_reference = 1; |
499 | 0 | param->i_scenecut_threshold = 0; |
500 | 0 | param->b_deblocking_filter = 0; |
501 | 0 | param->b_cabac = 0; |
502 | 0 | param->i_bframe = 0; |
503 | 0 | param->analyse.intra = 0; |
504 | 0 | param->analyse.inter = 0; |
505 | 0 | param->analyse.b_transform_8x8 = 0; |
506 | 0 | param->analyse.i_me_method = X264_ME_DIA; |
507 | 0 | param->analyse.i_subpel_refine = 0; |
508 | 0 | param->rc.i_aq_mode = 0; |
509 | 0 | param->analyse.b_mixed_references = 0; |
510 | 0 | param->analyse.i_trellis = 0; |
511 | 0 | param->i_bframe_adaptive = X264_B_ADAPT_NONE; |
512 | 0 | param->rc.b_mb_tree = 0; |
513 | 0 | param->analyse.i_weighted_pred = X264_WEIGHTP_NONE; |
514 | 0 | param->analyse.b_weighted_bipred = 0; |
515 | 0 | param->rc.i_lookahead = 0; |
516 | 0 | } |
517 | 0 | else if( !strcasecmp( preset, "superfast" ) ) |
518 | 0 | { |
519 | 0 | param->analyse.inter = X264_ANALYSE_I8x8|X264_ANALYSE_I4x4; |
520 | 0 | param->analyse.i_me_method = X264_ME_DIA; |
521 | 0 | param->analyse.i_subpel_refine = 1; |
522 | 0 | param->i_frame_reference = 1; |
523 | 0 | param->analyse.b_mixed_references = 0; |
524 | 0 | param->analyse.i_trellis = 0; |
525 | 0 | param->rc.b_mb_tree = 0; |
526 | 0 | param->analyse.i_weighted_pred = X264_WEIGHTP_SIMPLE; |
527 | 0 | param->rc.i_lookahead = 0; |
528 | 0 | } |
529 | 0 | else if( !strcasecmp( preset, "veryfast" ) ) |
530 | 0 | { |
531 | 0 | param->analyse.i_subpel_refine = 2; |
532 | 0 | param->i_frame_reference = 1; |
533 | 0 | param->analyse.b_mixed_references = 0; |
534 | 0 | param->analyse.i_trellis = 0; |
535 | 0 | param->analyse.i_weighted_pred = X264_WEIGHTP_SIMPLE; |
536 | 0 | param->rc.i_lookahead = 10; |
537 | 0 | } |
538 | 0 | else if( !strcasecmp( preset, "faster" ) ) |
539 | 0 | { |
540 | 0 | param->analyse.b_mixed_references = 0; |
541 | 0 | param->i_frame_reference = 2; |
542 | 0 | param->analyse.i_subpel_refine = 4; |
543 | 0 | param->analyse.i_weighted_pred = X264_WEIGHTP_SIMPLE; |
544 | 0 | param->rc.i_lookahead = 20; |
545 | 0 | } |
546 | 0 | else if( !strcasecmp( preset, "fast" ) ) |
547 | 0 | { |
548 | 0 | param->i_frame_reference = 2; |
549 | 0 | param->analyse.i_subpel_refine = 6; |
550 | 0 | param->analyse.i_weighted_pred = X264_WEIGHTP_SIMPLE; |
551 | 0 | param->rc.i_lookahead = 30; |
552 | 0 | } |
553 | 0 | else if( !strcasecmp( preset, "medium" ) ) |
554 | 0 | { |
555 | | /* Default is medium */ |
556 | 0 | } |
557 | 0 | else if( !strcasecmp( preset, "slow" ) ) |
558 | 0 | { |
559 | 0 | param->analyse.i_subpel_refine = 8; |
560 | 0 | param->i_frame_reference = 5; |
561 | 0 | param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_AUTO; |
562 | 0 | param->analyse.i_trellis = 2; |
563 | 0 | param->rc.i_lookahead = 50; |
564 | 0 | } |
565 | 0 | else if( !strcasecmp( preset, "slower" ) ) |
566 | 0 | { |
567 | 0 | param->analyse.i_me_method = X264_ME_UMH; |
568 | 0 | param->analyse.i_subpel_refine = 9; |
569 | 0 | param->i_frame_reference = 8; |
570 | 0 | param->i_bframe_adaptive = X264_B_ADAPT_TRELLIS; |
571 | 0 | param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_AUTO; |
572 | 0 | param->analyse.inter |= X264_ANALYSE_PSUB8x8; |
573 | 0 | param->analyse.i_trellis = 2; |
574 | 0 | param->rc.i_lookahead = 60; |
575 | 0 | } |
576 | 0 | else if( !strcasecmp( preset, "veryslow" ) ) |
577 | 0 | { |
578 | 0 | param->analyse.i_me_method = X264_ME_UMH; |
579 | 0 | param->analyse.i_subpel_refine = 10; |
580 | 0 | param->analyse.i_me_range = 24; |
581 | 0 | param->i_frame_reference = 16; |
582 | 0 | param->i_bframe_adaptive = X264_B_ADAPT_TRELLIS; |
583 | 0 | param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_AUTO; |
584 | 0 | param->analyse.inter |= X264_ANALYSE_PSUB8x8; |
585 | 0 | param->analyse.i_trellis = 2; |
586 | 0 | param->i_bframe = 8; |
587 | 0 | param->rc.i_lookahead = 60; |
588 | 0 | } |
589 | 0 | else if( !strcasecmp( preset, "placebo" ) ) |
590 | 0 | { |
591 | 0 | param->analyse.i_me_method = X264_ME_TESA; |
592 | 0 | param->analyse.i_subpel_refine = 11; |
593 | 0 | param->analyse.i_me_range = 24; |
594 | 0 | param->i_frame_reference = 16; |
595 | 0 | param->i_bframe_adaptive = X264_B_ADAPT_TRELLIS; |
596 | 0 | param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_AUTO; |
597 | 0 | param->analyse.inter |= X264_ANALYSE_PSUB8x8; |
598 | 0 | param->analyse.b_fast_pskip = 0; |
599 | 0 | param->analyse.i_trellis = 2; |
600 | 0 | param->i_bframe = 16; |
601 | 0 | param->rc.i_lookahead = 60; |
602 | 0 | } |
603 | 0 | else |
604 | 0 | { |
605 | 0 | x264_log_internal( X264_LOG_ERROR, "invalid preset '%s'\n", preset ); |
606 | 0 | return -1; |
607 | 0 | } |
608 | 0 | return 0; |
609 | 0 | } |
610 | | |
611 | | static int param_apply_tune( x264_param_t *param, const char *tune ) |
612 | 0 | { |
613 | 0 | int psy_tuning_used = 0; |
614 | 0 | for( int len; tune += strspn( tune, ",./-+" ), (len = strcspn( tune, ",./-+" )); tune += len ) |
615 | 0 | { |
616 | 0 | if( len == 4 && !strncasecmp( tune, "film", 4 ) ) |
617 | 0 | { |
618 | 0 | if( psy_tuning_used++ ) goto psy_failure; |
619 | 0 | param->i_deblocking_filter_alphac0 = -1; |
620 | 0 | param->i_deblocking_filter_beta = -1; |
621 | 0 | param->analyse.f_psy_trellis = 0.15; |
622 | 0 | } |
623 | 0 | else if( len == 9 && !strncasecmp( tune, "animation", 9 ) ) |
624 | 0 | { |
625 | 0 | if( psy_tuning_used++ ) goto psy_failure; |
626 | 0 | param->i_frame_reference = param->i_frame_reference > 1 ? param->i_frame_reference*2 : 1; |
627 | 0 | param->i_deblocking_filter_alphac0 = 1; |
628 | 0 | param->i_deblocking_filter_beta = 1; |
629 | 0 | param->analyse.f_psy_rd = 0.4; |
630 | 0 | param->rc.f_aq_strength = 0.6; |
631 | 0 | param->i_bframe += 2; |
632 | 0 | } |
633 | 0 | else if( len == 5 && !strncasecmp( tune, "grain", 5 ) ) |
634 | 0 | { |
635 | 0 | if( psy_tuning_used++ ) goto psy_failure; |
636 | 0 | param->i_deblocking_filter_alphac0 = -2; |
637 | 0 | param->i_deblocking_filter_beta = -2; |
638 | 0 | param->analyse.f_psy_trellis = 0.25; |
639 | 0 | param->analyse.b_dct_decimate = 0; |
640 | 0 | param->rc.f_pb_factor = 1.1; |
641 | 0 | param->rc.f_ip_factor = 1.1; |
642 | 0 | param->rc.f_aq_strength = 0.5; |
643 | 0 | param->analyse.i_luma_deadzone[0] = 6; |
644 | 0 | param->analyse.i_luma_deadzone[1] = 6; |
645 | 0 | param->rc.f_qcompress = 0.8; |
646 | 0 | } |
647 | 0 | else if( len == 10 && !strncasecmp( tune, "stillimage", 10 ) ) |
648 | 0 | { |
649 | 0 | if( psy_tuning_used++ ) goto psy_failure; |
650 | 0 | param->i_deblocking_filter_alphac0 = -3; |
651 | 0 | param->i_deblocking_filter_beta = -3; |
652 | 0 | param->analyse.f_psy_rd = 2.0; |
653 | 0 | param->analyse.f_psy_trellis = 0.7; |
654 | 0 | param->rc.f_aq_strength = 1.2; |
655 | 0 | } |
656 | 0 | else if( len == 4 && !strncasecmp( tune, "psnr", 4 ) ) |
657 | 0 | { |
658 | 0 | if( psy_tuning_used++ ) goto psy_failure; |
659 | 0 | param->rc.i_aq_mode = X264_AQ_NONE; |
660 | 0 | param->analyse.b_psy = 0; |
661 | 0 | } |
662 | 0 | else if( len == 4 && !strncasecmp( tune, "ssim", 4 ) ) |
663 | 0 | { |
664 | 0 | if( psy_tuning_used++ ) goto psy_failure; |
665 | 0 | param->rc.i_aq_mode = X264_AQ_AUTOVARIANCE; |
666 | 0 | param->analyse.b_psy = 0; |
667 | 0 | } |
668 | 0 | else if( len == 10 && !strncasecmp( tune, "fastdecode", 10 ) ) |
669 | 0 | { |
670 | 0 | param->b_deblocking_filter = 0; |
671 | 0 | param->b_cabac = 0; |
672 | 0 | param->analyse.b_weighted_bipred = 0; |
673 | 0 | param->analyse.i_weighted_pred = X264_WEIGHTP_NONE; |
674 | 0 | } |
675 | 0 | else if( len == 11 && !strncasecmp( tune, "zerolatency", 11 ) ) |
676 | 0 | { |
677 | 0 | param->rc.i_lookahead = 0; |
678 | 0 | param->i_sync_lookahead = 0; |
679 | 0 | param->i_bframe = 0; |
680 | 0 | param->b_sliced_threads = 1; |
681 | 0 | param->b_vfr_input = 0; |
682 | 0 | param->rc.b_mb_tree = 0; |
683 | 0 | } |
684 | 0 | else if( len == 6 && !strncasecmp( tune, "touhou", 6 ) ) |
685 | 0 | { |
686 | 0 | if( psy_tuning_used++ ) goto psy_failure; |
687 | 0 | param->i_frame_reference = param->i_frame_reference > 1 ? param->i_frame_reference*2 : 1; |
688 | 0 | param->i_deblocking_filter_alphac0 = -1; |
689 | 0 | param->i_deblocking_filter_beta = -1; |
690 | 0 | param->analyse.f_psy_trellis = 0.2; |
691 | 0 | param->rc.f_aq_strength = 1.3; |
692 | 0 | if( param->analyse.inter & X264_ANALYSE_PSUB16x16 ) |
693 | 0 | param->analyse.inter |= X264_ANALYSE_PSUB8x8; |
694 | 0 | } |
695 | 0 | else |
696 | 0 | { |
697 | 0 | x264_log_internal( X264_LOG_ERROR, "invalid tune '%.*s'\n", len, tune ); |
698 | 0 | return -1; |
699 | 0 | psy_failure: |
700 | 0 | x264_log_internal( X264_LOG_WARNING, "only 1 psy tuning can be used: ignoring tune %.*s\n", len, tune ); |
701 | 0 | } |
702 | 0 | } |
703 | 0 | return 0; |
704 | 0 | } |
705 | | |
706 | | REALIGN_STACK int x264_param_default_preset( x264_param_t *param, const char *preset, const char *tune ) |
707 | 0 | { |
708 | 0 | x264_param_default( param ); |
709 | |
|
710 | 0 | if( preset && param_apply_preset( param, preset ) < 0 ) |
711 | 0 | return -1; |
712 | 0 | if( tune && param_apply_tune( param, tune ) < 0 ) |
713 | 0 | return -1; |
714 | 0 | return 0; |
715 | 0 | } |
716 | | |
717 | | REALIGN_STACK void x264_param_apply_fastfirstpass( x264_param_t *param ) |
718 | 0 | { |
719 | | /* Set faster options in case of turbo firstpass. */ |
720 | 0 | if( param->rc.b_stat_write && !param->rc.b_stat_read ) |
721 | 0 | { |
722 | 0 | param->i_frame_reference = 1; |
723 | 0 | param->analyse.b_transform_8x8 = 0; |
724 | 0 | param->analyse.inter = 0; |
725 | 0 | param->analyse.i_me_method = X264_ME_DIA; |
726 | 0 | param->analyse.i_subpel_refine = X264_MIN( 2, param->analyse.i_subpel_refine ); |
727 | 0 | param->analyse.i_trellis = 0; |
728 | 0 | param->analyse.b_fast_pskip = 1; |
729 | 0 | } |
730 | 0 | } |
731 | | |
732 | | static int profile_string_to_int( const char *str ) |
733 | 0 | { |
734 | 0 | if( !strcasecmp( str, "baseline" ) ) |
735 | 0 | return PROFILE_BASELINE; |
736 | 0 | if( !strcasecmp( str, "main" ) ) |
737 | 0 | return PROFILE_MAIN; |
738 | 0 | if( !strcasecmp( str, "high" ) ) |
739 | 0 | return PROFILE_HIGH; |
740 | 0 | if( !strcasecmp( str, "high10" ) ) |
741 | 0 | return PROFILE_HIGH10; |
742 | 0 | if( !strcasecmp( str, "high422" ) ) |
743 | 0 | return PROFILE_HIGH422; |
744 | 0 | if( !strcasecmp( str, "high444" ) ) |
745 | 0 | return PROFILE_HIGH444_PREDICTIVE; |
746 | 0 | return -1; |
747 | 0 | } |
748 | | |
749 | | REALIGN_STACK int x264_param_apply_profile( x264_param_t *param, const char *profile ) |
750 | 0 | { |
751 | 0 | if( !profile ) |
752 | 0 | return 0; |
753 | | |
754 | 0 | const int qp_bd_offset = 6 * (param->i_bitdepth-8); |
755 | 0 | int p = profile_string_to_int( profile ); |
756 | 0 | if( p < 0 ) |
757 | 0 | { |
758 | 0 | x264_log_internal( X264_LOG_ERROR, "invalid profile: %s\n", profile ); |
759 | 0 | return -1; |
760 | 0 | } |
761 | 0 | if( p < PROFILE_HIGH444_PREDICTIVE && ((param->rc.i_rc_method == X264_RC_CQP && param->rc.i_qp_constant <= 0) || |
762 | 0 | (param->rc.i_rc_method == X264_RC_CRF && (int)(param->rc.f_rf_constant + qp_bd_offset) <= 0)) ) |
763 | 0 | { |
764 | 0 | x264_log_internal( X264_LOG_ERROR, "%s profile doesn't support lossless\n", profile ); |
765 | 0 | return -1; |
766 | 0 | } |
767 | 0 | if( p < PROFILE_HIGH444_PREDICTIVE && (param->i_csp & X264_CSP_MASK) >= X264_CSP_I444 ) |
768 | 0 | { |
769 | 0 | x264_log_internal( X264_LOG_ERROR, "%s profile doesn't support 4:4:4\n", profile ); |
770 | 0 | return -1; |
771 | 0 | } |
772 | 0 | if( p < PROFILE_HIGH422 && (param->i_csp & X264_CSP_MASK) >= X264_CSP_I422 ) |
773 | 0 | { |
774 | 0 | x264_log_internal( X264_LOG_ERROR, "%s profile doesn't support 4:2:2\n", profile ); |
775 | 0 | return -1; |
776 | 0 | } |
777 | 0 | if( p < PROFILE_HIGH10 && param->i_bitdepth > 8 ) |
778 | 0 | { |
779 | 0 | x264_log_internal( X264_LOG_ERROR, "%s profile doesn't support a bit depth of %d\n", profile, param->i_bitdepth ); |
780 | 0 | return -1; |
781 | 0 | } |
782 | 0 | if( p < PROFILE_HIGH && (param->i_csp & X264_CSP_MASK) == X264_CSP_I400 ) |
783 | 0 | { |
784 | 0 | x264_log_internal( X264_LOG_ERROR, "%s profile doesn't support 4:0:0\n", profile ); |
785 | 0 | return -1; |
786 | 0 | } |
787 | | |
788 | 0 | if( p == PROFILE_BASELINE ) |
789 | 0 | { |
790 | 0 | param->analyse.b_transform_8x8 = 0; |
791 | 0 | param->b_cabac = 0; |
792 | 0 | param->i_cqm_preset = X264_CQM_FLAT; |
793 | 0 | param->psz_cqm_file = NULL; |
794 | 0 | param->i_bframe = 0; |
795 | 0 | param->analyse.i_weighted_pred = X264_WEIGHTP_NONE; |
796 | 0 | if( param->b_interlaced ) |
797 | 0 | { |
798 | 0 | x264_log_internal( X264_LOG_ERROR, "baseline profile doesn't support interlacing\n" ); |
799 | 0 | return -1; |
800 | 0 | } |
801 | 0 | if( param->b_fake_interlaced ) |
802 | 0 | { |
803 | 0 | x264_log_internal( X264_LOG_ERROR, "baseline profile doesn't support fake interlacing\n" ); |
804 | 0 | return -1; |
805 | 0 | } |
806 | 0 | } |
807 | 0 | else if( p == PROFILE_MAIN ) |
808 | 0 | { |
809 | 0 | param->analyse.b_transform_8x8 = 0; |
810 | 0 | param->i_cqm_preset = X264_CQM_FLAT; |
811 | 0 | param->psz_cqm_file = NULL; |
812 | 0 | } |
813 | 0 | return 0; |
814 | 0 | } |
815 | | |
816 | | static int parse_enum( const char *arg, const char * const *names, int *dst ) |
817 | 0 | { |
818 | 0 | for( int i = 0; names[i]; i++ ) |
819 | 0 | if( *names[i] && !strcasecmp( arg, names[i] ) ) |
820 | 0 | { |
821 | 0 | *dst = i; |
822 | 0 | return 0; |
823 | 0 | } |
824 | 0 | return -1; |
825 | 0 | } |
826 | | |
827 | | static int parse_cqm( const char *str, uint8_t *cqm, int length ) |
828 | 0 | { |
829 | 0 | int i = 0; |
830 | 0 | do { |
831 | 0 | int coef; |
832 | 0 | if( !sscanf( str, "%d", &coef ) || coef < 1 || coef > 255 ) |
833 | 0 | return -1; |
834 | 0 | cqm[i++] = coef; |
835 | 0 | } while( i < length && (str = strchr( str, ',' )) && str++ ); |
836 | 0 | return (i == length) ? 0 : -1; |
837 | 0 | } |
838 | | |
839 | | static int atobool_internal( const char *str, int *b_error ) |
840 | 0 | { |
841 | 0 | if( !strcmp(str, "1") || |
842 | 0 | !strcasecmp(str, "true") || |
843 | 0 | !strcasecmp(str, "yes") ) |
844 | 0 | return 1; |
845 | 0 | if( !strcmp(str, "0") || |
846 | 0 | !strcasecmp(str, "false") || |
847 | 0 | !strcasecmp(str, "no") ) |
848 | 0 | return 0; |
849 | 0 | *b_error = 1; |
850 | 0 | return 0; |
851 | 0 | } |
852 | | |
853 | | static int atoi_internal( const char *str, int *b_error ) |
854 | 0 | { |
855 | 0 | char *end; |
856 | 0 | int v = strtol( str, &end, 0 ); |
857 | 0 | if( end == str || *end != '\0' ) |
858 | 0 | *b_error = 1; |
859 | 0 | return v; |
860 | 0 | } |
861 | | |
862 | | static double atof_internal( const char *str, int *b_error ) |
863 | 0 | { |
864 | 0 | char *end; |
865 | 0 | double v = strtod( str, &end ); |
866 | 0 | if( end == str || *end != '\0' ) |
867 | 0 | *b_error = 1; |
868 | 0 | return v; |
869 | 0 | } |
870 | | |
871 | 0 | #define atobool(str) ( name_was_bool = 1, atobool_internal( str, &b_error ) ) |
872 | | #undef atoi |
873 | | #undef atof |
874 | 0 | #define atoi(str) atoi_internal( str, &b_error ) |
875 | 0 | #define atof(str) atof_internal( str, &b_error ) |
876 | 0 | #define CHECKED_ERROR_PARAM_STRDUP( var, param, src )\ |
877 | 0 | do {\ |
878 | 0 | var = x264_param_strdup( param, src );\ |
879 | 0 | if( !var )\ |
880 | 0 | {\ |
881 | 0 | b_error = 1;\ |
882 | 0 | errortype = X264_PARAM_ALLOC_FAILED;\ |
883 | 0 | }\ |
884 | 0 | } while( 0 ) |
885 | | |
886 | | REALIGN_STACK int x264_param_parse( x264_param_t *p, const char *name, const char *value ) |
887 | 0 | { |
888 | 0 | char *name_buf = NULL; |
889 | 0 | int b_error = 0; |
890 | 0 | int errortype = X264_PARAM_BAD_VALUE; |
891 | 0 | int name_was_bool; |
892 | 0 | int value_was_null = !value; |
893 | |
|
894 | 0 | if( !name ) |
895 | 0 | return X264_PARAM_BAD_NAME; |
896 | 0 | if( !value ) |
897 | 0 | value = "true"; |
898 | |
|
899 | 0 | if( value[0] == '=' ) |
900 | 0 | value++; |
901 | |
|
902 | 0 | if( strchr( name, '_' ) ) // s/_/-/g |
903 | 0 | { |
904 | 0 | char *c; |
905 | 0 | name_buf = strdup(name); |
906 | 0 | if( !name_buf ) |
907 | 0 | return X264_PARAM_ALLOC_FAILED; |
908 | 0 | while( (c = strchr( name_buf, '_' )) ) |
909 | 0 | *c = '-'; |
910 | 0 | name = name_buf; |
911 | 0 | } |
912 | | |
913 | 0 | if( !strncmp( name, "no", 2 ) ) |
914 | 0 | { |
915 | 0 | name += 2; |
916 | 0 | if( name[0] == '-' ) |
917 | 0 | name++; |
918 | 0 | value = atobool(value) ? "false" : "true"; |
919 | 0 | } |
920 | 0 | name_was_bool = 0; |
921 | |
|
922 | 0 | #define OPT(STR) else if( !strcmp( name, STR ) ) |
923 | 0 | #define OPT2(STR0, STR1) else if( !strcmp( name, STR0 ) || !strcmp( name, STR1 ) ) |
924 | 0 | if( 0 ); |
925 | 0 | OPT("asm") |
926 | 0 | { |
927 | 0 | p->cpu = X264_ISDIGIT(value[0]) ? (uint32_t)atoi(value) : |
928 | 0 | !strcasecmp(value, "auto") || atobool(value) ? x264_cpu_detect() : 0; |
929 | 0 | if( b_error ) |
930 | 0 | { |
931 | 0 | char *buf = strdup( value ); |
932 | 0 | if( buf ) |
933 | 0 | { |
934 | 0 | char *tok, UNUSED *saveptr=NULL, *init; |
935 | 0 | b_error = 0; |
936 | 0 | p->cpu = 0; |
937 | 0 | for( init=buf; (tok=strtok_r(init, ",", &saveptr)); init=NULL ) |
938 | 0 | { |
939 | 0 | int i = 0; |
940 | 0 | while( x264_cpu_names[i].flags && strcasecmp(tok, x264_cpu_names[i].name) ) |
941 | 0 | i++; |
942 | 0 | p->cpu |= x264_cpu_names[i].flags; |
943 | 0 | if( !x264_cpu_names[i].flags ) |
944 | 0 | b_error = 1; |
945 | 0 | } |
946 | 0 | free( buf ); |
947 | 0 | if( (p->cpu&X264_CPU_SSSE3) && !(p->cpu&X264_CPU_SSE2_IS_SLOW) ) |
948 | 0 | p->cpu |= X264_CPU_SSE2_IS_FAST; |
949 | 0 | } |
950 | 0 | else |
951 | 0 | errortype = X264_PARAM_ALLOC_FAILED; |
952 | 0 | } |
953 | 0 | } |
954 | 0 | OPT("threads") |
955 | 0 | { |
956 | 0 | if( !strcasecmp(value, "auto") ) |
957 | 0 | p->i_threads = X264_THREADS_AUTO; |
958 | 0 | else |
959 | 0 | p->i_threads = atoi(value); |
960 | 0 | } |
961 | 0 | OPT("lookahead-threads") |
962 | 0 | { |
963 | 0 | if( !strcasecmp(value, "auto") ) |
964 | 0 | p->i_lookahead_threads = X264_THREADS_AUTO; |
965 | 0 | else |
966 | 0 | p->i_lookahead_threads = atoi(value); |
967 | 0 | } |
968 | 0 | OPT("sliced-threads") |
969 | 0 | p->b_sliced_threads = atobool(value); |
970 | 0 | OPT("sync-lookahead") |
971 | 0 | { |
972 | 0 | if( !strcasecmp(value, "auto") ) |
973 | 0 | p->i_sync_lookahead = X264_SYNC_LOOKAHEAD_AUTO; |
974 | 0 | else |
975 | 0 | p->i_sync_lookahead = atoi(value); |
976 | 0 | } |
977 | 0 | OPT2("deterministic", "n-deterministic") |
978 | 0 | p->b_deterministic = atobool(value); |
979 | 0 | OPT("cpu-independent") |
980 | 0 | p->b_cpu_independent = atobool(value); |
981 | 0 | OPT2("level", "level-idc") |
982 | 0 | { |
983 | 0 | if( !strcmp(value, "1b") ) |
984 | 0 | p->i_level_idc = 9; |
985 | 0 | else if( atof(value) < 7 ) |
986 | 0 | p->i_level_idc = (int)(10*atof(value)+.5); |
987 | 0 | else |
988 | 0 | p->i_level_idc = atoi(value); |
989 | 0 | } |
990 | 0 | OPT("bluray-compat") |
991 | 0 | p->b_bluray_compat = atobool(value); |
992 | 0 | OPT("avcintra-class") |
993 | 0 | p->i_avcintra_class = atoi(value); |
994 | 0 | OPT("avcintra-flavor") |
995 | 0 | b_error |= parse_enum( value, x264_avcintra_flavor_names, &p->i_avcintra_flavor ); |
996 | 0 | OPT("sar") |
997 | 0 | { |
998 | 0 | b_error |= ( 2 != sscanf( value, "%d:%d", &p->vui.i_sar_width, &p->vui.i_sar_height ) && |
999 | 0 | 2 != sscanf( value, "%d/%d", &p->vui.i_sar_width, &p->vui.i_sar_height ) ); |
1000 | 0 | } |
1001 | 0 | OPT("overscan") |
1002 | 0 | b_error |= parse_enum( value, x264_overscan_names, &p->vui.i_overscan ); |
1003 | 0 | OPT("videoformat") |
1004 | 0 | b_error |= parse_enum( value, x264_vidformat_names, &p->vui.i_vidformat ); |
1005 | 0 | OPT("fullrange") |
1006 | 0 | b_error |= parse_enum( value, x264_fullrange_names, &p->vui.b_fullrange ); |
1007 | 0 | OPT("colorprim") |
1008 | 0 | b_error |= parse_enum( value, x264_colorprim_names, &p->vui.i_colorprim ); |
1009 | 0 | OPT("transfer") |
1010 | 0 | b_error |= parse_enum( value, x264_transfer_names, &p->vui.i_transfer ); |
1011 | 0 | OPT("colormatrix") |
1012 | 0 | b_error |= parse_enum( value, x264_colmatrix_names, &p->vui.i_colmatrix ); |
1013 | 0 | OPT("chromaloc") |
1014 | 0 | { |
1015 | 0 | p->vui.i_chroma_loc = atoi(value); |
1016 | 0 | b_error |= ( p->vui.i_chroma_loc < 0 || p->vui.i_chroma_loc > 5 ); |
1017 | 0 | } |
1018 | 0 | OPT("mastering-display") |
1019 | 0 | { |
1020 | 0 | if( strcasecmp( value, "undef" ) ) |
1021 | 0 | { |
1022 | 0 | b_error |= sscanf( value, "G(%d,%d)B(%d,%d)R(%d,%d)WP(%d,%d)L(%"SCNd64",%"SCNd64")", |
1023 | 0 | &p->mastering_display.i_green_x, &p->mastering_display.i_green_y, |
1024 | 0 | &p->mastering_display.i_blue_x, &p->mastering_display.i_blue_y, |
1025 | 0 | &p->mastering_display.i_red_x, &p->mastering_display.i_red_y, |
1026 | 0 | &p->mastering_display.i_white_x, &p->mastering_display.i_white_y, |
1027 | 0 | &p->mastering_display.i_display_max, &p->mastering_display.i_display_min ) != 10; |
1028 | 0 | p->mastering_display.b_mastering_display = !b_error; |
1029 | 0 | } |
1030 | 0 | else |
1031 | 0 | p->mastering_display.b_mastering_display = 0; |
1032 | 0 | } |
1033 | 0 | OPT("cll") |
1034 | 0 | { |
1035 | 0 | if( strcasecmp( value, "undef" ) ) |
1036 | 0 | { |
1037 | 0 | b_error |= sscanf( value, "%d,%d", |
1038 | 0 | &p->content_light_level.i_max_cll, &p->content_light_level.i_max_fall ) != 2; |
1039 | 0 | p->content_light_level.b_cll = !b_error; |
1040 | 0 | } |
1041 | 0 | else |
1042 | 0 | p->content_light_level.b_cll = 0; |
1043 | 0 | } |
1044 | 0 | OPT("alternative-transfer") |
1045 | 0 | b_error |= parse_enum( value, x264_transfer_names, &p->i_alternative_transfer ); |
1046 | 0 | OPT("fps") |
1047 | 0 | { |
1048 | 0 | int64_t i_fps_num; |
1049 | 0 | int64_t i_fps_den; |
1050 | 0 | if( sscanf( value, "%"SCNd64"/%"SCNd64, &i_fps_num, &i_fps_den ) == 2 ) |
1051 | 0 | { |
1052 | 0 | p->i_fps_num = i_fps_num; |
1053 | 0 | p->i_fps_den = i_fps_den; |
1054 | 0 | b_error |= i_fps_num < 1 || i_fps_num > UINT32_MAX || i_fps_den < 1 || i_fps_den > UINT32_MAX; |
1055 | 0 | } |
1056 | 0 | else |
1057 | 0 | { |
1058 | 0 | double fps = atof(value); |
1059 | 0 | if( fps < 0.0005 || fps > INT_MAX ) |
1060 | 0 | b_error = 1; |
1061 | 0 | else if( fps <= INT_MAX/1000.0 ) |
1062 | 0 | { |
1063 | 0 | p->i_fps_num = (int)(fps * 1000.0 + .5); |
1064 | 0 | p->i_fps_den = 1000; |
1065 | 0 | } |
1066 | 0 | else |
1067 | 0 | { |
1068 | 0 | p->i_fps_num = atoi(value); |
1069 | 0 | p->i_fps_den = 1; |
1070 | 0 | } |
1071 | 0 | } |
1072 | 0 | } |
1073 | 0 | OPT2("ref", "frameref") |
1074 | 0 | p->i_frame_reference = atoi(value); |
1075 | 0 | OPT("dpb-size") |
1076 | 0 | p->i_dpb_size = atoi(value); |
1077 | 0 | OPT("keyint") |
1078 | 0 | { |
1079 | 0 | if( strstr( value, "infinite" ) ) |
1080 | 0 | p->i_keyint_max = X264_KEYINT_MAX_INFINITE; |
1081 | 0 | else |
1082 | 0 | p->i_keyint_max = atoi(value); |
1083 | 0 | } |
1084 | 0 | OPT2("min-keyint", "keyint-min") |
1085 | 0 | { |
1086 | 0 | p->i_keyint_min = atoi(value); |
1087 | 0 | if( p->i_keyint_max < p->i_keyint_min ) |
1088 | 0 | p->i_keyint_max = p->i_keyint_min; |
1089 | 0 | } |
1090 | 0 | OPT("scenecut") |
1091 | 0 | { |
1092 | 0 | p->i_scenecut_threshold = atobool(value); |
1093 | 0 | if( b_error || p->i_scenecut_threshold ) |
1094 | 0 | { |
1095 | 0 | b_error = 0; |
1096 | 0 | p->i_scenecut_threshold = atoi(value); |
1097 | 0 | } |
1098 | 0 | } |
1099 | 0 | OPT("intra-refresh") |
1100 | 0 | p->b_intra_refresh = atobool(value); |
1101 | 0 | OPT("bframes") |
1102 | 0 | p->i_bframe = atoi(value); |
1103 | 0 | OPT("b-adapt") |
1104 | 0 | { |
1105 | 0 | p->i_bframe_adaptive = atobool(value); |
1106 | 0 | if( b_error ) |
1107 | 0 | { |
1108 | 0 | b_error = 0; |
1109 | 0 | p->i_bframe_adaptive = atoi(value); |
1110 | 0 | } |
1111 | 0 | } |
1112 | 0 | OPT("b-bias") |
1113 | 0 | p->i_bframe_bias = atoi(value); |
1114 | 0 | OPT("b-pyramid") |
1115 | 0 | { |
1116 | 0 | b_error |= parse_enum( value, x264_b_pyramid_names, &p->i_bframe_pyramid ); |
1117 | 0 | if( b_error ) |
1118 | 0 | { |
1119 | 0 | b_error = 0; |
1120 | 0 | p->i_bframe_pyramid = atoi(value); |
1121 | 0 | } |
1122 | 0 | } |
1123 | 0 | OPT("open-gop") |
1124 | 0 | p->b_open_gop = atobool(value); |
1125 | 0 | OPT("nf") |
1126 | 0 | p->b_deblocking_filter = !atobool(value); |
1127 | 0 | OPT2("filter", "deblock") |
1128 | 0 | { |
1129 | 0 | if( 2 == sscanf( value, "%d:%d", &p->i_deblocking_filter_alphac0, &p->i_deblocking_filter_beta ) || |
1130 | 0 | 2 == sscanf( value, "%d,%d", &p->i_deblocking_filter_alphac0, &p->i_deblocking_filter_beta ) ) |
1131 | 0 | { |
1132 | 0 | p->b_deblocking_filter = 1; |
1133 | 0 | } |
1134 | 0 | else if( sscanf( value, "%d", &p->i_deblocking_filter_alphac0 ) ) |
1135 | 0 | { |
1136 | 0 | p->b_deblocking_filter = 1; |
1137 | 0 | p->i_deblocking_filter_beta = p->i_deblocking_filter_alphac0; |
1138 | 0 | } |
1139 | 0 | else |
1140 | 0 | p->b_deblocking_filter = atobool(value); |
1141 | 0 | } |
1142 | 0 | OPT("slice-max-size") |
1143 | 0 | p->i_slice_max_size = atoi(value); |
1144 | 0 | OPT("slice-max-mbs") |
1145 | 0 | p->i_slice_max_mbs = atoi(value); |
1146 | 0 | OPT("slice-min-mbs") |
1147 | 0 | p->i_slice_min_mbs = atoi(value); |
1148 | 0 | OPT("slices") |
1149 | 0 | p->i_slice_count = atoi(value); |
1150 | 0 | OPT("slices-max") |
1151 | 0 | p->i_slice_count_max = atoi(value); |
1152 | 0 | OPT("cabac") |
1153 | 0 | p->b_cabac = atobool(value); |
1154 | 0 | OPT("cabac-idc") |
1155 | 0 | p->i_cabac_init_idc = atoi(value); |
1156 | 0 | OPT("interlaced") |
1157 | 0 | p->b_interlaced = atobool(value); |
1158 | 0 | OPT("tff") |
1159 | 0 | p->b_interlaced = p->b_tff = atobool(value); |
1160 | 0 | OPT("bff") |
1161 | 0 | { |
1162 | 0 | p->b_interlaced = atobool(value); |
1163 | 0 | p->b_tff = !p->b_interlaced; |
1164 | 0 | } |
1165 | 0 | OPT("constrained-intra") |
1166 | 0 | p->b_constrained_intra = atobool(value); |
1167 | 0 | OPT("cqm") |
1168 | 0 | { |
1169 | 0 | if( strstr( value, "flat" ) ) |
1170 | 0 | p->i_cqm_preset = X264_CQM_FLAT; |
1171 | 0 | else if( strstr( value, "jvt" ) ) |
1172 | 0 | p->i_cqm_preset = X264_CQM_JVT; |
1173 | 0 | else |
1174 | 0 | CHECKED_ERROR_PARAM_STRDUP( p->psz_cqm_file, p, value ); |
1175 | 0 | } |
1176 | 0 | OPT("cqmfile") |
1177 | 0 | CHECKED_ERROR_PARAM_STRDUP( p->psz_cqm_file, p, value ); |
1178 | 0 | OPT("cqm4") |
1179 | 0 | { |
1180 | 0 | p->i_cqm_preset = X264_CQM_CUSTOM; |
1181 | 0 | b_error |= parse_cqm( value, p->cqm_4iy, 16 ); |
1182 | 0 | b_error |= parse_cqm( value, p->cqm_4py, 16 ); |
1183 | 0 | b_error |= parse_cqm( value, p->cqm_4ic, 16 ); |
1184 | 0 | b_error |= parse_cqm( value, p->cqm_4pc, 16 ); |
1185 | 0 | } |
1186 | 0 | OPT("cqm8") |
1187 | 0 | { |
1188 | 0 | p->i_cqm_preset = X264_CQM_CUSTOM; |
1189 | 0 | b_error |= parse_cqm( value, p->cqm_8iy, 64 ); |
1190 | 0 | b_error |= parse_cqm( value, p->cqm_8py, 64 ); |
1191 | 0 | b_error |= parse_cqm( value, p->cqm_8ic, 64 ); |
1192 | 0 | b_error |= parse_cqm( value, p->cqm_8pc, 64 ); |
1193 | 0 | } |
1194 | 0 | OPT("cqm4i") |
1195 | 0 | { |
1196 | 0 | p->i_cqm_preset = X264_CQM_CUSTOM; |
1197 | 0 | b_error |= parse_cqm( value, p->cqm_4iy, 16 ); |
1198 | 0 | b_error |= parse_cqm( value, p->cqm_4ic, 16 ); |
1199 | 0 | } |
1200 | 0 | OPT("cqm4p") |
1201 | 0 | { |
1202 | 0 | p->i_cqm_preset = X264_CQM_CUSTOM; |
1203 | 0 | b_error |= parse_cqm( value, p->cqm_4py, 16 ); |
1204 | 0 | b_error |= parse_cqm( value, p->cqm_4pc, 16 ); |
1205 | 0 | } |
1206 | 0 | OPT("cqm4iy") |
1207 | 0 | { |
1208 | 0 | p->i_cqm_preset = X264_CQM_CUSTOM; |
1209 | 0 | b_error |= parse_cqm( value, p->cqm_4iy, 16 ); |
1210 | 0 | } |
1211 | 0 | OPT("cqm4ic") |
1212 | 0 | { |
1213 | 0 | p->i_cqm_preset = X264_CQM_CUSTOM; |
1214 | 0 | b_error |= parse_cqm( value, p->cqm_4ic, 16 ); |
1215 | 0 | } |
1216 | 0 | OPT("cqm4py") |
1217 | 0 | { |
1218 | 0 | p->i_cqm_preset = X264_CQM_CUSTOM; |
1219 | 0 | b_error |= parse_cqm( value, p->cqm_4py, 16 ); |
1220 | 0 | } |
1221 | 0 | OPT("cqm4pc") |
1222 | 0 | { |
1223 | 0 | p->i_cqm_preset = X264_CQM_CUSTOM; |
1224 | 0 | b_error |= parse_cqm( value, p->cqm_4pc, 16 ); |
1225 | 0 | } |
1226 | 0 | OPT("cqm8i") |
1227 | 0 | { |
1228 | 0 | p->i_cqm_preset = X264_CQM_CUSTOM; |
1229 | 0 | b_error |= parse_cqm( value, p->cqm_8iy, 64 ); |
1230 | 0 | b_error |= parse_cqm( value, p->cqm_8ic, 64 ); |
1231 | 0 | } |
1232 | 0 | OPT("cqm8p") |
1233 | 0 | { |
1234 | 0 | p->i_cqm_preset = X264_CQM_CUSTOM; |
1235 | 0 | b_error |= parse_cqm( value, p->cqm_8py, 64 ); |
1236 | 0 | b_error |= parse_cqm( value, p->cqm_8pc, 64 ); |
1237 | 0 | } |
1238 | 0 | OPT("log") |
1239 | 0 | p->i_log_level = atoi(value); |
1240 | 0 | OPT("dump-yuv") |
1241 | 0 | CHECKED_ERROR_PARAM_STRDUP( p->psz_dump_yuv, p, value ); |
1242 | 0 | OPT2("analyse", "partitions") |
1243 | 0 | { |
1244 | 0 | p->analyse.inter = 0; |
1245 | 0 | if( strstr( value, "none" ) ) p->analyse.inter = 0; |
1246 | 0 | if( strstr( value, "all" ) ) p->analyse.inter = ~0; |
1247 | |
|
1248 | 0 | if( strstr( value, "i4x4" ) ) p->analyse.inter |= X264_ANALYSE_I4x4; |
1249 | 0 | if( strstr( value, "i8x8" ) ) p->analyse.inter |= X264_ANALYSE_I8x8; |
1250 | 0 | if( strstr( value, "p8x8" ) ) p->analyse.inter |= X264_ANALYSE_PSUB16x16; |
1251 | 0 | if( strstr( value, "p4x4" ) ) p->analyse.inter |= X264_ANALYSE_PSUB8x8; |
1252 | 0 | if( strstr( value, "b8x8" ) ) p->analyse.inter |= X264_ANALYSE_BSUB16x16; |
1253 | 0 | } |
1254 | 0 | OPT("8x8dct") |
1255 | 0 | p->analyse.b_transform_8x8 = atobool(value); |
1256 | 0 | OPT2("weightb", "weight-b") |
1257 | 0 | p->analyse.b_weighted_bipred = atobool(value); |
1258 | 0 | OPT("weightp") |
1259 | 0 | p->analyse.i_weighted_pred = atoi(value); |
1260 | 0 | OPT2("direct", "direct-pred") |
1261 | 0 | b_error |= parse_enum( value, x264_direct_pred_names, &p->analyse.i_direct_mv_pred ); |
1262 | 0 | OPT("chroma-qp-offset") |
1263 | 0 | p->analyse.i_chroma_qp_offset = atoi(value); |
1264 | 0 | OPT("me") |
1265 | 0 | b_error |= parse_enum( value, x264_motion_est_names, &p->analyse.i_me_method ); |
1266 | 0 | OPT2("merange", "me-range") |
1267 | 0 | p->analyse.i_me_range = atoi(value); |
1268 | 0 | OPT2("mvrange", "mv-range") |
1269 | 0 | p->analyse.i_mv_range = atoi(value); |
1270 | 0 | OPT2("mvrange-thread", "mv-range-thread") |
1271 | 0 | p->analyse.i_mv_range_thread = atoi(value); |
1272 | 0 | OPT2("subme", "subq") |
1273 | 0 | p->analyse.i_subpel_refine = atoi(value); |
1274 | 0 | OPT("psy-rd") |
1275 | 0 | { |
1276 | 0 | if( 2 == sscanf( value, "%f:%f", &p->analyse.f_psy_rd, &p->analyse.f_psy_trellis ) || |
1277 | 0 | 2 == sscanf( value, "%f,%f", &p->analyse.f_psy_rd, &p->analyse.f_psy_trellis ) || |
1278 | 0 | 2 == sscanf( value, "%f|%f", &p->analyse.f_psy_rd, &p->analyse.f_psy_trellis )) |
1279 | 0 | { } |
1280 | 0 | else if( sscanf( value, "%f", &p->analyse.f_psy_rd ) ) |
1281 | 0 | { |
1282 | 0 | p->analyse.f_psy_trellis = 0; |
1283 | 0 | } |
1284 | 0 | else |
1285 | 0 | { |
1286 | 0 | p->analyse.f_psy_rd = 0; |
1287 | 0 | p->analyse.f_psy_trellis = 0; |
1288 | 0 | } |
1289 | 0 | } |
1290 | 0 | OPT("psy") |
1291 | 0 | p->analyse.b_psy = atobool(value); |
1292 | 0 | OPT("chroma-me") |
1293 | 0 | p->analyse.b_chroma_me = atobool(value); |
1294 | 0 | OPT("mixed-refs") |
1295 | 0 | p->analyse.b_mixed_references = atobool(value); |
1296 | 0 | OPT("trellis") |
1297 | 0 | p->analyse.i_trellis = atoi(value); |
1298 | 0 | OPT("fast-pskip") |
1299 | 0 | p->analyse.b_fast_pskip = atobool(value); |
1300 | 0 | OPT("dct-decimate") |
1301 | 0 | p->analyse.b_dct_decimate = atobool(value); |
1302 | 0 | OPT("deadzone-inter") |
1303 | 0 | p->analyse.i_luma_deadzone[0] = atoi(value); |
1304 | 0 | OPT("deadzone-intra") |
1305 | 0 | p->analyse.i_luma_deadzone[1] = atoi(value); |
1306 | 0 | OPT("nr") |
1307 | 0 | p->analyse.i_noise_reduction = atoi(value); |
1308 | 0 | OPT("bitrate") |
1309 | 0 | { |
1310 | 0 | p->rc.i_bitrate = atoi(value); |
1311 | 0 | p->rc.i_rc_method = X264_RC_ABR; |
1312 | 0 | } |
1313 | 0 | OPT2("qp", "qp_constant") |
1314 | 0 | { |
1315 | 0 | p->rc.i_qp_constant = atoi(value); |
1316 | 0 | p->rc.i_rc_method = X264_RC_CQP; |
1317 | 0 | } |
1318 | 0 | OPT("crf") |
1319 | 0 | { |
1320 | 0 | p->rc.f_rf_constant = atof(value); |
1321 | 0 | p->rc.i_rc_method = X264_RC_CRF; |
1322 | 0 | } |
1323 | 0 | OPT("crf-max") |
1324 | 0 | p->rc.f_rf_constant_max = atof(value); |
1325 | 0 | OPT("rc-lookahead") |
1326 | 0 | p->rc.i_lookahead = atoi(value); |
1327 | 0 | OPT2("qpmin", "qp-min") |
1328 | 0 | p->rc.i_qp_min = atoi(value); |
1329 | 0 | OPT2("qpmax", "qp-max") |
1330 | 0 | p->rc.i_qp_max = atoi(value); |
1331 | 0 | OPT2("qpstep", "qp-step") |
1332 | 0 | p->rc.i_qp_step = atoi(value); |
1333 | 0 | OPT("ratetol") |
1334 | 0 | p->rc.f_rate_tolerance = !strncmp("inf", value, 3) ? 1e9 : atof(value); |
1335 | 0 | OPT("vbv-maxrate") |
1336 | 0 | p->rc.i_vbv_max_bitrate = atoi(value); |
1337 | 0 | OPT("vbv-bufsize") |
1338 | 0 | p->rc.i_vbv_buffer_size = atoi(value); |
1339 | 0 | OPT("vbv-init") |
1340 | 0 | p->rc.f_vbv_buffer_init = atof(value); |
1341 | 0 | OPT2("ipratio", "ip-factor") |
1342 | 0 | p->rc.f_ip_factor = atof(value); |
1343 | 0 | OPT2("pbratio", "pb-factor") |
1344 | 0 | p->rc.f_pb_factor = atof(value); |
1345 | 0 | OPT("aq-mode") |
1346 | 0 | p->rc.i_aq_mode = atoi(value); |
1347 | 0 | OPT("aq-strength") |
1348 | 0 | p->rc.f_aq_strength = atof(value); |
1349 | 0 | OPT("pass") |
1350 | 0 | { |
1351 | 0 | int pass = x264_clip3( atoi(value), 0, 3 ); |
1352 | 0 | p->rc.b_stat_write = pass & 1; |
1353 | 0 | p->rc.b_stat_read = pass & 2; |
1354 | 0 | } |
1355 | 0 | OPT("stats") |
1356 | 0 | { |
1357 | 0 | CHECKED_ERROR_PARAM_STRDUP( p->rc.psz_stat_in, p, value ); |
1358 | 0 | CHECKED_ERROR_PARAM_STRDUP( p->rc.psz_stat_out, p, value ); |
1359 | 0 | } |
1360 | 0 | OPT("qcomp") |
1361 | 0 | p->rc.f_qcompress = atof(value); |
1362 | 0 | OPT("mbtree") |
1363 | 0 | p->rc.b_mb_tree = atobool(value); |
1364 | 0 | OPT("qblur") |
1365 | 0 | p->rc.f_qblur = atof(value); |
1366 | 0 | OPT2("cplxblur", "cplx-blur") |
1367 | 0 | p->rc.f_complexity_blur = atof(value); |
1368 | 0 | OPT("zones") |
1369 | 0 | CHECKED_ERROR_PARAM_STRDUP( p->rc.psz_zones, p, value ); |
1370 | 0 | OPT("crop-rect") |
1371 | 0 | b_error |= sscanf( value, "%d,%d,%d,%d", &p->crop_rect.i_left, &p->crop_rect.i_top, |
1372 | 0 | &p->crop_rect.i_right, &p->crop_rect.i_bottom ) != 4; |
1373 | 0 | OPT("psnr") |
1374 | 0 | p->analyse.b_psnr = atobool(value); |
1375 | 0 | OPT("ssim") |
1376 | 0 | p->analyse.b_ssim = atobool(value); |
1377 | 0 | OPT("aud") |
1378 | 0 | p->b_aud = atobool(value); |
1379 | 0 | OPT("sps-id") |
1380 | 0 | p->i_sps_id = atoi(value); |
1381 | 0 | OPT("global-header") |
1382 | 0 | p->b_repeat_headers = !atobool(value); |
1383 | 0 | OPT("repeat-headers") |
1384 | 0 | p->b_repeat_headers = atobool(value); |
1385 | 0 | OPT("annexb") |
1386 | 0 | p->b_annexb = atobool(value); |
1387 | 0 | OPT("force-cfr") |
1388 | 0 | p->b_vfr_input = !atobool(value); |
1389 | 0 | OPT("nal-hrd") |
1390 | 0 | b_error |= parse_enum( value, x264_nal_hrd_names, &p->i_nal_hrd ); |
1391 | 0 | OPT("filler") |
1392 | 0 | p->rc.b_filler = atobool(value); |
1393 | 0 | OPT("pic-struct") |
1394 | 0 | p->b_pic_struct = atobool(value); |
1395 | 0 | OPT("fake-interlaced") |
1396 | 0 | p->b_fake_interlaced = atobool(value); |
1397 | 0 | OPT("frame-packing") |
1398 | 0 | p->i_frame_packing = atoi(value); |
1399 | 0 | OPT("stitchable") |
1400 | 0 | p->b_stitchable = atobool(value); |
1401 | 0 | OPT("opencl") |
1402 | 0 | p->b_opencl = atobool( value ); |
1403 | 0 | OPT("opencl-clbin") |
1404 | 0 | CHECKED_ERROR_PARAM_STRDUP( p->psz_clbin_file, p, value ); |
1405 | 0 | OPT("opencl-device") |
1406 | 0 | p->i_opencl_device = atoi( value ); |
1407 | 0 | else |
1408 | 0 | { |
1409 | 0 | b_error = 1; |
1410 | 0 | errortype = X264_PARAM_BAD_NAME; |
1411 | 0 | } |
1412 | 0 | #undef OPT |
1413 | 0 | #undef OPT2 |
1414 | 0 | #undef atobool |
1415 | 0 | #undef atoi |
1416 | 0 | #undef atof |
1417 | |
|
1418 | 0 | if( name_buf ) |
1419 | 0 | free( name_buf ); |
1420 | |
|
1421 | 0 | b_error |= value_was_null && !name_was_bool; |
1422 | 0 | return b_error ? errortype : 0; |
1423 | 0 | } |
1424 | | |
1425 | | /**************************************************************************** |
1426 | | * x264_param2string: |
1427 | | ****************************************************************************/ |
1428 | | char *x264_param2string( x264_param_t *p, int b_res ) |
1429 | 0 | { |
1430 | 0 | int len = 2000; |
1431 | 0 | char *buf, *s; |
1432 | 0 | if( p->rc.psz_zones ) |
1433 | 0 | len += strlen(p->rc.psz_zones); |
1434 | 0 | buf = s = x264_malloc( len ); |
1435 | 0 | if( !buf ) |
1436 | 0 | return NULL; |
1437 | | |
1438 | 0 | if( b_res ) |
1439 | 0 | { |
1440 | 0 | s += sprintf( s, "%dx%d ", p->i_width, p->i_height ); |
1441 | 0 | s += sprintf( s, "fps=%u/%u ", p->i_fps_num, p->i_fps_den ); |
1442 | 0 | s += sprintf( s, "timebase=%u/%u ", p->i_timebase_num, p->i_timebase_den ); |
1443 | 0 | s += sprintf( s, "bitdepth=%d ", p->i_bitdepth ); |
1444 | 0 | } |
1445 | |
|
1446 | 0 | if( p->b_opencl ) |
1447 | 0 | s += sprintf( s, "opencl=%d ", p->b_opencl ); |
1448 | 0 | s += sprintf( s, "cabac=%d", p->b_cabac ); |
1449 | 0 | s += sprintf( s, " ref=%d", p->i_frame_reference ); |
1450 | 0 | s += sprintf( s, " deblock=%d:%d:%d", p->b_deblocking_filter, |
1451 | 0 | p->i_deblocking_filter_alphac0, p->i_deblocking_filter_beta ); |
1452 | 0 | s += sprintf( s, " analyse=%#x:%#x", p->analyse.intra, p->analyse.inter ); |
1453 | 0 | s += sprintf( s, " me=%s", x264_motion_est_names[ p->analyse.i_me_method ] ); |
1454 | 0 | s += sprintf( s, " subme=%d", p->analyse.i_subpel_refine ); |
1455 | 0 | s += sprintf( s, " psy=%d", p->analyse.b_psy ); |
1456 | 0 | if( p->analyse.b_psy ) |
1457 | 0 | s += sprintf( s, " psy_rd=%.2f:%.2f", p->analyse.f_psy_rd, p->analyse.f_psy_trellis ); |
1458 | 0 | s += sprintf( s, " mixed_ref=%d", p->analyse.b_mixed_references ); |
1459 | 0 | s += sprintf( s, " me_range=%d", p->analyse.i_me_range ); |
1460 | 0 | s += sprintf( s, " chroma_me=%d", p->analyse.b_chroma_me ); |
1461 | 0 | s += sprintf( s, " trellis=%d", p->analyse.i_trellis ); |
1462 | 0 | s += sprintf( s, " 8x8dct=%d", p->analyse.b_transform_8x8 ); |
1463 | 0 | s += sprintf( s, " cqm=%d", p->i_cqm_preset ); |
1464 | 0 | s += sprintf( s, " deadzone=%d,%d", p->analyse.i_luma_deadzone[0], p->analyse.i_luma_deadzone[1] ); |
1465 | 0 | s += sprintf( s, " fast_pskip=%d", p->analyse.b_fast_pskip ); |
1466 | 0 | s += sprintf( s, " chroma_qp_offset=%d", p->analyse.i_chroma_qp_offset ); |
1467 | 0 | s += sprintf( s, " threads=%d", p->i_threads ); |
1468 | 0 | s += sprintf( s, " lookahead_threads=%d", p->i_lookahead_threads ); |
1469 | 0 | s += sprintf( s, " sliced_threads=%d", p->b_sliced_threads ); |
1470 | 0 | if( p->i_slice_count ) |
1471 | 0 | s += sprintf( s, " slices=%d", p->i_slice_count ); |
1472 | 0 | if( p->i_slice_count_max ) |
1473 | 0 | s += sprintf( s, " slices_max=%d", p->i_slice_count_max ); |
1474 | 0 | if( p->i_slice_max_size ) |
1475 | 0 | s += sprintf( s, " slice_max_size=%d", p->i_slice_max_size ); |
1476 | 0 | if( p->i_slice_max_mbs ) |
1477 | 0 | s += sprintf( s, " slice_max_mbs=%d", p->i_slice_max_mbs ); |
1478 | 0 | if( p->i_slice_min_mbs ) |
1479 | 0 | s += sprintf( s, " slice_min_mbs=%d", p->i_slice_min_mbs ); |
1480 | 0 | s += sprintf( s, " nr=%d", p->analyse.i_noise_reduction ); |
1481 | 0 | s += sprintf( s, " decimate=%d", p->analyse.b_dct_decimate ); |
1482 | 0 | s += sprintf( s, " interlaced=%s", p->b_interlaced ? p->b_tff ? "tff" : "bff" : p->b_fake_interlaced ? "fake" : "0" ); |
1483 | 0 | s += sprintf( s, " bluray_compat=%d", p->b_bluray_compat ); |
1484 | 0 | if( p->b_stitchable ) |
1485 | 0 | s += sprintf( s, " stitchable=%d", p->b_stitchable ); |
1486 | |
|
1487 | 0 | s += sprintf( s, " constrained_intra=%d", p->b_constrained_intra ); |
1488 | |
|
1489 | 0 | s += sprintf( s, " bframes=%d", p->i_bframe ); |
1490 | 0 | if( p->i_bframe ) |
1491 | 0 | { |
1492 | 0 | s += sprintf( s, " b_pyramid=%d b_adapt=%d b_bias=%d direct=%d weightb=%d open_gop=%d", |
1493 | 0 | p->i_bframe_pyramid, p->i_bframe_adaptive, p->i_bframe_bias, |
1494 | 0 | p->analyse.i_direct_mv_pred, p->analyse.b_weighted_bipred, p->b_open_gop ); |
1495 | 0 | } |
1496 | 0 | s += sprintf( s, " weightp=%d", p->analyse.i_weighted_pred > 0 ? p->analyse.i_weighted_pred : 0 ); |
1497 | |
|
1498 | 0 | if( p->i_keyint_max == X264_KEYINT_MAX_INFINITE ) |
1499 | 0 | s += sprintf( s, " keyint=infinite" ); |
1500 | 0 | else |
1501 | 0 | s += sprintf( s, " keyint=%d", p->i_keyint_max ); |
1502 | 0 | s += sprintf( s, " keyint_min=%d scenecut=%d intra_refresh=%d", |
1503 | 0 | p->i_keyint_min, p->i_scenecut_threshold, p->b_intra_refresh ); |
1504 | |
|
1505 | 0 | if( p->rc.b_mb_tree || p->rc.i_vbv_buffer_size ) |
1506 | 0 | s += sprintf( s, " rc_lookahead=%d", p->rc.i_lookahead ); |
1507 | |
|
1508 | 0 | s += sprintf( s, " rc=%s mbtree=%d", p->rc.i_rc_method == X264_RC_ABR ? |
1509 | 0 | ( p->rc.b_stat_read ? "2pass" : p->rc.i_vbv_max_bitrate == p->rc.i_bitrate ? "cbr" : "abr" ) |
1510 | 0 | : p->rc.i_rc_method == X264_RC_CRF ? "crf" : "cqp", p->rc.b_mb_tree ); |
1511 | 0 | if( p->rc.i_rc_method == X264_RC_ABR || p->rc.i_rc_method == X264_RC_CRF ) |
1512 | 0 | { |
1513 | 0 | if( p->rc.i_rc_method == X264_RC_CRF ) |
1514 | 0 | s += sprintf( s, " crf=%.1f", p->rc.f_rf_constant ); |
1515 | 0 | else |
1516 | 0 | s += sprintf( s, " bitrate=%d ratetol=%.1f", |
1517 | 0 | p->rc.i_bitrate, p->rc.f_rate_tolerance ); |
1518 | 0 | s += sprintf( s, " qcomp=%.2f qpmin=%d qpmax=%d qpstep=%d", |
1519 | 0 | p->rc.f_qcompress, p->rc.i_qp_min, p->rc.i_qp_max, p->rc.i_qp_step ); |
1520 | 0 | if( p->rc.b_stat_read ) |
1521 | 0 | s += sprintf( s, " cplxblur=%.1f qblur=%.1f", |
1522 | 0 | p->rc.f_complexity_blur, p->rc.f_qblur ); |
1523 | 0 | if( p->rc.i_vbv_buffer_size ) |
1524 | 0 | { |
1525 | 0 | s += sprintf( s, " vbv_maxrate=%d vbv_bufsize=%d", |
1526 | 0 | p->rc.i_vbv_max_bitrate, p->rc.i_vbv_buffer_size ); |
1527 | 0 | if( p->rc.i_rc_method == X264_RC_CRF ) |
1528 | 0 | s += sprintf( s, " crf_max=%.1f", p->rc.f_rf_constant_max ); |
1529 | 0 | } |
1530 | 0 | } |
1531 | 0 | else if( p->rc.i_rc_method == X264_RC_CQP ) |
1532 | 0 | s += sprintf( s, " qp=%d", p->rc.i_qp_constant ); |
1533 | |
|
1534 | 0 | if( p->rc.i_vbv_buffer_size ) |
1535 | 0 | s += sprintf( s, " nal_hrd=%s filler=%d", x264_nal_hrd_names[p->i_nal_hrd], p->rc.b_filler ); |
1536 | 0 | if( p->crop_rect.i_left | p->crop_rect.i_top | p->crop_rect.i_right | p->crop_rect.i_bottom ) |
1537 | 0 | s += sprintf( s, " crop_rect=%d,%d,%d,%d", p->crop_rect.i_left, p->crop_rect.i_top, |
1538 | 0 | p->crop_rect.i_right, p->crop_rect.i_bottom ); |
1539 | 0 | if( p->mastering_display.b_mastering_display ) |
1540 | 0 | s += sprintf( s, " mastering-display=G(%d,%d)B(%d,%d)R(%d,%d)WP(%d,%d)L(%"PRId64",%"PRId64")", |
1541 | 0 | p->mastering_display.i_green_x, p->mastering_display.i_green_y, |
1542 | 0 | p->mastering_display.i_blue_x, p->mastering_display.i_blue_y, |
1543 | 0 | p->mastering_display.i_red_x, p->mastering_display.i_red_y, |
1544 | 0 | p->mastering_display.i_white_x, p->mastering_display.i_white_y, |
1545 | 0 | p->mastering_display.i_display_max, p->mastering_display.i_display_min ); |
1546 | 0 | if( p->content_light_level.b_cll ) |
1547 | 0 | s += sprintf( s, " cll=%d,%d", |
1548 | 0 | p->content_light_level.i_max_cll, p->content_light_level.i_max_fall ); |
1549 | 0 | if( p->i_frame_packing >= 0 ) |
1550 | 0 | s += sprintf( s, " frame-packing=%d", p->i_frame_packing ); |
1551 | |
|
1552 | 0 | if( !(p->rc.i_rc_method == X264_RC_CQP && p->rc.i_qp_constant == 0) ) |
1553 | 0 | { |
1554 | 0 | s += sprintf( s, " ip_ratio=%.2f", p->rc.f_ip_factor ); |
1555 | 0 | if( p->i_bframe && !p->rc.b_mb_tree ) |
1556 | 0 | s += sprintf( s, " pb_ratio=%.2f", p->rc.f_pb_factor ); |
1557 | 0 | s += sprintf( s, " aq=%d", p->rc.i_aq_mode ); |
1558 | 0 | if( p->rc.i_aq_mode ) |
1559 | 0 | s += sprintf( s, ":%.2f", p->rc.f_aq_strength ); |
1560 | 0 | if( p->rc.psz_zones ) |
1561 | 0 | s += sprintf( s, " zones=%s", p->rc.psz_zones ); |
1562 | 0 | else if( p->rc.i_zones ) |
1563 | 0 | s += sprintf( s, " zones" ); |
1564 | 0 | } |
1565 | |
|
1566 | 0 | return buf; |
1567 | 0 | } |