New upstream version 0.148.2728+git4d5c8b0
Rico Tzschichholz
7 years ago
1253 | 1253 | endfunc |
1254 | 1254 | |
1255 | 1255 | function x264_plane_copy_core_neon, export=1 |
1256 | add x8, x4, #15 | |
1257 | and x4, x8, #~15 | |
1256 | add w8, w4, #15 // 32-bit write clears the upper 32-bit the register | |
1257 | and w4, w8, #~15 | |
1258 | // safe use of the full reg since negative width makes no sense | |
1258 | 1259 | sub x1, x1, x4 |
1259 | 1260 | sub x3, x3, x4 |
1260 | 1261 | 1: |
1270 | 1271 | subs w8, w8, #32 |
1271 | 1272 | ldp q0, q1, [x2], #32 |
1272 | 1273 | stp q0, q1, [x0], #32 |
1274 | b.gt 32b | |
1275 | 0: | |
1276 | subs w5, w5, #1 | |
1277 | add x2, x2, x3 | |
1278 | add x0, x0, x1 | |
1279 | b.gt 1b | |
1280 | ||
1281 | ret | |
1282 | endfunc | |
1283 | ||
1284 | function x264_plane_copy_swap_core_neon, export=1 | |
1285 | lsl w4, w4, #1 | |
1286 | sub x1, x1, x4 | |
1287 | sub x3, x3, x4 | |
1288 | 1: | |
1289 | mov w8, w4 | |
1290 | tbz w4, #4, 32f | |
1291 | subs w8, w8, #16 | |
1292 | ld1 {v0.16b}, [x2], #16 | |
1293 | rev16 v0.16b, v0.16b | |
1294 | st1 {v0.16b}, [x0], #16 | |
1295 | b.eq 0f | |
1296 | 32: | |
1297 | subs w8, w8, #32 | |
1298 | ld1 {v0.16b,v1.16b}, [x2], #32 | |
1299 | rev16 v0.16b, v0.16b | |
1300 | rev16 v1.16b, v1.16b | |
1301 | st1 {v0.16b,v1.16b}, [x0], #32 | |
1273 | 1302 | b.gt 32b |
1274 | 1303 | 0: |
1275 | 1304 | subs w5, w5, #1 |
50 | 50 | |
51 | 51 | void x264_plane_copy_core_neon( pixel *dst, intptr_t i_dst, |
52 | 52 | pixel *src, intptr_t i_src, int w, int h ); |
53 | void x264_plane_copy_swap_core_neon( pixel *dst, intptr_t i_dst, | |
54 | pixel *src, intptr_t i_src, int w, int h ); | |
53 | 55 | void x264_plane_copy_deinterleave_neon( pixel *dstu, intptr_t i_dstu, |
54 | 56 | pixel *dstv, intptr_t i_dstv, |
55 | 57 | pixel *src, intptr_t i_src, int w, int h ); |
207 | 209 | int height, int16_t *buf ); |
208 | 210 | |
209 | 211 | PLANE_COPY(16, neon) |
212 | PLANE_COPY_SWAP(16, neon) | |
210 | 213 | PLANE_INTERLEAVE(neon) |
211 | 214 | #endif // !HIGH_BIT_DEPTH |
212 | 215 | |
231 | 234 | pf->copy[PIXEL_4x4] = x264_mc_copy_w4_neon; |
232 | 235 | |
233 | 236 | pf->plane_copy = x264_plane_copy_neon; |
237 | pf->plane_copy_swap = x264_plane_copy_swap_neon; | |
234 | 238 | pf->plane_copy_deinterleave = x264_plane_copy_deinterleave_neon; |
235 | 239 | pf->plane_copy_deinterleave_rgb = x264_plane_copy_deinterleave_rgb_neon; |
236 | 240 | pf->plane_copy_interleave = x264_plane_copy_interleave_neon; |
210 | 210 | vclt.u8 q13, q4, q14 @ < (alpha >> 2) + 2 if_2 |
211 | 211 | vand q12, q7, q6 @ if_1 |
212 | 212 | vshrn.u16 d28, q12, #4 |
213 | vcmp.f64 d28, #0 | |
214 | vmrs APSR_nzcv, FPSCR | |
213 | vmov r2, lr, d28 | |
214 | orrs r2, r2, lr | |
215 | 215 | beq 9f |
216 | 216 | |
217 | 217 | sub sp, sp, #32 |
324 | 324 | .endm |
325 | 325 | |
326 | 326 | function x264_deblock_v_luma_intra_neon |
327 | push {lr} | |
327 | 328 | vld1.64 {d0, d1}, [r0,:128], r1 |
328 | 329 | vld1.64 {d2, d3}, [r0,:128], r1 |
329 | 330 | vld1.64 {d4, d5}, [r0,:128], r1 |
347 | 348 | vst1.64 {d4, d5}, [r0,:128] |
348 | 349 | 9: |
349 | 350 | align_pop_regs |
350 | bx lr | |
351 | pop {pc} | |
351 | 352 | endfunc |
352 | 353 | |
353 | 354 | function x264_deblock_h_luma_intra_neon |
355 | push {lr} | |
354 | 356 | sub r0, r0, #4 |
355 | 357 | vld1.64 {d22}, [r0], r1 |
356 | 358 | vld1.64 {d20}, [r0], r1 |
396 | 398 | vst1.64 {d7}, [r0], r1 |
397 | 399 | 9: |
398 | 400 | align_pop_regs |
399 | bx lr | |
401 | pop {pc} | |
400 | 402 | endfunc |
401 | 403 | |
402 | 404 | .macro h264_loop_filter_chroma |
220 | 220 | } |
221 | 221 | else if( !strcasecmp( preset, "veryfast" ) ) |
222 | 222 | { |
223 | param->analyse.i_me_method = X264_ME_HEX; | |
224 | 223 | param->analyse.i_subpel_refine = 2; |
225 | 224 | param->i_frame_reference = 1; |
226 | 225 | param->analyse.b_mixed_references = 0; |
249 | 248 | } |
250 | 249 | else if( !strcasecmp( preset, "slow" ) ) |
251 | 250 | { |
252 | param->analyse.i_me_method = X264_ME_UMH; | |
253 | 251 | param->analyse.i_subpel_refine = 8; |
254 | 252 | param->i_frame_reference = 5; |
255 | param->i_bframe_adaptive = X264_B_ADAPT_TRELLIS; | |
256 | 253 | param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_AUTO; |
254 | param->analyse.i_trellis = 2; | |
257 | 255 | param->rc.i_lookahead = 50; |
258 | 256 | } |
259 | 257 | else if( !strcasecmp( preset, "slower" ) ) |
989 | 989 | pf_progressive->scan_4x4 = x264_zigzag_scan_4x4_frame_mmx; |
990 | 990 | if( cpu&X264_CPU_MMX2 ) |
991 | 991 | { |
992 | pf_interlaced->scan_4x4 = x264_zigzag_scan_4x4_field_mmx2; | |
993 | 992 | pf_interlaced->scan_8x8 = x264_zigzag_scan_8x8_field_mmx2; |
994 | 993 | pf_progressive->scan_8x8 = x264_zigzag_scan_8x8_frame_mmx2; |
995 | 994 | } |
995 | if( cpu&X264_CPU_SSE ) | |
996 | pf_interlaced->scan_4x4 = x264_zigzag_scan_4x4_field_sse; | |
996 | 997 | if( cpu&X264_CPU_SSE2_IS_FAST ) |
997 | 998 | pf_progressive->scan_8x8 = x264_zigzag_scan_8x8_frame_sse2; |
998 | 999 | if( cpu&X264_CPU_SSSE3 ) |
3429 | 3429 | x264_mc_weight_w8_msa( p_dst, *p_dst_stride, |
3430 | 3430 | p_dst, *p_dst_stride, |
3431 | 3431 | pWeight, i_h4w ); |
3432 | for( i_cnt = i_h4w; i_cnt < i_height ; i_cnt++ ) | |
3432 | for( i_cnt = i_h4w; i_cnt < i_height; i_cnt++ ) | |
3433 | 3433 | { |
3434 | 3434 | uint64_t temp0; |
3435 | 3435 | v16i8 zero = {0}; |
3665 | 3665 | pWeight, i_h4w ); |
3666 | 3666 | p_src1 = src1_org + i_h4w * i_src_stride; |
3667 | 3667 | |
3668 | for( i_cnt = i_h4w; i_cnt < i_height ; i_cnt++ ) | |
3668 | for( i_cnt = i_h4w; i_cnt < i_height; i_cnt++ ) | |
3669 | 3669 | { |
3670 | 3670 | uint64_t u_temp0; |
3671 | 3671 | v16i8 zero = {0}; |
369 | 369 | h->mb.i_partition = partition_col[0]; |
370 | 370 | } |
371 | 371 | } |
372 | int i_mb_4x4 = b_interlaced ? 4 * (h->mb.i_b4_stride*mb_y + mb_x) : h->mb.i_b4_xy ; | |
373 | int i_mb_8x8 = b_interlaced ? 2 * (h->mb.i_b8_stride*mb_y + mb_x) : h->mb.i_b8_xy ; | |
372 | int i_mb_4x4 = b_interlaced ? 4 * (h->mb.i_b4_stride*mb_y + mb_x) : h->mb.i_b4_xy; | |
373 | int i_mb_8x8 = b_interlaced ? 2 * (h->mb.i_b8_stride*mb_y + mb_x) : h->mb.i_b8_xy; | |
374 | 374 | |
375 | 375 | int8_t *l1ref0 = &h->fref[1][0]->ref[0][i_mb_8x8]; |
376 | 376 | int8_t *l1ref1 = &h->fref[1][0]->ref[1][i_mb_8x8]; |
248 | 248 | static ALWAYS_INLINE int x264_pthread_fetch_and_add( int *val, int add, x264_pthread_mutex_t *mutex ) |
249 | 249 | { |
250 | 250 | #if HAVE_THREAD |
251 | #if defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ > 0) && ARCH_X86 | |
251 | #if defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ > 0) && (ARCH_X86 || ARCH_X86_64) | |
252 | 252 | return __sync_fetch_and_add( val, add ); |
253 | 253 | #else |
254 | 254 | x264_pthread_mutex_lock( mutex ); |
555 | 555 | #if HIGH_BIT_DEPTH |
556 | 556 | #define x264_predict_8x8c_v_mmx2 x264_predict_8x8c_v_mmx |
557 | 557 | #define x264_predict_8x16c_v_mmx2 x264_predict_8x16c_v_c |
558 | #define x264_predict_16x16_dc_mmx2 x264_predict_16x16_dc_c | |
558 | 559 | #define x264_predict_8x8c_v_sse2 x264_predict_8x8c_v_sse |
559 | 560 | #define x264_predict_8x16c_v_sse2 x264_predict_8x16c_v_sse |
560 | 561 | #define x264_predict_16x16_v_sse2 x264_predict_16x16_v_sse |
883 | 884 | INIT8( ssd, _mmx2 ); |
884 | 885 | INIT_ADS( _mmx2 ); |
885 | 886 | |
886 | pixf->ssd_nv12_core = x264_pixel_ssd_nv12_core_mmx2; | |
887 | 887 | pixf->var[PIXEL_16x16] = x264_pixel_var_16x16_mmx2; |
888 | 888 | pixf->var[PIXEL_8x8] = x264_pixel_var_8x8_mmx2; |
889 | 889 | #if ARCH_X86 |
1069 | 1069 | pixf->var[PIXEL_16x16] = x264_pixel_var_16x16_mmx2; |
1070 | 1070 | pixf->var[PIXEL_8x16] = x264_pixel_var_8x16_mmx2; |
1071 | 1071 | pixf->var[PIXEL_8x8] = x264_pixel_var_8x8_mmx2; |
1072 | pixf->ssd_nv12_core = x264_pixel_ssd_nv12_core_mmx2; | |
1073 | 1072 | #if ARCH_X86 |
1074 | 1073 | pixf->sa8d[PIXEL_16x16] = x264_pixel_sa8d_16x16_mmx2; |
1075 | 1074 | pixf->sa8d[PIXEL_8x8] = x264_pixel_sa8d_8x8_mmx2; |
1811 | 1811 | d3 = vec_sub(t1, t3); \ |
1812 | 1812 | } |
1813 | 1813 | |
1814 | #ifdef WORDS_BIGENDIAN | |
1815 | #define vec_perm_extend_s16(val, perm) (vec_s16_t)vec_perm(val, zero_u8v, perm) | |
1816 | #else | |
1817 | #define vec_perm_extend_s16(val, perm) (vec_s16_t)vec_perm(zero_u8v, val, perm) | |
1818 | #endif | |
1819 | ||
1814 | 1820 | #define VEC_LOAD_HIGH( p, num ) \ |
1815 | 1821 | vec_u8_t pix8_##num = vec_ld( stride*num, p ); \ |
1816 | vec_s16_t pix16_s##num = (vec_s16_t)vec_perm(pix8_##num, zero_u8v, perm); \ | |
1822 | vec_s16_t pix16_s##num = vec_perm_extend_s16( pix8_##num, perm ); \ | |
1817 | 1823 | vec_s16_t pix16_d##num; |
1818 | 1824 | |
1819 | 1825 | static uint64_t pixel_hadamard_ac_altivec( uint8_t *pix, intptr_t stride, const vec_u8_t perm ) |
70 | 70 | vec_u32_t multEvenvA, multOddvA; |
71 | 71 | vec_u16_t mfvA; |
72 | 72 | vec_u16_t biasvA; |
73 | vec_s16_t one = vec_splat_s16(1);; | |
73 | vec_s16_t one = vec_splat_s16(1); | |
74 | 74 | vec_s16_t nz = zero_s16v; |
75 | 75 | |
76 | 76 | vector bool short mskB; |
215 | 215 | vec_u32_t multEvenvA, multOddvA; |
216 | 216 | vec_u16_t mfvA; |
217 | 217 | vec_u16_t biasvA; |
218 | vec_s16_t one = vec_splat_s16(1);; | |
218 | vec_s16_t one = vec_splat_s16(1); | |
219 | 219 | vec_s16_t nz = zero_s16v; |
220 | 220 | |
221 | 221 | vector bool short mskB; |
37 | 37 | const pw_pixel_max,times 16 dw ((1 << BIT_DEPTH)-1) |
38 | 38 | const pw_0to15, dw 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 |
39 | 39 | const pd_1, times 8 dd 1 |
40 | const pd_0123, dd 0,1,2,3 | |
41 | const pd_4567, dd 4,5,6,7 | |
40 | 42 | const deinterleave_shufd, dd 0,4,1,5,2,6,3,7 |
41 | 43 | const pb_unpackbd1, times 2 db 0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3 |
42 | 44 | const pb_unpackbd2, times 2 db 4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7 |
62 | 64 | const pw_pmpmpmpm, dw 1,-1,1,-1,1,-1,1,-1 |
63 | 65 | const pw_pmmpzzzz, dw 1,-1,-1,1,0,0,0,0 |
64 | 66 | |
67 | const pd_8, times 4 dd 8 | |
65 | 68 | const pd_32, times 4 dd 32 |
66 | 69 | const pd_1024, times 4 dd 1024 |
67 | 70 | const pd_ffff, times 4 dd 0xffff |
1462 | 1462 | ; void zigzag_scan_4x4_field( int32_t level[16], int32_t dct[4][4] ) |
1463 | 1463 | ;----------------------------------------------------------------------------- |
1464 | 1464 | INIT_XMM sse2 |
1465 | cglobal zigzag_scan_4x4_field, 2,3 | |
1466 | movu m4, [r1+ 8] | |
1467 | pshufd m0, m4, q3102 | |
1465 | cglobal zigzag_scan_4x4_field, 2,2 | |
1466 | movu m0, [r1+ 8] | |
1467 | pshufd m0, m0, q3102 | |
1468 | 1468 | mova m1, [r1+32] |
1469 | 1469 | mova m2, [r1+48] |
1470 | 1470 | movu [r0+ 8], m0 |
1479 | 1479 | ;----------------------------------------------------------------------------- |
1480 | 1480 | ; void zigzag_scan_4x4_field( int16_t level[16], int16_t dct[4][4] ) |
1481 | 1481 | ;----------------------------------------------------------------------------- |
1482 | ; sse2 is only 1 cycle faster, and ssse3/pshufb is slower on core2 | |
1483 | INIT_MMX mmx2 | |
1484 | cglobal zigzag_scan_4x4_field, 2,3 | |
1485 | pshufw m0, [r1+4], q3102 | |
1486 | mova m1, [r1+16] | |
1487 | mova m2, [r1+24] | |
1488 | movu [r0+4], m0 | |
1489 | mova [r0+16], m1 | |
1490 | mova [r0+24], m2 | |
1491 | mov r2d, [r1] | |
1492 | mov [r0], r2d | |
1493 | mov r2d, [r1+12] | |
1494 | mov [r0+12], r2d | |
1482 | INIT_XMM sse | |
1483 | cglobal zigzag_scan_4x4_field, 2,2 | |
1484 | mova m0, [r1] | |
1485 | mova m1, [r1+16] | |
1486 | pshufw mm0, [r1+4], q3102 | |
1487 | mova [r0], m0 | |
1488 | mova [r0+16], m1 | |
1489 | movq [r0+4], mm0 | |
1495 | 1490 | RET |
1496 | 1491 | %endif ; HIGH_BIT_DEPTH |
1497 | 1492 |
111 | 111 | void x264_zigzag_scan_4x4_frame_sse2 ( int32_t level[16], int32_t dct[16] ); |
112 | 112 | void x264_zigzag_scan_4x4_frame_mmx ( int16_t level[16], int16_t dct[16] ); |
113 | 113 | void x264_zigzag_scan_4x4_field_sse2 ( int32_t level[16], int32_t dct[16] ); |
114 | void x264_zigzag_scan_4x4_field_mmx2 ( int16_t level[16], int16_t dct[16] ); | |
114 | void x264_zigzag_scan_4x4_field_sse ( int16_t level[16], int16_t dct[16] ); | |
115 | 115 | void x264_zigzag_scan_8x8_field_xop ( int16_t level[64], int16_t dct[64] ); |
116 | 116 | void x264_zigzag_scan_8x8_field_avx ( int32_t level[64], int32_t dct[64] ); |
117 | 117 | void x264_zigzag_scan_8x8_field_sse4 ( int32_t level[64], int32_t dct[64] ); |
66 | 66 | pf_inv256: times 4 dd 0.00390625 |
67 | 67 | |
68 | 68 | pd_16: times 4 dd 16 |
69 | pd_0f: times 4 dd 0xffff | |
70 | 69 | |
71 | 70 | pad10: times 8 dw 10*PIXEL_MAX |
72 | 71 | pad20: times 8 dw 20*PIXEL_MAX |
93 | 92 | cextern pw_3fff |
94 | 93 | cextern pw_pixel_max |
95 | 94 | cextern pw_0to15 |
95 | cextern pd_8 | |
96 | cextern pd_0123 | |
96 | 97 | cextern pd_ffff |
97 | 98 | |
98 | 99 | %macro LOAD_ADD 4 |
284 | 285 | psrad m1, 10 |
285 | 286 | psrad m2, 10 |
286 | 287 | pslld m2, 16 |
287 | pand m1, [pd_0f] | |
288 | pand m1, [pd_ffff] | |
288 | 289 | por m1, m2 |
289 | 290 | CLIPW m1, [pb_0], [pw_pixel_max] |
290 | 291 | mova [r0+r2], m1 |
2177 | 2178 | |
2178 | 2179 | %macro MBTREE_PROPAGATE_LIST 0 |
2179 | 2180 | ;----------------------------------------------------------------------------- |
2180 | ; void mbtree_propagate_list_internal( int16_t (*mvs)[2], int *propagate_amount, uint16_t *lowres_costs, | |
2181 | ; void mbtree_propagate_list_internal( int16_t (*mvs)[2], int16_t *propagate_amount, uint16_t *lowres_costs, | |
2181 | 2182 | ; int16_t *output, int bipred_weight, int mb_y, int len ) |
2182 | 2183 | ;----------------------------------------------------------------------------- |
2183 | 2184 | cglobal mbtree_propagate_list_internal, 4,6,8 |
2266 | 2267 | MBTREE_PROPAGATE_LIST |
2267 | 2268 | INIT_XMM avx |
2268 | 2269 | MBTREE_PROPAGATE_LIST |
2270 | ||
2271 | INIT_YMM avx2 | |
2272 | cglobal mbtree_propagate_list_internal, 4+2*UNIX64,5+UNIX64,8 | |
2273 | mova xm4, [pw_0xc000] | |
2274 | %if UNIX64 | |
2275 | shl r4d, 9 | |
2276 | shl r5d, 16 | |
2277 | movd xm5, r4d | |
2278 | movd xm6, r5d | |
2279 | vpbroadcastw xm5, xm5 | |
2280 | vpbroadcastd m6, xm6 | |
2281 | %else | |
2282 | vpbroadcastw xm5, r4m | |
2283 | vpbroadcastd m6, r5m | |
2284 | psllw xm5, 9 ; bipred_weight << 9 | |
2285 | pslld m6, 16 | |
2286 | %endif | |
2287 | mov r4d, r6m | |
2288 | lea r1, [r1+r4*2] | |
2289 | lea r2, [r2+r4*2] | |
2290 | lea r0, [r0+r4*4] | |
2291 | neg r4 | |
2292 | por m6, [pd_0123] ; 0 y 1 y 2 y 3 y 4 y 5 y 6 y 7 y | |
2293 | vbroadcasti128 m7, [pw_31] | |
2294 | .loop: | |
2295 | mova xm3, [r1+r4*2] | |
2296 | pand xm0, xm4, [r2+r4*2] | |
2297 | pmulhrsw xm1, xm3, xm5 ; bipred_amount = (propagate_amount * bipred_weight + 32) >> 6 | |
2298 | pcmpeqw xm0, xm4 | |
2299 | pblendvb xm3, xm3, xm1, xm0 ; (lists_used == 3) ? bipred_amount : propagate_amount | |
2300 | vpermq m3, m3, q1100 | |
2301 | ||
2302 | movu m0, [r0+r4*4] ; {x, y} | |
2303 | vbroadcasti128 m1, [pd_8] | |
2304 | psraw m2, m0, 5 | |
2305 | paddw m2, m6 ; {mbx, mby} = ({x, y} >> 5) + {h->mb.i_mb_x, h->mb.i_mb_y} | |
2306 | paddw m6, m1 ; i_mb_x += 8 | |
2307 | mova [r3], m2 | |
2308 | ||
2309 | mova m1, [pw_32] | |
2310 | pand m0, m7 | |
2311 | psubw m1, m0 | |
2312 | packuswb m1, m0 ; {32-x, 32-y} {x, y} {32-x, 32-y} {x, y} | |
2313 | psrlw m0, m1, 3 | |
2314 | pand m1, [pw_00ff] ; 32-x x 32-x x | |
2315 | pandn m0, m7, m0 ; (32-y y 32-y y) << 5 | |
2316 | pshufd m2, m1, q1032 | |
2317 | pmullw m1, m0 ; idx0 idx3 idx0 idx3 | |
2318 | pmullw m2, m0 ; idx1 idx2 idx1 idx2 | |
2319 | ||
2320 | pmulhrsw m0, m1, m3 ; (idx0 idx3 idx0 idx3) * propagate_amount + 512 >> 10 | |
2321 | pmulhrsw m2, m3 ; (idx1 idx2 idx1 idx2) * propagate_amount + 512 >> 10 | |
2322 | psignw m0, m1 ; correct potential overflow in the idx0 input to pmulhrsw | |
2323 | punpcklwd m1, m0, m2 ; idx01weight | |
2324 | punpckhwd m2, m0 ; idx23weight | |
2325 | mova [r3+32], m1 | |
2326 | mova [r3+64], m2 | |
2327 | add r3, 3*mmsize | |
2328 | add r4, 8 | |
2329 | jl .loop | |
2330 | RET | |
2269 | 2331 | |
2270 | 2332 | %macro MBTREE_FIX8 0 |
2271 | 2333 | ;----------------------------------------------------------------------------- |
531 | 531 | |
532 | 532 | PROPAGATE_LIST(ssse3) |
533 | 533 | PROPAGATE_LIST(avx) |
534 | PROPAGATE_LIST(avx2) | |
534 | 535 | |
535 | 536 | void x264_mc_init_mmx( int cpu, x264_mc_functions_t *pf ) |
536 | 537 | { |
842 | 843 | pf->plane_copy_swap = x264_plane_copy_swap_avx2; |
843 | 844 | pf->get_ref = get_ref_avx2; |
844 | 845 | pf->mbtree_propagate_cost = x264_mbtree_propagate_cost_avx2; |
846 | pf->mbtree_propagate_list = x264_mbtree_propagate_list_avx2; | |
845 | 847 | pf->mbtree_fix8_pack = x264_mbtree_fix8_pack_avx2; |
846 | 848 | pf->mbtree_fix8_unpack = x264_mbtree_fix8_unpack_avx2; |
847 | 849 | } |
42 | 42 | mask_ac4: times 2 dw 0, -1, -1, -1, 0, -1, -1, -1 |
43 | 43 | mask_ac4b: times 2 dw 0, -1, 0, -1, -1, -1, -1, -1 |
44 | 44 | mask_ac8: times 2 dw 0, -1, -1, -1, -1, -1, -1, -1 |
45 | %if HIGH_BIT_DEPTH | |
46 | ssd_nv12_shuf: db 0, 1, 4, 5, 2, 3, 6, 7, 8, 9, 12, 13, 10, 11, 14, 15 | |
47 | %endif | |
45 | 48 | %if BIT_DEPTH == 10 |
46 | 49 | ssim_c1: times 4 dd 6697.7856 ; .01*.01*1023*1023*64 |
47 | 50 | ssim_c2: times 4 dd 3797644.4352 ; .03*.03*1023*1023*64*63 |
530 | 533 | ; |
531 | 534 | ; 2 * mmsize/32 * (2^32 - 1) / (2^BIT_DEPTH - 1)^2 |
532 | 535 | ; |
533 | ; For 10-bit MMX this means width >= 16416 and for XMM >= 32832. At sane | |
534 | ; distortion levels it will take much more than that though. | |
536 | ; For 10-bit XMM this means width >= 32832. At sane distortion levels | |
537 | ; it will take much more than that though. | |
535 | 538 | ;----------------------------------------------------------------------------- |
536 | 539 | %if HIGH_BIT_DEPTH |
537 | 540 | %macro SSD_NV12 0 |
540 | 543 | FIX_STRIDES r1, r3 |
541 | 544 | add r0, r4 |
542 | 545 | add r2, r4 |
543 | xor r6, r6 | |
546 | neg r4 | |
544 | 547 | pxor m4, m4 |
545 | 548 | pxor m5, m5 |
546 | pxor m6, m6 | |
549 | %if mmsize == 32 | |
550 | vbroadcasti128 m6, [ssd_nv12_shuf] | |
551 | %endif | |
547 | 552 | .loopy: |
548 | 553 | mov r6, r4 |
549 | neg r6 | |
550 | 554 | pxor m2, m2 |
551 | 555 | pxor m3, m3 |
552 | 556 | .loopx: |
554 | 558 | mova m1, [r0+r6+mmsize] |
555 | 559 | psubw m0, [r2+r6] |
556 | 560 | psubw m1, [r2+r6+mmsize] |
557 | PSHUFLW m0, m0, q3120 | |
558 | PSHUFLW m1, m1, q3120 | |
559 | %if mmsize >= 16 | |
560 | pshufhw m0, m0, q3120 | |
561 | pshufhw m1, m1, q3120 | |
561 | %if mmsize == 32 | |
562 | pshufb m0, m6 | |
563 | pshufb m1, m6 | |
564 | %else | |
565 | SBUTTERFLY wd, 0, 1, 6 | |
562 | 566 | %endif |
563 | 567 | %if cpuflag(xop) |
564 | 568 | pmadcswd m2, m0, m0, m2 |
576 | 580 | psubd m3, m1 |
577 | 581 | .no_overread: |
578 | 582 | %endif |
579 | %if mmsize >= 16 ; using HADDD would remove the mmsize/32 part from the | |
580 | ; equation above, putting the width limit at 8208 | |
581 | punpckhdq m0, m2, m6 | |
582 | punpckhdq m1, m3, m6 | |
583 | punpckldq m2, m6 | |
584 | punpckldq m3, m6 | |
585 | paddq m3, m2 | |
586 | paddq m1, m0 | |
587 | paddq m4, m3 | |
588 | paddq m4, m1 | |
589 | %else ; unfortunately paddq is sse2 | |
590 | ; emulate 48 bit precision for mmx2 instead | |
591 | mova m0, m2 | |
592 | mova m1, m3 | |
593 | punpcklwd m2, m6 | |
594 | punpcklwd m3, m6 | |
595 | punpckhwd m0, m6 | |
596 | punpckhwd m1, m6 | |
597 | paddd m3, m2 | |
598 | paddd m1, m0 | |
599 | paddd m4, m3 | |
600 | paddd m5, m1 | |
601 | %endif | |
583 | punpckhdq m0, m2, m5 ; using HADDD would remove the mmsize/32 part from the | |
584 | punpckhdq m1, m3, m5 ; equation above, putting the width limit at 8208 | |
585 | punpckldq m2, m5 | |
586 | punpckldq m3, m5 | |
587 | paddq m0, m1 | |
588 | paddq m2, m3 | |
589 | paddq m4, m0 | |
590 | paddq m4, m2 | |
602 | 591 | add r0, r1 |
603 | 592 | add r2, r3 |
604 | 593 | dec r5d |
605 | 594 | jg .loopy |
606 | mov r3, r6m | |
607 | mov r4, r7m | |
595 | mov r0, r6m | |
596 | mov r1, r7m | |
608 | 597 | %if mmsize == 32 |
609 | 598 | vextracti128 xm0, m4, 1 |
610 | 599 | paddq xm4, xm0 |
611 | 600 | %endif |
612 | %if mmsize >= 16 | |
613 | movq [r3], xm4 | |
614 | movhps [r4], xm4 | |
615 | %else ; fixup for mmx2 | |
616 | SBUTTERFLY dq, 4, 5, 0 | |
617 | mova m0, m4 | |
618 | psrld m4, 16 | |
619 | paddd m5, m4 | |
620 | pslld m0, 16 | |
621 | SBUTTERFLY dq, 0, 5, 4 | |
622 | psrlq m0, 16 | |
623 | psrlq m5, 16 | |
624 | movq [r3], m0 | |
625 | movq [r4], m5 | |
626 | %endif | |
601 | movq [r0], xm4 | |
602 | movhps [r1], xm4 | |
627 | 603 | RET |
628 | 604 | %endmacro ; SSD_NV12 |
629 | %endif ; HIGH_BIT_DEPTH | |
630 | ||
631 | %if HIGH_BIT_DEPTH == 0 | |
605 | ||
606 | %else ; !HIGH_BIT_DEPTH | |
632 | 607 | ;----------------------------------------------------------------------------- |
633 | 608 | ; void pixel_ssd_nv12_core( uint8_t *pixuv1, intptr_t stride1, uint8_t *pixuv2, intptr_t stride2, |
634 | 609 | ; int width, int height, uint64_t *ssd_u, uint64_t *ssd_v ) |
642 | 617 | add r4d, r4d |
643 | 618 | add r0, r4 |
644 | 619 | add r2, r4 |
620 | neg r4 | |
645 | 621 | pxor m3, m3 |
646 | 622 | pxor m4, m4 |
647 | 623 | mova m5, [pw_00ff] |
648 | 624 | .loopy: |
649 | 625 | mov r6, r4 |
650 | neg r6 | |
651 | 626 | .loopx: |
652 | 627 | %if mmsize == 32 ; only 16-byte alignment is guaranteed |
653 | 628 | movu m2, [r0+r6] |
685 | 660 | add r2, r3 |
686 | 661 | dec r5d |
687 | 662 | jg .loopy |
688 | mov r3, r6m | |
689 | mov r4, r7m | |
690 | HADDD m3, m0 | |
691 | HADDD m4, m0 | |
692 | pxor xm0, xm0 | |
693 | punpckldq xm3, xm0 | |
694 | punpckldq xm4, xm0 | |
695 | movq [r3], xm3 | |
696 | movq [r4], xm4 | |
663 | mov r0, r6m | |
664 | mov r1, r7m | |
665 | %if cpuflag(ssse3) | |
666 | phaddd m3, m4 | |
667 | %else | |
668 | SBUTTERFLY qdq, 3, 4, 0 | |
669 | paddd m3, m4 | |
670 | %endif | |
671 | %if mmsize == 32 | |
672 | vextracti128 xm4, m3, 1 | |
673 | paddd xm3, xm4 | |
674 | %endif | |
675 | psllq xm4, xm3, 32 | |
676 | paddd xm3, xm4 | |
677 | psrlq xm3, 32 | |
678 | movq [r0], xm3 | |
679 | movhps [r1], xm3 | |
697 | 680 | RET |
698 | 681 | %endmacro ; SSD_NV12 |
699 | 682 | %endif ; !HIGH_BIT_DEPTH |
700 | 683 | |
701 | INIT_MMX mmx2 | |
702 | SSD_NV12 | |
703 | 684 | INIT_XMM sse2 |
704 | 685 | SSD_NV12 |
705 | 686 | INIT_XMM avx |
4613 | 4594 | ;----------------------------------------------------------------------------- |
4614 | 4595 | %macro SSIM_ITER 1 |
4615 | 4596 | %if HIGH_BIT_DEPTH |
4616 | movdqu m5, [r0+(%1&1)*r1] | |
4617 | movdqu m6, [r2+(%1&1)*r3] | |
4618 | %else | |
4619 | movq m5, [r0+(%1&1)*r1] | |
4620 | movq m6, [r2+(%1&1)*r3] | |
4621 | punpcklbw m5, m0 | |
4622 | punpcklbw m6, m0 | |
4597 | movu m4, [r0+(%1&1)*r1] | |
4598 | movu m5, [r2+(%1&1)*r3] | |
4599 | %elif cpuflag(avx) | |
4600 | pmovzxbw m4, [r0+(%1&1)*r1] | |
4601 | pmovzxbw m5, [r2+(%1&1)*r3] | |
4602 | %else | |
4603 | movq m4, [r0+(%1&1)*r1] | |
4604 | movq m5, [r2+(%1&1)*r3] | |
4605 | punpcklbw m4, m7 | |
4606 | punpcklbw m5, m7 | |
4623 | 4607 | %endif |
4624 | 4608 | %if %1==1 |
4625 | 4609 | lea r0, [r0+r1*2] |
4626 | 4610 | lea r2, [r2+r3*2] |
4627 | 4611 | %endif |
4628 | %if %1==0 | |
4629 | movdqa m1, m5 | |
4630 | movdqa m2, m6 | |
4631 | %else | |
4612 | %if %1 == 0 && cpuflag(avx) | |
4613 | SWAP 0, 4 | |
4614 | SWAP 1, 5 | |
4615 | pmaddwd m4, m0, m0 | |
4616 | pmaddwd m5, m1, m1 | |
4617 | pmaddwd m6, m0, m1 | |
4618 | %else | |
4619 | %if %1 == 0 | |
4620 | mova m0, m4 | |
4621 | mova m1, m5 | |
4622 | %else | |
4623 | paddw m0, m4 | |
4632 | 4624 | paddw m1, m5 |
4633 | paddw m2, m6 | |
4634 | %endif | |
4635 | pmaddwd m7, m5, m6 | |
4625 | %endif | |
4626 | pmaddwd m6, m4, m5 | |
4627 | pmaddwd m4, m4 | |
4636 | 4628 | pmaddwd m5, m5 |
4637 | pmaddwd m6, m6 | |
4638 | ACCUM paddd, 3, 5, %1 | |
4639 | ACCUM paddd, 4, 7, %1 | |
4640 | paddd m3, m6 | |
4629 | %endif | |
4630 | ACCUM paddd, 2, 4, %1 | |
4631 | ACCUM paddd, 3, 6, %1 | |
4632 | paddd m2, m5 | |
4641 | 4633 | %endmacro |
4642 | 4634 | |
4643 | 4635 | %macro SSIM 0 |
4644 | cglobal pixel_ssim_4x4x2_core, 4,4,8 | |
4636 | %if HIGH_BIT_DEPTH | |
4637 | cglobal pixel_ssim_4x4x2_core, 4,4,7 | |
4645 | 4638 | FIX_STRIDES r1, r3 |
4646 | pxor m0, m0 | |
4639 | %else | |
4640 | cglobal pixel_ssim_4x4x2_core, 4,4,7+notcpuflag(avx) | |
4641 | %if notcpuflag(avx) | |
4642 | pxor m7, m7 | |
4643 | %endif | |
4644 | %endif | |
4647 | 4645 | SSIM_ITER 0 |
4648 | 4646 | SSIM_ITER 1 |
4649 | 4647 | SSIM_ITER 2 |
4650 | 4648 | SSIM_ITER 3 |
4651 | ; PHADDW m1, m2 | |
4652 | ; PHADDD m3, m4 | |
4653 | movdqa m7, [pw_1] | |
4654 | pshufd m5, m3, q2301 | |
4655 | pmaddwd m1, m7 | |
4656 | pmaddwd m2, m7 | |
4657 | pshufd m6, m4, q2301 | |
4658 | packssdw m1, m2 | |
4659 | paddd m3, m5 | |
4660 | pshufd m1, m1, q3120 | |
4661 | paddd m4, m6 | |
4662 | pmaddwd m1, m7 | |
4663 | punpckhdq m5, m3, m4 | |
4664 | punpckldq m3, m4 | |
4665 | ||
4666 | 4649 | %if UNIX64 |
4667 | %define t0 r4 | |
4668 | %else | |
4669 | %define t0 rax | |
4670 | mov t0, r4mp | |
4671 | %endif | |
4672 | ||
4673 | movq [t0+ 0], m1 | |
4674 | movq [t0+ 8], m3 | |
4675 | movhps [t0+16], m1 | |
4676 | movq [t0+24], m5 | |
4650 | DECLARE_REG_TMP 4 | |
4651 | %else | |
4652 | DECLARE_REG_TMP 0 | |
4653 | mov t0, r4mp | |
4654 | %endif | |
4655 | %if cpuflag(ssse3) | |
4656 | phaddw m0, m1 | |
4657 | pmaddwd m0, [pw_1] | |
4658 | phaddd m2, m3 | |
4659 | %else | |
4660 | mova m4, [pw_1] | |
4661 | pmaddwd m0, m4 | |
4662 | pmaddwd m1, m4 | |
4663 | packssdw m0, m1 | |
4664 | shufps m1, m2, m3, q2020 | |
4665 | shufps m2, m3, q3131 | |
4666 | pmaddwd m0, m4 | |
4667 | paddd m2, m1 | |
4668 | %endif | |
4669 | shufps m1, m0, m2, q2020 | |
4670 | shufps m0, m2, q3131 | |
4671 | mova [t0], m1 | |
4672 | mova [t0+16], m0 | |
4677 | 4673 | RET |
4678 | 4674 | |
4679 | 4675 | ;----------------------------------------------------------------------------- |
144 | 144 | int x264_intra_sad_x9_8x8_avx ( uint8_t *, uint8_t *, uint8_t *, uint16_t *, uint16_t * ); |
145 | 145 | int x264_intra_sad_x9_8x8_avx2 ( uint8_t *, uint8_t *, uint8_t *, uint16_t *, uint16_t * ); |
146 | 146 | |
147 | void x264_pixel_ssd_nv12_core_mmx2( pixel *pixuv1, intptr_t stride1, | |
148 | pixel *pixuv2, intptr_t stride2, int width, | |
149 | int height, uint64_t *ssd_u, uint64_t *ssd_v ); | |
150 | 147 | void x264_pixel_ssd_nv12_core_sse2( pixel *pixuv1, intptr_t stride1, |
151 | 148 | pixel *pixuv2, intptr_t stride2, int width, |
152 | 149 | int height, uint64_t *ssd_u, uint64_t *ssd_v ); |
2091 | 2091 | %endif |
2092 | 2092 | |
2093 | 2093 | ;----------------------------------------------------------------------------- |
2094 | ; void predict_16x16_dc_core( pixel *src, int i_dc_left ) | |
2095 | ;----------------------------------------------------------------------------- | |
2096 | %macro PRED16x16_DC_MMX 2 | |
2097 | %if HIGH_BIT_DEPTH | |
2098 | mova m0, [r0 - FDEC_STRIDEB+ 0] | |
2099 | paddw m0, [r0 - FDEC_STRIDEB+ 8] | |
2100 | paddw m0, [r0 - FDEC_STRIDEB+16] | |
2101 | paddw m0, [r0 - FDEC_STRIDEB+24] | |
2102 | HADDW m0, m1 | |
2103 | paddw m0, %1 | |
2104 | psrlw m0, %2 | |
2105 | SPLATW m0, m0 | |
2106 | STORE16 m0, m0, m0, m0 | |
2107 | %else ; !HIGH_BIT_DEPTH | |
2108 | pxor m0, m0 | |
2109 | pxor m1, m1 | |
2110 | psadbw m0, [r0 - FDEC_STRIDE] | |
2111 | psadbw m1, [r0 - FDEC_STRIDE + 8] | |
2112 | paddusw m0, m1 | |
2113 | paddusw m0, %1 | |
2114 | psrlw m0, %2 ; dc | |
2115 | pshufw m0, m0, 0 | |
2116 | packuswb m0, m0 ; dc in bytes | |
2117 | STORE16 m0, m0 | |
2118 | %endif | |
2119 | %endmacro | |
2120 | ||
2121 | INIT_MMX mmx2 | |
2122 | cglobal predict_16x16_dc_core, 1,2 | |
2123 | %if ARCH_X86_64 | |
2124 | movd m6, r1d | |
2125 | PRED16x16_DC_MMX m6, 5 | |
2126 | %else | |
2127 | PRED16x16_DC_MMX r1m, 5 | |
2128 | %endif | |
2129 | RET | |
2130 | ||
2131 | INIT_MMX mmx2 | |
2132 | cglobal predict_16x16_dc_top, 1,2 | |
2133 | PRED16x16_DC_MMX [pw_8], 4 | |
2134 | RET | |
2135 | ||
2136 | INIT_MMX mmx2 | |
2137 | %if HIGH_BIT_DEPTH | |
2138 | cglobal predict_16x16_dc_left_core, 1,2 | |
2139 | movd m0, r1m | |
2140 | SPLATW m0, m0 | |
2141 | STORE16 m0, m0, m0, m0 | |
2142 | RET | |
2143 | %else ; !HIGH_BIT_DEPTH | |
2144 | cglobal predict_16x16_dc_left_core, 1,1 | |
2145 | movd m0, r1m | |
2146 | pshufw m0, m0, 0 | |
2147 | packuswb m0, m0 | |
2148 | STORE16 m0, m0 | |
2149 | RET | |
2150 | %endif | |
2094 | ; void predict_16x16_dc( pixel *src ) | |
2095 | ;----------------------------------------------------------------------------- | |
2096 | %if WIN64 | |
2097 | DECLARE_REG_TMP 6 ; Reduces code size due to fewer REX prefixes | |
2098 | %else | |
2099 | DECLARE_REG_TMP 3 | |
2100 | %endif | |
2101 | ||
2102 | INIT_XMM | |
2103 | ; Returns the sum of the left pixels in r1d+r2d | |
2104 | cglobal predict_16x16_dc_left_internal, 0,4 | |
2105 | movzx r1d, pixel [r0-SIZEOF_PIXEL] | |
2106 | movzx r2d, pixel [r0+FDEC_STRIDEB-SIZEOF_PIXEL] | |
2107 | %assign i 2*FDEC_STRIDEB | |
2108 | %rep 7 | |
2109 | movzx t0d, pixel [r0+i-SIZEOF_PIXEL] | |
2110 | add r1d, t0d | |
2111 | movzx t0d, pixel [r0+i+FDEC_STRIDEB-SIZEOF_PIXEL] | |
2112 | add r2d, t0d | |
2113 | %assign i i+2*FDEC_STRIDEB | |
2114 | %endrep | |
2115 | RET | |
2151 | 2116 | |
2152 | 2117 | %macro PRED16x16_DC 2 |
2153 | 2118 | %if HIGH_BIT_DEPTH |
2175 | 2140 | %endif |
2176 | 2141 | %endmacro |
2177 | 2142 | |
2178 | %macro PREDICT_16x16_DC_CORE 0 | |
2179 | cglobal predict_16x16_dc_core, 2,2,4 | |
2180 | movd xm3, r1m | |
2143 | %macro PREDICT_16x16_DC 0 | |
2144 | cglobal predict_16x16_dc, 1,3 | |
2145 | call predict_16x16_dc_left_internal | |
2146 | lea r1d, [r1+r2+16] | |
2147 | movd xm3, r1d | |
2181 | 2148 | PRED16x16_DC xm3, 5 |
2182 | 2149 | RET |
2183 | 2150 | |
2185 | 2152 | PRED16x16_DC [pw_8], 4 |
2186 | 2153 | RET |
2187 | 2154 | |
2188 | cglobal predict_16x16_dc_left_core, 1,2 | |
2189 | movd xm0, r1m | |
2155 | cglobal predict_16x16_dc_left, 1,3 | |
2156 | call predict_16x16_dc_left_internal | |
2157 | lea r1d, [r1+r2+8] | |
2158 | shr r1d, 4 | |
2159 | movd xm0, r1d | |
2190 | 2160 | SPLATW m0, xm0 |
2191 | 2161 | %if HIGH_BIT_DEPTH && mmsize == 16 |
2192 | 2162 | STORE16 m0, m0 |
2200 | 2170 | %endmacro |
2201 | 2171 | |
2202 | 2172 | INIT_XMM sse2 |
2203 | PREDICT_16x16_DC_CORE | |
2173 | PREDICT_16x16_DC | |
2204 | 2174 | %if HIGH_BIT_DEPTH |
2205 | 2175 | INIT_YMM avx2 |
2206 | PREDICT_16x16_DC_CORE | |
2176 | PREDICT_16x16_DC | |
2207 | 2177 | %else |
2208 | 2178 | INIT_XMM avx2 |
2209 | PREDICT_16x16_DC_CORE | |
2210 | %endif | |
2179 | PREDICT_16x16_DC | |
2180 | %endif |
27 | 27 | #include "common/common.h" |
28 | 28 | #include "predict.h" |
29 | 29 | #include "pixel.h" |
30 | ||
31 | #define PREDICT_16x16_DC(name)\ | |
32 | void x264_predict_16x16_dc_##name( pixel *src )\ | |
33 | {\ | |
34 | uint32_t dc = 16;\ | |
35 | for( int i = 0; i < 16; i += 2 )\ | |
36 | {\ | |
37 | dc += src[-1 + i * FDEC_STRIDE];\ | |
38 | dc += src[-1 + (i+1) * FDEC_STRIDE];\ | |
39 | }\ | |
40 | x264_predict_16x16_dc_core_##name( src, dc );\ | |
41 | } | |
42 | ||
43 | PREDICT_16x16_DC( mmx2 ) | |
44 | PREDICT_16x16_DC( sse2 ) | |
45 | PREDICT_16x16_DC( avx2 ) | |
46 | ||
47 | #define PREDICT_16x16_DC_LEFT(name)\ | |
48 | static void x264_predict_16x16_dc_left_##name( pixel *src )\ | |
49 | {\ | |
50 | uint32_t dc = 8;\ | |
51 | for( int i = 0; i < 16; i += 2 )\ | |
52 | {\ | |
53 | dc += src[-1 + i * FDEC_STRIDE];\ | |
54 | dc += src[-1 + (i+1) * FDEC_STRIDE];\ | |
55 | }\ | |
56 | x264_predict_16x16_dc_left_core_##name( src, dc>>4 );\ | |
57 | } | |
58 | ||
59 | PREDICT_16x16_DC_LEFT( mmx2 ) | |
60 | PREDICT_16x16_DC_LEFT( sse2 ) | |
61 | PREDICT_16x16_DC_LEFT( avx2 ) | |
62 | 30 | |
63 | 31 | #define PREDICT_P_SUM(j,i)\ |
64 | 32 | H += i * ( src[j+i - FDEC_STRIDE ] - src[j-i - FDEC_STRIDE ] );\ |
346 | 314 | { |
347 | 315 | if( !(cpu&X264_CPU_MMX2) ) |
348 | 316 | return; |
349 | pf[I_PRED_16x16_DC] = x264_predict_16x16_dc_mmx2; | |
350 | pf[I_PRED_16x16_DC_TOP] = x264_predict_16x16_dc_top_mmx2; | |
351 | pf[I_PRED_16x16_DC_LEFT] = x264_predict_16x16_dc_left_mmx2; | |
352 | 317 | pf[I_PRED_16x16_V] = x264_predict_16x16_v_mmx2; |
353 | 318 | pf[I_PRED_16x16_H] = x264_predict_16x16_h_mmx2; |
354 | 319 | #if HIGH_BIT_DEPTH |
39 | 39 | void x264_predict_16x16_h_sse2( uint16_t *src ); |
40 | 40 | void x264_predict_16x16_h_ssse3( uint8_t *src ); |
41 | 41 | void x264_predict_16x16_h_avx2( uint16_t *src ); |
42 | void x264_predict_16x16_dc_mmx2( pixel *src ); | |
43 | 42 | void x264_predict_16x16_dc_sse2( pixel *src ); |
44 | void x264_predict_16x16_dc_core_mmx2( pixel *src, int i_dc_left ); | |
45 | void x264_predict_16x16_dc_core_sse2( pixel *src, int i_dc_left ); | |
46 | void x264_predict_16x16_dc_core_avx2( pixel *src, int i_dc_left ); | |
47 | void x264_predict_16x16_dc_left_core_mmx2( pixel *src, int i_dc_left ); | |
48 | void x264_predict_16x16_dc_left_core_sse2( pixel *src, int i_dc_left ); | |
49 | void x264_predict_16x16_dc_left_core_avx2( pixel *src, int i_dc_left ); | |
50 | void x264_predict_16x16_dc_top_mmx2( pixel *src ); | |
43 | void x264_predict_16x16_dc_avx2( pixel *src ); | |
44 | void x264_predict_16x16_dc_left_sse2( pixel *src ); | |
45 | void x264_predict_16x16_dc_left_avx2( pixel *src ); | |
51 | 46 | void x264_predict_16x16_dc_top_sse2( pixel *src ); |
52 | 47 | void x264_predict_16x16_dc_top_avx2( pixel *src ); |
53 | 48 | void x264_predict_16x16_p_core_mmx2( uint8_t *src, int i00, int b, int c ); |
52 | 52 | |
53 | 53 | SECTION_RODATA |
54 | 54 | |
55 | pd_8: times 4 dd 8 | |
56 | 55 | pd_m16: times 4 dd -16 |
57 | pd_0123: dd 0, 1, 2, 3 | |
58 | pd_4567: dd 4, 5, 6, 7 | |
59 | 56 | sq_1: dq 1, 0 |
60 | 57 | pq_128: times 2 dq 128 |
61 | 58 | pq_ffffffff: times 2 dq 0xffffffff |
62 | 59 | |
60 | cextern pd_8 | |
61 | cextern pd_0123 | |
62 | cextern pd_4567 | |
63 | 63 | cextern cabac_entropy |
64 | 64 | cextern cabac_transition |
65 | 65 | cextern cabac_size_unary |
1 | 1 | # Attempt to guess a canonical system name. |
2 | 2 | # Copyright 1992-2016 Free Software Foundation, Inc. |
3 | 3 | |
4 | timestamp='2016-04-02' | |
4 | timestamp='2016-10-02' | |
5 | 5 | |
6 | 6 | # This file is free software; you can redistribute it and/or modify it |
7 | 7 | # under the terms of the GNU General Public License as published by |
185 | 185 | *) machine=${UNAME_MACHINE_ARCH}-unknown ;; |
186 | 186 | esac |
187 | 187 | # The Operating System including object format, if it has switched |
188 | # to ELF recently, or will in the future. | |
188 | # to ELF recently (or will in the future) and ABI. | |
189 | 189 | case "${UNAME_MACHINE_ARCH}" in |
190 | arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax) | |
190 | earm*) | |
191 | os=netbsdelf | |
192 | ;; | |
193 | arm*|i386|m68k|ns32k|sh3*|sparc|vax) | |
191 | 194 | eval $set_cc_for_build |
192 | 195 | if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ |
193 | 196 | | grep -q __ELF__ |
996 | 999 | eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` |
997 | 1000 | test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } |
998 | 1001 | ;; |
1002 | mips64el:Linux:*:*) | |
1003 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} | |
1004 | exit ;; | |
999 | 1005 | openrisc*:Linux:*:*) |
1000 | 1006 | echo or1k-unknown-linux-${LIBC} |
1001 | 1007 | exit ;; |
1027 | 1033 | exit ;; |
1028 | 1034 | ppcle:Linux:*:*) |
1029 | 1035 | echo powerpcle-unknown-linux-${LIBC} |
1036 | exit ;; | |
1037 | riscv32:Linux:*:* | riscv64:Linux:*:*) | |
1038 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} | |
1030 | 1039 | exit ;; |
1031 | 1040 | s390:Linux:*:* | s390x:Linux:*:*) |
1032 | 1041 | echo ${UNAME_MACHINE}-ibm-linux-${LIBC} |
1407 | 1416 | cat >&2 <<EOF |
1408 | 1417 | $0: unable to guess system type |
1409 | 1418 | |
1410 | This script, last modified $timestamp, has failed to recognize | |
1411 | the operating system you are using. It is advised that you | |
1412 | download the most up to date version of the config scripts from | |
1419 | This script (version $timestamp), has failed to recognize the | |
1420 | operating system you are using. If your script is old, overwrite | |
1421 | config.guess and config.sub with the latest versions from: | |
1413 | 1422 | |
1414 | 1423 | http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess |
1415 | 1424 | and |
1416 | 1425 | http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub |
1417 | 1426 | |
1418 | If the version you run ($0) is already up to date, please | |
1419 | send the following data and any information you think might be | |
1420 | pertinent to <config-patches@gnu.org> in order to provide the needed | |
1421 | information to handle your system. | |
1427 | If $0 has already been updated, send the following data and any | |
1428 | information you think might be pertinent to config-patches@gnu.org to | |
1429 | provide the necessary information to handle your system. | |
1422 | 1430 | |
1423 | 1431 | config.guess timestamp = $timestamp |
1424 | 1432 |
1 | 1 | # Configuration validation subroutine script. |
2 | 2 | # Copyright 1992-2016 Free Software Foundation, Inc. |
3 | 3 | |
4 | timestamp='2016-03-30' | |
4 | timestamp='2016-11-04' | |
5 | 5 | |
6 | 6 | # This file is free software; you can redistribute it and/or modify it |
7 | 7 | # under the terms of the GNU General Public License as published by |
116 | 116 | nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ |
117 | 117 | linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ |
118 | 118 | knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ |
119 | kopensolaris*-gnu* | \ | |
119 | kopensolaris*-gnu* | cloudabi*-eabi* | \ | |
120 | 120 | storm-chaos* | os2-emx* | rtmk-nova*) |
121 | 121 | os=-$maybe_os |
122 | 122 | basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` |
300 | 300 | | open8 | or1k | or1knd | or32 \ |
301 | 301 | | pdp10 | pdp11 | pj | pjl \ |
302 | 302 | | powerpc | powerpc64 | powerpc64le | powerpcle \ |
303 | | pru \ | |
303 | 304 | | pyramid \ |
304 | 305 | | riscv32 | riscv64 \ |
305 | 306 | | rl78 | rx \ |
427 | 428 | | orion-* \ |
428 | 429 | | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ |
429 | 430 | | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ |
431 | | pru-* \ | |
430 | 432 | | pyramid-* \ |
431 | 433 | | riscv32-* | riscv64-* \ |
432 | 434 | | rl78-* | romp-* | rs6000-* | rx-* \ |
642 | 644 | basic_machine=m68k-bull |
643 | 645 | os=-sysv3 |
644 | 646 | ;; |
647 | e500v[12]) | |
648 | basic_machine=powerpc-unknown | |
649 | os=$os"spe" | |
650 | ;; | |
651 | e500v[12]-*) | |
652 | basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` | |
653 | os=$os"spe" | |
654 | ;; | |
645 | 655 | ebmon29k) |
646 | 656 | basic_machine=a29k-amd |
647 | 657 | os=-ebmon |
1021 | 1031 | ppc-* | ppcbe-*) |
1022 | 1032 | basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` |
1023 | 1033 | ;; |
1024 | ppcle | powerpclittle | ppc-le | powerpc-little) | |
1034 | ppcle | powerpclittle) | |
1025 | 1035 | basic_machine=powerpcle-unknown |
1026 | 1036 | ;; |
1027 | 1037 | ppcle-* | powerpclittle-*) |
1031 | 1041 | ;; |
1032 | 1042 | ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` |
1033 | 1043 | ;; |
1034 | ppc64le | powerpc64little | ppc64-le | powerpc64-little) | |
1044 | ppc64le | powerpc64little) | |
1035 | 1045 | basic_machine=powerpc64le-unknown |
1036 | 1046 | ;; |
1037 | 1047 | ppc64le-* | powerpc64little-*) |
1388 | 1398 | | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ |
1389 | 1399 | | -chorusos* | -chorusrdb* | -cegcc* \ |
1390 | 1400 | | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ |
1391 | | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | |
1401 | | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | |
1392 | 1402 | | -linux-newlib* | -linux-musl* | -linux-uclibc* \ |
1393 | 1403 | | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ |
1394 | 1404 | | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ |
1398 | 1408 | | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ |
1399 | 1409 | | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ |
1400 | 1410 | | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ |
1401 | | -onefs* | -tirtos*) | |
1411 | | -onefs* | -tirtos* | -phoenix* | -fuchsia*) | |
1402 | 1412 | # Remember, each alternative MUST END IN *, to match a version number. |
1403 | 1413 | ;; |
1404 | 1414 | -qnx*) |
862 | 862 | x264_cabac_encode_bypass( cb, 0 ); // sign |
863 | 863 | } |
864 | 864 | |
865 | for( int i = last-1 ; i >= 0; i-- ) | |
865 | for( int i = last-1; i >= 0; i-- ) | |
866 | 866 | { |
867 | 867 | if( l[i] ) |
868 | 868 | { |
707 | 707 | } |
708 | 708 | for( int p = 0; p < plane_count; p++, i_qp = h->mb.i_chroma_qp ) |
709 | 709 | { |
710 | for( int i = (p == 0 && h->mb.i_skip_intra) ? 3 : 0 ; i < 4; i++ ) | |
710 | for( int i = (p == 0 && h->mb.i_skip_intra) ? 3 : 0; i < 4; i++ ) | |
711 | 711 | { |
712 | 712 | int i_mode = h->mb.cache.intra4x4_pred_mode[x264_scan8[4*i]]; |
713 | 713 | x264_mb_encode_i8x8( h, p, i, i_qp, i_mode, NULL, 1 ); |
732 | 732 | } |
733 | 733 | for( int p = 0; p < plane_count; p++, i_qp = h->mb.i_chroma_qp ) |
734 | 734 | { |
735 | for( int i = (p == 0 && h->mb.i_skip_intra) ? 15 : 0 ; i < 16; i++ ) | |
735 | for( int i = (p == 0 && h->mb.i_skip_intra) ? 15 : 0; i < 16; i++ ) | |
736 | 736 | { |
737 | 737 | pixel *p_dst = &h->mb.pic.p_fdec[p][block_idx_xy_fdec[i]]; |
738 | 738 | int i_mode = h->mb.cache.intra4x4_pred_mode[x264_scan8[i]]; |
785 | 785 | x264_reduce_fraction64( &num, &denom ); |
786 | 786 | rc->hrd_multiply_denom = 90000 / num; |
787 | 787 | |
788 | double bits_required = log2( 90000 / rc->hrd_multiply_denom ) | |
788 | double bits_required = log2( num ) | |
789 | 789 | + log2( h->sps->vui.i_time_scale ) |
790 | 790 | + log2( h->sps->vui.hrd.i_cpb_size_unscaled ); |
791 | 791 | if( bits_required >= 63 ) |
136 | 136 | sps->i_level_idc = 11; |
137 | 137 | } |
138 | 138 | /* Intra profiles */ |
139 | if( param->i_keyint_max == 1 && sps->i_profile_idc > PROFILE_HIGH ) | |
139 | if( param->i_keyint_max == 1 && sps->i_profile_idc >= PROFILE_HIGH ) | |
140 | 140 | sps->b_constraint_set3 = 1; |
141 | 141 | |
142 | 142 | sps->vui.i_num_reorder_frames = param->i_bframe_pyramid ? 2 : param->i_bframe ? 1 : 0; |
237 | 237 | |
238 | 238 | // NOTE: HRD related parts of the SPS are initialised in x264_ratecontrol_init_reconfigurable |
239 | 239 | |
240 | sps->vui.b_bitstream_restriction = param->i_keyint_max > 1; | |
240 | sps->vui.b_bitstream_restriction = !(sps->b_constraint_set3 && sps->i_profile_idc >= PROFILE_HIGH); | |
241 | 241 | if( sps->vui.b_bitstream_restriction ) |
242 | 242 | { |
243 | 243 | sps->vui.b_motion_vectors_over_pic_boundaries = 1; |
53 | 53 | #define AVSC_INLINE static __inline |
54 | 54 | |
55 | 55 | #ifdef AVISYNTH_C_EXPORTS |
56 | # define AVSC_EXPORT EXTERN_C | |
57 | # define AVSC_API(ret, name) EXTERN_C __declspec(dllexport) ret AVSC_CC name | |
56 | # define AVSC_EXPORT __declspec(dllexport) | |
57 | # define AVSC_API(ret, name) EXTERN_C AVSC_EXPORT ret AVSC_CC name | |
58 | 58 | #else |
59 | # define AVSC_EXPORT EXTERN_C __declspec(dllexport) | |
59 | # define AVSC_EXPORT __declspec(dllimport) | |
60 | 60 | # ifndef AVSC_NO_DECLSPEC |
61 | # define AVSC_API(ret, name) EXTERN_C __declspec(dllimport) ret AVSC_CC name | |
61 | # define AVSC_API(ret, name) EXTERN_C AVSC_EXPORT ret AVSC_CC name | |
62 | 62 | # else |
63 | 63 | # define AVSC_API(ret, name) typedef ret (AVSC_CC *name##_func) |
64 | 64 | # endif |
77 | 77 | // Constants |
78 | 78 | // |
79 | 79 | |
80 | #ifndef __AVISYNTH_H__ | |
81 | enum { AVISYNTH_INTERFACE_VERSION = 4 }; | |
80 | #ifndef __AVISYNTH_6_H__ | |
81 | enum { AVISYNTH_INTERFACE_VERSION = 6 }; | |
82 | 82 | #endif |
83 | 83 | |
84 | 84 | enum {AVS_SAMPLE_INT8 = 1<<0, |
85 | AVS_SAMPLE_INT16 = 1<<1, | |
85 | AVS_SAMPLE_INT16 = 1<<1, | |
86 | 86 | AVS_SAMPLE_INT24 = 1<<2, |
87 | 87 | AVS_SAMPLE_INT32 = 1<<3, |
88 | 88 | AVS_SAMPLE_FLOAT = 1<<4}; |
108 | 108 | AVS_CS_YUV = 1<<29, |
109 | 109 | AVS_CS_INTERLEAVED = 1<<30, |
110 | 110 | AVS_CS_PLANAR = 1<<31, |
111 | ||
111 | ||
112 | 112 | AVS_CS_SHIFT_SUB_WIDTH = 0, |
113 | AVS_CS_SHIFT_SUB_HEIGHT = 1 << 3, | |
114 | AVS_CS_SHIFT_SAMPLE_BITS = 1 << 4, | |
113 | AVS_CS_SHIFT_SUB_HEIGHT = 8, | |
114 | AVS_CS_SHIFT_SAMPLE_BITS = 16, | |
115 | 115 | |
116 | 116 | AVS_CS_SUB_WIDTH_MASK = 7 << AVS_CS_SHIFT_SUB_WIDTH, |
117 | 117 | AVS_CS_SUB_WIDTH_1 = 3 << AVS_CS_SHIFT_SUB_WIDTH, // YV24 |
178 | 178 | AVS_FILTER_OUTPUT_TYPE_DIFFERENT=4}; |
179 | 179 | |
180 | 180 | enum { |
181 | AVS_CACHE_NOTHING=0, | |
182 | AVS_CACHE_RANGE=1, | |
183 | AVS_CACHE_ALL=2, | |
184 | AVS_CACHE_AUDIO=3, | |
185 | AVS_CACHE_AUDIO_NONE=4, | |
186 | AVS_CACHE_AUDIO_AUTO=5 | |
181 | // New 2.6 explicitly defined cache hints. | |
182 | AVS_CACHE_NOTHING=10, // Do not cache video. | |
183 | AVS_CACHE_WINDOW=11, // Hard protect upto X frames within a range of X from the current frame N. | |
184 | AVS_CACHE_GENERIC=12, // LRU cache upto X frames. | |
185 | AVS_CACHE_FORCE_GENERIC=13, // LRU cache upto X frames, override any previous CACHE_WINDOW. | |
186 | ||
187 | AVS_CACHE_GET_POLICY=30, // Get the current policy. | |
188 | AVS_CACHE_GET_WINDOW=31, // Get the current window h_span. | |
189 | AVS_CACHE_GET_RANGE=32, // Get the current generic frame range. | |
190 | ||
191 | AVS_CACHE_AUDIO=50, // Explicitly do cache audio, X byte cache. | |
192 | AVS_CACHE_AUDIO_NOTHING=51, // Explicitly do not cache audio. | |
193 | AVS_CACHE_AUDIO_NONE=52, // Audio cache off (auto mode), X byte intial cache. | |
194 | AVS_CACHE_AUDIO_AUTO=53, // Audio cache on (auto mode), X byte intial cache. | |
195 | ||
196 | AVS_CACHE_GET_AUDIO_POLICY=70, // Get the current audio policy. | |
197 | AVS_CACHE_GET_AUDIO_SIZE=71, // Get the current audio cache size. | |
198 | ||
199 | AVS_CACHE_PREFETCH_FRAME=100, // Queue request to prefetch frame N. | |
200 | AVS_CACHE_PREFETCH_GO=101, // Action video prefetches. | |
201 | ||
202 | AVS_CACHE_PREFETCH_AUDIO_BEGIN=120, // Begin queue request transaction to prefetch audio (take critical section). | |
203 | AVS_CACHE_PREFETCH_AUDIO_STARTLO=121, // Set low 32 bits of start. | |
204 | AVS_CACHE_PREFETCH_AUDIO_STARTHI=122, // Set high 32 bits of start. | |
205 | AVS_CACHE_PREFETCH_AUDIO_COUNT=123, // Set low 32 bits of length. | |
206 | AVS_CACHE_PREFETCH_AUDIO_COMMIT=124, // Enqueue request transaction to prefetch audio (release critical section). | |
207 | AVS_CACHE_PREFETCH_AUDIO_GO=125, // Action audio prefetches. | |
208 | ||
209 | AVS_CACHE_GETCHILD_CACHE_MODE=200, // Cache ask Child for desired video cache mode. | |
210 | AVS_CACHE_GETCHILD_CACHE_SIZE=201, // Cache ask Child for desired video cache size. | |
211 | AVS_CACHE_GETCHILD_AUDIO_MODE=202, // Cache ask Child for desired audio cache mode. | |
212 | AVS_CACHE_GETCHILD_AUDIO_SIZE=203, // Cache ask Child for desired audio cache size. | |
213 | ||
214 | AVS_CACHE_GETCHILD_COST=220, // Cache ask Child for estimated processing cost. | |
215 | AVS_CACHE_COST_ZERO=221, // Child response of zero cost (ptr arithmetic only). | |
216 | AVS_CACHE_COST_UNIT=222, // Child response of unit cost (less than or equal 1 full frame blit). | |
217 | AVS_CACHE_COST_LOW=223, // Child response of light cost. (Fast) | |
218 | AVS_CACHE_COST_MED=224, // Child response of medium cost. (Real time) | |
219 | AVS_CACHE_COST_HI=225, // Child response of heavy cost. (Slow) | |
220 | ||
221 | AVS_CACHE_GETCHILD_THREAD_MODE=240, // Cache ask Child for thread safetyness. | |
222 | AVS_CACHE_THREAD_UNSAFE=241, // Only 1 thread allowed for all instances. 2.5 filters default! | |
223 | AVS_CACHE_THREAD_CLASS=242, // Only 1 thread allowed for each instance. 2.6 filters default! | |
224 | AVS_CACHE_THREAD_SAFE=243, // Allow all threads in any instance. | |
225 | AVS_CACHE_THREAD_OWN=244, // Safe but limit to 1 thread, internally threaded. | |
226 | ||
227 | AVS_CACHE_GETCHILD_ACCESS_COST=260, // Cache ask Child for preferred access pattern. | |
228 | AVS_CACHE_ACCESS_RAND=261, // Filter is access order agnostic. | |
229 | AVS_CACHE_ACCESS_SEQ0=262, // Filter prefers sequential access (low cost) | |
230 | AVS_CACHE_ACCESS_SEQ1=263, // Filter needs sequential access (high cost) | |
187 | 231 | }; |
188 | 232 | |
189 | #define AVS_FRAME_ALIGN 16 | |
233 | #define AVS_FRAME_ALIGN 16 | |
190 | 234 | |
191 | 235 | typedef struct AVS_Clip AVS_Clip; |
192 | 236 | typedef struct AVS_ScriptEnvironment AVS_ScriptEnvironment; |
203 | 247 | int num_frames; |
204 | 248 | |
205 | 249 | int pixel_type; |
206 | ||
250 | ||
207 | 251 | int audio_samples_per_second; // 0 means no audio |
208 | 252 | int sample_type; |
209 | 253 | INT64 num_audio_samples; |
215 | 259 | } AVS_VideoInfo; |
216 | 260 | |
217 | 261 | // useful functions of the above |
218 | AVSC_INLINE int avs_has_video(const AVS_VideoInfo * p) | |
262 | AVSC_INLINE int avs_has_video(const AVS_VideoInfo * p) | |
219 | 263 | { return (p->width!=0); } |
220 | 264 | |
221 | AVSC_INLINE int avs_has_audio(const AVS_VideoInfo * p) | |
265 | AVSC_INLINE int avs_has_audio(const AVS_VideoInfo * p) | |
222 | 266 | { return (p->audio_samples_per_second!=0); } |
223 | 267 | |
224 | AVSC_INLINE int avs_is_rgb(const AVS_VideoInfo * p) | |
268 | AVSC_INLINE int avs_is_rgb(const AVS_VideoInfo * p) | |
225 | 269 | { return !!(p->pixel_type&AVS_CS_BGR); } |
226 | 270 | |
227 | AVSC_INLINE int avs_is_rgb24(const AVS_VideoInfo * p) | |
228 | { return (p->pixel_type&AVS_CS_BGR24)==AVS_CS_BGR24; } // Clear out additional properties | |
229 | ||
230 | AVSC_INLINE int avs_is_rgb32(const AVS_VideoInfo * p) | |
231 | { return (p->pixel_type & AVS_CS_BGR32) == AVS_CS_BGR32 ; } | |
232 | ||
233 | AVSC_INLINE int avs_is_yuv(const AVS_VideoInfo * p) | |
271 | AVSC_INLINE int avs_is_rgb24(const AVS_VideoInfo * p) | |
272 | { return ((p->pixel_type&AVS_CS_BGR24)==AVS_CS_BGR24) && ((p->pixel_type & AVS_CS_SAMPLE_BITS_MASK) == AVS_CS_SAMPLE_BITS_8); } | |
273 | ||
274 | AVSC_INLINE int avs_is_rgb32(const AVS_VideoInfo * p) | |
275 | { return ((p->pixel_type&AVS_CS_BGR32)==AVS_CS_BGR32) && ((p->pixel_type & AVS_CS_SAMPLE_BITS_MASK) == AVS_CS_SAMPLE_BITS_8); } | |
276 | ||
277 | AVSC_INLINE int avs_is_yuv(const AVS_VideoInfo * p) | |
234 | 278 | { return !!(p->pixel_type&AVS_CS_YUV ); } |
235 | 279 | |
236 | AVSC_INLINE int avs_is_yuy2(const AVS_VideoInfo * p) | |
237 | { return (p->pixel_type & AVS_CS_YUY2) == AVS_CS_YUY2; } | |
238 | ||
280 | AVSC_INLINE int avs_is_yuy2(const AVS_VideoInfo * p) | |
281 | { return (p->pixel_type & AVS_CS_YUY2) == AVS_CS_YUY2; } | |
282 | ||
283 | AVSC_API(int, avs_is_yv24)(const AVS_VideoInfo * p); | |
284 | ||
285 | AVSC_API(int, avs_is_yv16)(const AVS_VideoInfo * p); | |
286 | ||
287 | AVSC_API(int, avs_is_yv12)(const AVS_VideoInfo * p); | |
288 | ||
289 | AVSC_API(int, avs_is_yv411)(const AVS_VideoInfo * p); | |
290 | ||
291 | AVSC_API(int, avs_is_y8)(const AVS_VideoInfo * p); | |
292 | ||
293 | #ifdef AVSC_NO_DECLSPEC | |
239 | 294 | AVSC_INLINE int avs_is_yv24(const AVS_VideoInfo * p) |
240 | 295 | { return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_YV24 & AVS_CS_PLANAR_FILTER); } |
241 | 296 | |
242 | 297 | AVSC_INLINE int avs_is_yv16(const AVS_VideoInfo * p) |
243 | 298 | { return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_YV16 & AVS_CS_PLANAR_FILTER); } |
244 | 299 | |
245 | AVSC_INLINE int avs_is_yv12(const AVS_VideoInfo * p) | |
300 | AVSC_INLINE int avs_is_yv12(const AVS_VideoInfo * p) | |
246 | 301 | { return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_YV12 & AVS_CS_PLANAR_FILTER); } |
247 | 302 | |
248 | 303 | AVSC_INLINE int avs_is_yv411(const AVS_VideoInfo * p) |
249 | 304 | { return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_YV411 & AVS_CS_PLANAR_FILTER); } |
250 | ||
305 | ||
251 | 306 | AVSC_INLINE int avs_is_y8(const AVS_VideoInfo * p) |
252 | 307 | { return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_Y8 & AVS_CS_PLANAR_FILTER); } |
253 | ||
254 | AVSC_INLINE int avs_is_property(const AVS_VideoInfo * p, int property) | |
255 | { return ((p->pixel_type & property)==property ); } | |
256 | ||
257 | AVSC_INLINE int avs_is_planar(const AVS_VideoInfo * p) | |
308 | #endif | |
309 | ||
310 | #if 1 // AviSynth+ extension | |
311 | AVSC_API(int, avs_is_rgb48)(const AVS_VideoInfo * p); | |
312 | ||
313 | AVSC_API(int, avs_is_rgb64)(const AVS_VideoInfo * p); | |
314 | ||
315 | AVSC_API(int, avs_is_yuv444p16)(const AVS_VideoInfo * p); | |
316 | ||
317 | AVSC_API(int, avs_is_yuv422p16)(const AVS_VideoInfo * p); | |
318 | ||
319 | AVSC_API(int, avs_is_yuv420p16)(const AVS_VideoInfo * p); | |
320 | ||
321 | AVSC_API(int, avs_is_y16)(const AVS_VideoInfo * p); | |
322 | ||
323 | AVSC_API(int, avs_is_yuv444ps)(const AVS_VideoInfo * p); | |
324 | ||
325 | AVSC_API(int, avs_is_yuv422ps)(const AVS_VideoInfo * p); | |
326 | ||
327 | AVSC_API(int, avs_is_yuv420ps)(const AVS_VideoInfo * p); | |
328 | ||
329 | AVSC_API(int, avs_is_y32)(const AVS_VideoInfo * p); | |
330 | ||
331 | AVSC_API(int, avs_is_444)(const AVS_VideoInfo * p); | |
332 | ||
333 | AVSC_API(int, avs_is_422)(const AVS_VideoInfo * p); | |
334 | ||
335 | AVSC_API(int, avs_is_420)(const AVS_VideoInfo * p); | |
336 | ||
337 | AVSC_API(int, avs_is_y)(const AVS_VideoInfo * p); | |
338 | ||
339 | AVSC_API(int, avs_is_yuva)(const AVS_VideoInfo * p); | |
340 | ||
341 | AVSC_API(int, avs_is_planar_rgb)(const AVS_VideoInfo * p); | |
342 | ||
343 | AVSC_API(int, avs_is_planar_rgba)(const AVS_VideoInfo * p); | |
344 | ||
345 | AVSC_API(int, avs_num_components)(const AVS_VideoInfo * p); | |
346 | ||
347 | AVSC_API(int, avs_component_size)(const AVS_VideoInfo * p); | |
348 | ||
349 | AVSC_API(int, avs_bits_per_component)(const AVS_VideoInfo * p); | |
350 | #endif | |
351 | ||
352 | AVSC_INLINE int avs_is_property(const AVS_VideoInfo * p, int property) | |
353 | { return ((p->image_type & property)==property ); } | |
354 | ||
355 | AVSC_INLINE int avs_is_planar(const AVS_VideoInfo * p) | |
258 | 356 | { return !!(p->pixel_type & AVS_CS_PLANAR); } |
259 | 357 | |
260 | AVSC_INLINE int avs_is_color_space(const AVS_VideoInfo * p, int c_space) | |
261 | { return avs_is_planar(p) ? ((p->pixel_type & AVS_CS_PLANAR_MASK) == (c_space & AVS_CS_PLANAR_FILTER)) : ((p->pixel_type & c_space) == c_space); } | |
262 | ||
263 | AVSC_INLINE int avs_is_field_based(const AVS_VideoInfo * p) | |
358 | AVSC_API(int, avs_is_color_space)(const AVS_VideoInfo * p, int c_space); | |
359 | ||
360 | AVSC_INLINE int avs_is_field_based(const AVS_VideoInfo * p) | |
264 | 361 | { return !!(p->image_type & AVS_IT_FIELDBASED); } |
265 | 362 | |
266 | AVSC_INLINE int avs_is_parity_known(const AVS_VideoInfo * p) | |
363 | AVSC_INLINE int avs_is_parity_known(const AVS_VideoInfo * p) | |
267 | 364 | { return ((p->image_type & AVS_IT_FIELDBASED)&&(p->image_type & (AVS_IT_BFF | AVS_IT_TFF))); } |
268 | 365 | |
269 | AVSC_INLINE int avs_is_bff(const AVS_VideoInfo * p) | |
366 | AVSC_INLINE int avs_is_bff(const AVS_VideoInfo * p) | |
270 | 367 | { return !!(p->image_type & AVS_IT_BFF); } |
271 | 368 | |
272 | AVSC_INLINE int avs_is_tff(const AVS_VideoInfo * p) | |
369 | AVSC_INLINE int avs_is_tff(const AVS_VideoInfo * p) | |
273 | 370 | { return !!(p->image_type & AVS_IT_TFF); } |
274 | 371 | |
275 | AVSC_INLINE int avs_bits_per_pixel(const AVS_VideoInfo * p) | |
276 | { | |
277 | switch (p->pixel_type) { | |
278 | case AVS_CS_BGR24: return 24; | |
279 | case AVS_CS_BGR32: return 32; | |
280 | case AVS_CS_YUY2: return 16; | |
281 | case AVS_CS_YV12: | |
282 | case AVS_CS_I420: return 12; | |
283 | default: return 0; | |
284 | } | |
285 | } | |
286 | AVSC_INLINE int avs_bytes_from_pixels(const AVS_VideoInfo * p, int pixels) | |
287 | { return pixels * (avs_bits_per_pixel(p)>>3); } // Will work on planar images, but will return only luma planes | |
288 | ||
289 | AVSC_INLINE int avs_row_size(const AVS_VideoInfo * p) | |
290 | { return avs_bytes_from_pixels(p,p->width); } // Also only returns first plane on planar images | |
291 | ||
292 | AVSC_INLINE int avs_bmp_size(const AVS_VideoInfo * vi) | |
293 | { if (avs_is_planar(vi)) {int p = vi->height * ((avs_row_size(vi)+3) & ~3); p+=p>>1; return p; } return vi->height * ((avs_row_size(vi)+3) & ~3); } | |
294 | ||
295 | AVSC_INLINE int avs_samples_per_second(const AVS_VideoInfo * p) | |
372 | AVSC_API(int, avs_get_plane_width_subsampling)(const AVS_VideoInfo * p, int plane); | |
373 | ||
374 | AVSC_API(int, avs_get_plane_height_subsampling)(const AVS_VideoInfo * p, int plane); | |
375 | ||
376 | ||
377 | AVSC_API(int, avs_bits_per_pixel)(const AVS_VideoInfo * p); | |
378 | ||
379 | AVSC_API(int, avs_bytes_from_pixels)(const AVS_VideoInfo * p, int pixels); | |
380 | ||
381 | AVSC_API(int, avs_row_size_p)(const AVS_VideoInfo * p, int plane); | |
382 | ||
383 | #ifndef AVSC_NO_DECLSPEC | |
384 | AVSC_INLINE int avs_row_size(const AVS_VideoInfo * p) | |
385 | { return avs_row_size_p(p, 0); } | |
386 | #endif | |
387 | ||
388 | AVSC_API(int, avs_bmp_size)(const AVS_VideoInfo * vi); | |
389 | ||
390 | AVSC_INLINE int avs_samples_per_second(const AVS_VideoInfo * p) | |
296 | 391 | { return p->audio_samples_per_second; } |
297 | 392 | |
298 | 393 | |
299 | AVSC_INLINE int avs_bytes_per_channel_sample(const AVS_VideoInfo * p) | |
394 | AVSC_INLINE int avs_bytes_per_channel_sample(const AVS_VideoInfo * p) | |
300 | 395 | { |
301 | 396 | switch (p->sample_type) { |
302 | 397 | case AVS_SAMPLE_INT8: return sizeof(signed char); |
307 | 402 | default: return 0; |
308 | 403 | } |
309 | 404 | } |
310 | AVSC_INLINE int avs_bytes_per_audio_sample(const AVS_VideoInfo * p) | |
405 | AVSC_INLINE int avs_bytes_per_audio_sample(const AVS_VideoInfo * p) | |
311 | 406 | { return p->nchannels*avs_bytes_per_channel_sample(p);} |
312 | 407 | |
313 | AVSC_INLINE INT64 avs_audio_samples_from_frames(const AVS_VideoInfo * p, INT64 frames) | |
408 | AVSC_INLINE INT64 avs_audio_samples_from_frames(const AVS_VideoInfo * p, INT64 frames) | |
314 | 409 | { return ((INT64)(frames) * p->audio_samples_per_second * p->fps_denominator / p->fps_numerator); } |
315 | 410 | |
316 | AVSC_INLINE int avs_frames_from_audio_samples(const AVS_VideoInfo * p, INT64 samples) | |
411 | AVSC_INLINE int avs_frames_from_audio_samples(const AVS_VideoInfo * p, INT64 samples) | |
317 | 412 | { return (int)(samples * (INT64)p->fps_numerator / (INT64)p->fps_denominator / (INT64)p->audio_samples_per_second); } |
318 | 413 | |
319 | AVSC_INLINE INT64 avs_audio_samples_from_bytes(const AVS_VideoInfo * p, INT64 bytes) | |
414 | AVSC_INLINE INT64 avs_audio_samples_from_bytes(const AVS_VideoInfo * p, INT64 bytes) | |
320 | 415 | { return bytes / avs_bytes_per_audio_sample(p); } |
321 | 416 | |
322 | AVSC_INLINE INT64 avs_bytes_from_audio_samples(const AVS_VideoInfo * p, INT64 samples) | |
417 | AVSC_INLINE INT64 avs_bytes_from_audio_samples(const AVS_VideoInfo * p, INT64 samples) | |
323 | 418 | { return samples * avs_bytes_per_audio_sample(p); } |
324 | 419 | |
325 | AVSC_INLINE int avs_audio_channels(const AVS_VideoInfo * p) | |
420 | AVSC_INLINE int avs_audio_channels(const AVS_VideoInfo * p) | |
326 | 421 | { return p->nchannels; } |
327 | 422 | |
328 | 423 | AVSC_INLINE int avs_sample_type(const AVS_VideoInfo * p) |
329 | 424 | { return p->sample_type;} |
330 | 425 | |
331 | 426 | // useful mutator |
332 | AVSC_INLINE void avs_set_property(AVS_VideoInfo * p, int property) | |
427 | AVSC_INLINE void avs_set_property(AVS_VideoInfo * p, int property) | |
333 | 428 | { p->image_type|=property; } |
334 | 429 | |
335 | AVSC_INLINE void avs_clear_property(AVS_VideoInfo * p, int property) | |
430 | AVSC_INLINE void avs_clear_property(AVS_VideoInfo * p, int property) | |
336 | 431 | { p->image_type&=~property; } |
337 | 432 | |
338 | AVSC_INLINE void avs_set_field_based(AVS_VideoInfo * p, int isfieldbased) | |
433 | AVSC_INLINE void avs_set_field_based(AVS_VideoInfo * p, int isfieldbased) | |
339 | 434 | { if (isfieldbased) p->image_type|=AVS_IT_FIELDBASED; else p->image_type&=~AVS_IT_FIELDBASED; } |
340 | 435 | |
341 | AVSC_INLINE void avs_set_fps(AVS_VideoInfo * p, unsigned numerator, unsigned denominator) | |
436 | AVSC_INLINE void avs_set_fps(AVS_VideoInfo * p, unsigned numerator, unsigned denominator) | |
342 | 437 | { |
343 | 438 | unsigned x=numerator, y=denominator; |
344 | 439 | while (y) { // find gcd |
389 | 484 | } AVS_VideoFrame; |
390 | 485 | |
391 | 486 | // Access functions for AVS_VideoFrame |
487 | AVSC_API(int, avs_get_pitch_p)(const AVS_VideoFrame * p, int plane); | |
488 | ||
489 | #ifdef AVSC_NO_DECLSPEC | |
490 | AVSC_INLINE int avs_get_pitch_p(const AVS_VideoFrame * p, int plane) { | |
491 | switch (plane) { | |
492 | case AVS_PLANAR_U: | |
493 | case AVS_PLANAR_V: | |
494 | return p->pitchUV; | |
495 | } | |
496 | return p->pitch; | |
497 | } | |
498 | #endif | |
499 | ||
392 | 500 | AVSC_INLINE int avs_get_pitch(const AVS_VideoFrame * p) { |
393 | return p->pitch;} | |
394 | ||
395 | AVSC_INLINE int avs_get_pitch_p(const AVS_VideoFrame * p, int plane) { | |
396 | switch (plane) { | |
397 | case AVS_PLANAR_U: case AVS_PLANAR_V: return p->pitchUV;} | |
398 | return p->pitch;} | |
501 | return avs_get_pitch_p(p, 0);} | |
502 | ||
503 | AVSC_API(int, avs_get_row_size_p)(const AVS_VideoFrame * p, int plane); | |
399 | 504 | |
400 | 505 | AVSC_INLINE int avs_get_row_size(const AVS_VideoFrame * p) { |
401 | 506 | return p->row_size; } |
402 | 507 | |
403 | AVSC_INLINE int avs_get_row_size_p(const AVS_VideoFrame * p, int plane) { | |
404 | int r; | |
405 | switch (plane) { | |
406 | case AVS_PLANAR_U: case AVS_PLANAR_V: | |
407 | if (p->pitchUV) return p->row_sizeUV; | |
408 | else return 0; | |
409 | case AVS_PLANAR_U_ALIGNED: case AVS_PLANAR_V_ALIGNED: | |
410 | if (p->pitchUV) { | |
411 | r = (p->row_sizeUV+AVS_FRAME_ALIGN-1)&(~(AVS_FRAME_ALIGN-1)); // Aligned rowsize | |
412 | if (r < p->pitchUV) | |
413 | return r; | |
414 | return p->row_sizeUV; | |
415 | } else return 0; | |
416 | case AVS_PLANAR_Y_ALIGNED: | |
417 | r = (p->row_size+AVS_FRAME_ALIGN-1)&(~(AVS_FRAME_ALIGN-1)); // Aligned rowsize | |
418 | if (r <= p->pitch) | |
419 | return r; | |
420 | return p->row_size; | |
421 | } | |
422 | return p->row_size; | |
423 | } | |
508 | AVSC_API(int, avs_get_height_p)(const AVS_VideoFrame * p, int plane); | |
424 | 509 | |
425 | 510 | AVSC_INLINE int avs_get_height(const AVS_VideoFrame * p) { |
426 | 511 | return p->height;} |
427 | 512 | |
428 | AVSC_INLINE int avs_get_height_p(const AVS_VideoFrame * p, int plane) { | |
513 | AVSC_API(const BYTE *, avs_get_read_ptr_p)(const AVS_VideoFrame * p, int plane); | |
514 | ||
515 | #ifdef AVSC_NO_DECLSPEC | |
516 | AVSC_INLINE const BYTE* avs_get_read_ptr_p(const AVS_VideoFrame * p, int plane) { | |
429 | 517 | switch (plane) { |
430 | case AVS_PLANAR_U: case AVS_PLANAR_V: | |
431 | if (p->pitchUV) return p->heightUV; | |
432 | return 0; | |
433 | } | |
434 | return p->height;} | |
435 | ||
436 | AVSC_INLINE const BYTE* avs_get_read_ptr(const AVS_VideoFrame * p) { | |
437 | return p->vfb->data + p->offset;} | |
438 | ||
439 | AVSC_INLINE const BYTE* avs_get_read_ptr_p(const AVS_VideoFrame * p, int plane) | |
440 | { | |
441 | switch (plane) { | |
442 | case AVS_PLANAR_U: return p->vfb->data + p->offsetU; | |
443 | case AVS_PLANAR_V: return p->vfb->data + p->offsetV; | |
444 | default: return p->vfb->data + p->offset;} | |
445 | } | |
446 | ||
447 | AVSC_INLINE int avs_is_writable(const AVS_VideoFrame * p) { | |
448 | return (p->refcount == 1 && p->vfb->refcount == 1);} | |
449 | ||
450 | AVSC_INLINE BYTE* avs_get_write_ptr(const AVS_VideoFrame * p) | |
451 | { | |
452 | if (avs_is_writable(p)) { | |
453 | ++p->vfb->sequence_number; | |
454 | return p->vfb->data + p->offset; | |
455 | } else | |
456 | return 0; | |
457 | } | |
458 | ||
459 | AVSC_INLINE BYTE* avs_get_write_ptr_p(const AVS_VideoFrame * p, int plane) | |
460 | { | |
461 | if (plane==AVS_PLANAR_Y && avs_is_writable(p)) { | |
462 | ++p->vfb->sequence_number; | |
463 | return p->vfb->data + p->offset; | |
464 | } else if (plane==AVS_PLANAR_Y) { | |
465 | return 0; | |
466 | } else { | |
467 | switch (plane) { | |
468 | case AVS_PLANAR_U: return p->vfb->data + p->offsetU; | |
469 | case AVS_PLANAR_V: return p->vfb->data + p->offsetV; | |
470 | default: return p->vfb->data + p->offset; | |
471 | } | |
518 | case AVS_PLANAR_U: return p->vfb->data + p->offsetU; | |
519 | case AVS_PLANAR_V: return p->vfb->data + p->offsetV; | |
520 | default: return p->vfb->data + p->offset; | |
472 | 521 | } |
473 | 522 | } |
474 | ||
523 | #endif | |
524 | ||
525 | AVSC_INLINE const BYTE* avs_get_read_ptr(const AVS_VideoFrame * p) { | |
526 | return avs_get_read_ptr_p(p, 0);} | |
527 | ||
528 | AVSC_API(int, avs_is_writable)(const AVS_VideoFrame * p); | |
529 | ||
530 | AVSC_API(BYTE *, avs_get_write_ptr_p)(const AVS_VideoFrame * p, int plane); | |
531 | ||
532 | #ifndef AVSC_NO_DECLSPEC | |
533 | AVSC_INLINE BYTE* avs_get_write_ptr(const AVS_VideoFrame * p) { | |
534 | return avs_get_write_ptr_p(p, 0);} | |
535 | #endif | |
475 | 536 | |
476 | 537 | AVSC_API(void, avs_release_video_frame)(AVS_VideoFrame *); |
477 | 538 | // makes a shallow copy of a video frame |
534 | 595 | AVSC_API(AVS_Clip *, avs_take_clip)(AVS_Value, AVS_ScriptEnvironment *); |
535 | 596 | AVSC_API(void, avs_set_to_clip)(AVS_Value *, AVS_Clip *); |
536 | 597 | |
537 | AVSC_INLINE int avs_as_bool(AVS_Value v) | |
538 | { return v.d.boolean; } | |
539 | AVSC_INLINE int avs_as_int(AVS_Value v) | |
540 | { return v.d.integer; } | |
541 | AVSC_INLINE const char * avs_as_string(AVS_Value v) | |
598 | AVSC_INLINE int avs_as_bool(AVS_Value v) | |
599 | { return v.d.boolean; } | |
600 | AVSC_INLINE int avs_as_int(AVS_Value v) | |
601 | { return v.d.integer; } | |
602 | AVSC_INLINE const char * avs_as_string(AVS_Value v) | |
542 | 603 | { return avs_is_error(v) || avs_is_string(v) ? v.d.string : 0; } |
543 | AVSC_INLINE double avs_as_float(AVS_Value v) | |
604 | AVSC_INLINE double avs_as_float(AVS_Value v) | |
544 | 605 | { return avs_is_int(v) ? v.d.integer : v.d.floating_pt; } |
545 | AVSC_INLINE const char * avs_as_error(AVS_Value v) | |
606 | AVSC_INLINE const char * avs_as_error(AVS_Value v) | |
546 | 607 | { return avs_is_error(v) ? v.d.string : 0; } |
547 | 608 | AVSC_INLINE const AVS_Value * avs_as_array(AVS_Value v) |
548 | 609 | { return v.d.array; } |
549 | AVSC_INLINE int avs_array_size(AVS_Value v) | |
610 | AVSC_INLINE int avs_array_size(AVS_Value v) | |
550 | 611 | { return avs_is_array(v) ? v.array_size : 1; } |
551 | AVSC_INLINE AVS_Value avs_array_elt(AVS_Value v, int index) | |
612 | AVSC_INLINE AVS_Value avs_array_elt(AVS_Value v, int index) | |
552 | 613 | { return avs_is_array(v) ? v.d.array[index] : v; } |
553 | 614 | |
554 | 615 | // only use these functions on an AVS_Value that does not already have |
555 | 616 | // an active value. Remember, treat AVS_Value as a fat pointer. |
556 | AVSC_INLINE AVS_Value avs_new_value_bool(int v0) | |
557 | { AVS_Value v; v.type = 'b'; v.d.boolean = v0 == 0 ? 0 : 1; return v; } | |
558 | AVSC_INLINE AVS_Value avs_new_value_int(int v0) | |
559 | { AVS_Value v; v.type = 'i'; v.d.integer = v0; return v; } | |
560 | AVSC_INLINE AVS_Value avs_new_value_string(const char * v0) | |
617 | AVSC_INLINE AVS_Value avs_new_value_bool(int v0) | |
618 | { AVS_Value v; v.type = 'b'; v.d.boolean = v0 == 0 ? 0 : 1; return v; } | |
619 | AVSC_INLINE AVS_Value avs_new_value_int(int v0) | |
620 | { AVS_Value v; v.type = 'i'; v.d.integer = v0; return v; } | |
621 | AVSC_INLINE AVS_Value avs_new_value_string(const char * v0) | |
561 | 622 | { AVS_Value v; v.type = 's'; v.d.string = v0; return v; } |
562 | AVSC_INLINE AVS_Value avs_new_value_float(float v0) | |
623 | AVSC_INLINE AVS_Value avs_new_value_float(float v0) | |
563 | 624 | { AVS_Value v; v.type = 'f'; v.d.floating_pt = v0; return v;} |
564 | AVSC_INLINE AVS_Value avs_new_value_error(const char * v0) | |
625 | AVSC_INLINE AVS_Value avs_new_value_error(const char * v0) | |
565 | 626 | { AVS_Value v; v.type = 'e'; v.d.string = v0; return v; } |
566 | 627 | #ifndef AVSC_NO_DECLSPEC |
567 | 628 | AVSC_INLINE AVS_Value avs_new_value_clip(AVS_Clip * v0) |
568 | 629 | { AVS_Value v; avs_set_to_clip(&v, v0); return v; } |
569 | 630 | #endif |
570 | 631 | AVSC_INLINE AVS_Value avs_new_value_array(AVS_Value * v0, int size) |
571 | { AVS_Value v; v.type = 'a'; v.d.array = v0; v.array_size = size; return v; } | |
632 | { AVS_Value v; v.type = 'a'; v.d.array = v0; v.array_size = (short)size; return v; } | |
572 | 633 | |
573 | 634 | ///////////////////////////////////////////////////////////////////// |
574 | 635 | // |
583 | 644 | AVSC_API(const AVS_VideoInfo *, avs_get_video_info)(AVS_Clip *); |
584 | 645 | |
585 | 646 | AVSC_API(int, avs_get_version)(AVS_Clip *); |
586 | ||
647 | ||
587 | 648 | AVSC_API(AVS_VideoFrame *, avs_get_frame)(AVS_Clip *, int n); |
588 | 649 | // The returned video frame must be released with avs_release_video_frame |
589 | 650 | |
590 | AVSC_API(int, avs_get_parity)(AVS_Clip *, int n); | |
651 | AVSC_API(int, avs_get_parity)(AVS_Clip *, int n); | |
591 | 652 | // return field parity if field_based, else parity of first field in frame |
592 | 653 | |
593 | AVSC_API(int, avs_get_audio)(AVS_Clip *, void * buf, | |
594 | INT64 start, INT64 count); | |
654 | AVSC_API(int, avs_get_audio)(AVS_Clip *, void * buf, | |
655 | INT64 start, INT64 count); | |
595 | 656 | // start and count are in samples |
596 | 657 | |
597 | AVSC_API(int, avs_set_cache_hints)(AVS_Clip *, | |
658 | AVSC_API(int, avs_set_cache_hints)(AVS_Clip *, | |
598 | 659 | int cachehints, int frame_range); |
599 | 660 | |
600 | 661 | // This is the callback type used by avs_add_function |
610 | 671 | AVS_ScriptEnvironment * env; |
611 | 672 | AVS_VideoFrame * (AVSC_CC * get_frame)(AVS_FilterInfo *, int n); |
612 | 673 | int (AVSC_CC * get_parity)(AVS_FilterInfo *, int n); |
613 | int (AVSC_CC * get_audio)(AVS_FilterInfo *, void * buf, | |
674 | int (AVSC_CC * get_audio)(AVS_FilterInfo *, void * buf, | |
614 | 675 | INT64 start, INT64 count); |
615 | int (AVSC_CC * set_cache_hints)(AVS_FilterInfo *, int cachehints, | |
676 | int (AVSC_CC * set_cache_hints)(AVS_FilterInfo *, int cachehints, | |
616 | 677 | int frame_range); |
617 | 678 | void (AVSC_CC * free_filter)(AVS_FilterInfo *); |
618 | ||
679 | ||
619 | 680 | // Should be set when ever there is an error to report. |
620 | 681 | // It is cleared before any of the above methods are called |
621 | 682 | const char * error; |
640 | 701 | // |
641 | 702 | |
642 | 703 | // For GetCPUFlags. These are backwards-compatible with those in VirtualDub. |
643 | enum { | |
704 | enum { | |
644 | 705 | /* slowest CPU to support extension */ |
645 | 706 | AVS_CPU_FORCE = 0x01, // N/A |
646 | 707 | AVS_CPU_FPU = 0x02, // 386/486DX |
650 | 711 | AVS_CPU_SSE2 = 0x20, // PIV, Hammer |
651 | 712 | AVS_CPU_3DNOW = 0x40, // K6-2 |
652 | 713 | AVS_CPU_3DNOW_EXT = 0x80, // Athlon |
653 | AVS_CPU_X86_64 = 0xA0, // Hammer (note: equiv. to 3DNow + SSE2, | |
714 | AVS_CPU_X86_64 = 0xA0, // Hammer (note: equiv. to 3DNow + SSE2, | |
654 | 715 | // which only Hammer will have anyway) |
655 | 716 | AVS_CPUF_SSE3 = 0x100, // PIV+, K8 Venice |
656 | 717 | AVS_CPUF_SSSE3 = 0x200, // Core 2 |
657 | 718 | AVS_CPUF_SSE4 = 0x400, // Penryn, Wolfdale, Yorkfield |
658 | 719 | AVS_CPUF_SSE4_1 = 0x400, |
659 | AVS_CPUF_SSE4_2 = 0x800, // Nehalem | |
720 | //AVS_CPUF_AVX = 0x800, // Sandy Bridge, Bulldozer | |
721 | AVS_CPUF_SSE4_2 = 0x1000, // Nehalem | |
722 | //AVS_CPUF_AVX2 = 0x2000, // Haswell | |
723 | //AVS_CPUF_AVX512 = 0x4000, // Knights Landing | |
660 | 724 | }; |
725 | ||
661 | 726 | |
662 | 727 | AVSC_API(const char *, avs_get_error)(AVS_ScriptEnvironment *); // return 0 if no error |
663 | 728 | |
670 | 735 | AVSC_API(char *, avs_vsprintf)(AVS_ScriptEnvironment *, const char * fmt, void* val); |
671 | 736 | // note: val is really a va_list; I hope everyone typedefs va_list to a pointer |
672 | 737 | |
673 | AVSC_API(int, avs_add_function)(AVS_ScriptEnvironment *, | |
674 | const char * name, const char * params, | |
738 | AVSC_API(int, avs_add_function)(AVS_ScriptEnvironment *, | |
739 | const char * name, const char * params, | |
675 | 740 | AVS_ApplyFunc apply, void * user_data); |
676 | 741 | |
677 | 742 | AVSC_API(int, avs_function_exists)(AVS_ScriptEnvironment *, const char * name); |
678 | 743 | |
679 | AVSC_API(AVS_Value, avs_invoke)(AVS_ScriptEnvironment *, const char * name, | |
744 | AVSC_API(AVS_Value, avs_invoke)(AVS_ScriptEnvironment *, const char * name, | |
680 | 745 | AVS_Value args, const char** arg_names); |
681 | 746 | // The returned value must be be released with avs_release_value |
682 | 747 | |
690 | 755 | //void avs_push_context(AVS_ScriptEnvironment *, int level=0); |
691 | 756 | //void avs_pop_context(AVS_ScriptEnvironment *); |
692 | 757 | |
693 | AVSC_API(AVS_VideoFrame *, avs_new_video_frame_a)(AVS_ScriptEnvironment *, | |
758 | AVSC_API(AVS_VideoFrame *, avs_new_video_frame_a)(AVS_ScriptEnvironment *, | |
694 | 759 | const AVS_VideoInfo * vi, int align); |
695 | 760 | // align should be at least 16 |
696 | 761 | |
697 | 762 | #ifndef AVSC_NO_DECLSPEC |
698 | AVSC_INLINE | |
699 | AVS_VideoFrame * avs_new_video_frame(AVS_ScriptEnvironment * env, | |
763 | AVSC_INLINE | |
764 | AVS_VideoFrame * avs_new_video_frame(AVS_ScriptEnvironment * env, | |
700 | 765 | const AVS_VideoInfo * vi) |
701 | 766 | {return avs_new_video_frame_a(env,vi,AVS_FRAME_ALIGN);} |
702 | 767 | |
703 | AVSC_INLINE | |
704 | AVS_VideoFrame * avs_new_frame(AVS_ScriptEnvironment * env, | |
768 | AVSC_INLINE | |
769 | AVS_VideoFrame * avs_new_frame(AVS_ScriptEnvironment * env, | |
705 | 770 | const AVS_VideoInfo * vi) |
706 | 771 | {return avs_new_video_frame_a(env,vi,AVS_FRAME_ALIGN);} |
707 | 772 | #endif |
771 | 836 | AVSC_DECLARE_FUNC(avs_function_exists); |
772 | 837 | AVSC_DECLARE_FUNC(avs_get_audio); |
773 | 838 | AVSC_DECLARE_FUNC(avs_get_cpu_flags); |
774 | AVSC_DECLARE_FUNC(avs_get_error); | |
775 | 839 | AVSC_DECLARE_FUNC(avs_get_frame); |
776 | 840 | AVSC_DECLARE_FUNC(avs_get_parity); |
777 | 841 | AVSC_DECLARE_FUNC(avs_get_var); |
796 | 860 | AVSC_DECLARE_FUNC(avs_subframe_planar); |
797 | 861 | AVSC_DECLARE_FUNC(avs_take_clip); |
798 | 862 | AVSC_DECLARE_FUNC(avs_vsprintf); |
863 | ||
864 | AVSC_DECLARE_FUNC(avs_get_error); | |
865 | AVSC_DECLARE_FUNC(avs_is_yv24); | |
866 | AVSC_DECLARE_FUNC(avs_is_yv16); | |
867 | AVSC_DECLARE_FUNC(avs_is_yv12); | |
868 | AVSC_DECLARE_FUNC(avs_is_yv411); | |
869 | AVSC_DECLARE_FUNC(avs_is_y8); | |
870 | AVSC_DECLARE_FUNC(avs_is_color_space); | |
871 | ||
872 | AVSC_DECLARE_FUNC(avs_get_plane_width_subsampling); | |
873 | AVSC_DECLARE_FUNC(avs_get_plane_height_subsampling); | |
874 | AVSC_DECLARE_FUNC(avs_bits_per_pixel); | |
875 | AVSC_DECLARE_FUNC(avs_bytes_from_pixels); | |
876 | AVSC_DECLARE_FUNC(avs_row_size_p); | |
877 | AVSC_DECLARE_FUNC(avs_bmp_size); | |
878 | AVSC_DECLARE_FUNC(avs_get_pitch_p); | |
879 | AVSC_DECLARE_FUNC(avs_get_row_size_p); | |
880 | AVSC_DECLARE_FUNC(avs_get_height_p); | |
881 | AVSC_DECLARE_FUNC(avs_get_read_ptr_p); | |
882 | AVSC_DECLARE_FUNC(avs_is_writable); | |
883 | AVSC_DECLARE_FUNC(avs_get_write_ptr_p); | |
799 | 884 | }; |
800 | 885 | |
801 | 886 | #undef AVSC_DECLARE_FUNC |
830 | 915 | AVSC_LOAD_FUNC(avs_function_exists); |
831 | 916 | AVSC_LOAD_FUNC(avs_get_audio); |
832 | 917 | AVSC_LOAD_FUNC(avs_get_cpu_flags); |
833 | AVSC_LOAD_FUNC(avs_get_error); | |
834 | 918 | AVSC_LOAD_FUNC(avs_get_frame); |
835 | 919 | AVSC_LOAD_FUNC(avs_get_parity); |
836 | 920 | AVSC_LOAD_FUNC(avs_get_var); |
856 | 940 | AVSC_LOAD_FUNC(avs_take_clip); |
857 | 941 | AVSC_LOAD_FUNC(avs_vsprintf); |
858 | 942 | |
943 | AVSC_LOAD_FUNC(avs_get_error); | |
944 | AVSC_LOAD_FUNC(avs_is_yv24); | |
945 | AVSC_LOAD_FUNC(avs_is_yv16); | |
946 | AVSC_LOAD_FUNC(avs_is_yv12); | |
947 | AVSC_LOAD_FUNC(avs_is_yv411); | |
948 | AVSC_LOAD_FUNC(avs_is_y8); | |
949 | AVSC_LOAD_FUNC(avs_is_color_space); | |
950 | ||
951 | AVSC_LOAD_FUNC(avs_get_plane_width_subsampling); | |
952 | AVSC_LOAD_FUNC(avs_get_plane_height_subsampling); | |
953 | AVSC_LOAD_FUNC(avs_bits_per_pixel); | |
954 | AVSC_LOAD_FUNC(avs_bytes_from_pixels); | |
955 | AVSC_LOAD_FUNC(avs_row_size_p); | |
956 | AVSC_LOAD_FUNC(avs_bmp_size); | |
957 | AVSC_LOAD_FUNC(avs_get_pitch_p); | |
958 | AVSC_LOAD_FUNC(avs_get_row_size_p); | |
959 | AVSC_LOAD_FUNC(avs_get_height_p); | |
960 | AVSC_LOAD_FUNC(avs_get_read_ptr_p); | |
961 | AVSC_LOAD_FUNC(avs_is_writable); | |
962 | AVSC_LOAD_FUNC(avs_get_write_ptr_p); | |
963 | ||
859 | 964 | #undef __AVSC_STRINGIFY |
860 | 965 | #undef AVSC_STRINGIFY |
861 | 966 | #undef AVSC_LOAD_FUNC |
47 | 47 | while( *option && (strlen( *option ) != length || strncmp( opt, *option, length )) ) |
48 | 48 | option++; |
49 | 49 | |
50 | RETURN_IF_ERROR( !*option, "Invalid option '%.*s'\n", length, opt ) | |
50 | RETURN_IF_ERROR( !*option, "Invalid option '%.*s'\n", length, opt ); | |
51 | 51 | found_named = 1; |
52 | 52 | length += strcspn( opt + length, "," ); |
53 | 53 | } |
54 | 54 | else |
55 | 55 | { |
56 | RETURN_IF_ERROR( opt_count >= options_count, "Too many options given\n" ) | |
57 | RETURN_IF_ERROR( found_named, "Ordered option given after named\n" ) | |
56 | RETURN_IF_ERROR( opt_count >= options_count, "Too many options given\n" ); | |
57 | RETURN_IF_ERROR( found_named, "Ordered option given after named\n" ); | |
58 | 58 | size += strlen( options[opt_count] ) + 1; |
59 | 59 | } |
60 | 60 | opt_count++; |
64 | 64 | int offset = 2 * (opt_count+1) * sizeof(char*); |
65 | 65 | size += offset + (opt - opt_str); |
66 | 66 | char **opts = calloc( 1, size ); |
67 | RETURN_IF_ERROR( !opts, "malloc failed\n" ) | |
67 | RETURN_IF_ERROR( !opts, "malloc failed\n" ); | |
68 | 68 | |
69 | 69 | #define insert_opt( src, length )\ |
70 | 70 | do {\ |
51 | 51 | for( int i = 0; i < 4; i++ ) |
52 | 52 | { |
53 | 53 | char *opt = x264_get_option( optlist[i], opts ); |
54 | FAIL_IF_ERROR( !opt, "%s crop value not specified\n", optlist[i] ) | |
54 | FAIL_IF_ERROR( !opt, "%s crop value not specified\n", optlist[i] ); | |
55 | 55 | h->dims[i] = x264_otoi( opt, -1 ); |
56 | FAIL_IF_ERROR( h->dims[i] < 0, "%s crop value `%s' is less than 0\n", optlist[i], opt ) | |
56 | FAIL_IF_ERROR( h->dims[i] < 0, "%s crop value `%s' is less than 0\n", optlist[i], opt ); | |
57 | 57 | int dim_mod = i&1 ? (h->csp->mod_height << info->interlaced) : h->csp->mod_width; |
58 | FAIL_IF_ERROR( h->dims[i] % dim_mod, "%s crop value `%s' is not a multiple of %d\n", optlist[i], opt, dim_mod ) | |
58 | FAIL_IF_ERROR( h->dims[i] % dim_mod, "%s crop value `%s' is not a multiple of %d\n", optlist[i], opt, dim_mod ); | |
59 | 59 | } |
60 | 60 | return 0; |
61 | 61 | } |
62 | 62 | |
63 | 63 | static int init( hnd_t *handle, cli_vid_filter_t *filter, video_info_t *info, x264_param_t *param, char *opt_string ) |
64 | 64 | { |
65 | FAIL_IF_ERROR( x264_cli_csp_is_invalid( info->csp ), "invalid csp %d\n", info->csp ) | |
65 | FAIL_IF_ERROR( x264_cli_csp_is_invalid( info->csp ), "invalid csp %d\n", info->csp ); | |
66 | 66 | crop_hnd_t *h = calloc( 1, sizeof(crop_hnd_t) ); |
67 | 67 | if( !h ) |
68 | 68 | return -1; |
80 | 80 | |
81 | 81 | h->dims[2] = info->width - h->dims[0] - h->dims[2]; |
82 | 82 | h->dims[3] = info->height - h->dims[1] - h->dims[3]; |
83 | FAIL_IF_ERROR( h->dims[2] <= 0 || h->dims[3] <= 0, "invalid output resolution %dx%d\n", h->dims[2], h->dims[3] ) | |
83 | FAIL_IF_ERROR( h->dims[2] <= 0 || h->dims[3] <= 0, "invalid output resolution %dx%d\n", h->dims[2], h->dims[3] ); | |
84 | 84 | |
85 | 85 | if( info->width != h->dims[2] || info->height != h->dims[3] ) |
86 | 86 | x264_cli_log( NAME, X264_LOG_INFO, "cropping to %dx%d\n", h->dims[2], h->dims[3] ); |
216 | 216 | ret = 1; |
217 | 217 | } |
218 | 218 | |
219 | FAIL_IF_ERROR( bit_depth != X264_BIT_DEPTH, "this build supports only bit depth %d\n", X264_BIT_DEPTH ) | |
220 | FAIL_IF_ERROR( ret, "unsupported bit depth conversion.\n" ) | |
219 | FAIL_IF_ERROR( bit_depth != X264_BIT_DEPTH, "this build supports only bit depth %d\n", X264_BIT_DEPTH ); | |
220 | FAIL_IF_ERROR( ret, "unsupported bit depth conversion.\n" ); | |
221 | 221 | |
222 | 222 | /* only add the filter to the chain if it's needed */ |
223 | 223 | if( change_fmt || bit_depth != 8 * x264_cli_csp_depth_factor( csp ) ) |
224 | 224 | { |
225 | FAIL_IF_ERROR( !depth_filter_csp_is_supported(csp), "unsupported colorspace.\n" ) | |
225 | FAIL_IF_ERROR( !depth_filter_csp_is_supported(csp), "unsupported colorspace.\n" ); | |
226 | 226 | depth_hnd_t *h = x264_malloc( sizeof(depth_hnd_t) + (info->width+1)*sizeof(int16_t) ); |
227 | 227 | |
228 | 228 | if( !h ) |
38 | 38 | int x264_cli_pic_copy( cli_pic_t *out, cli_pic_t *in ) |
39 | 39 | { |
40 | 40 | int csp = in->img.csp & X264_CSP_MASK; |
41 | FAIL_IF_ERROR( x264_cli_csp_is_invalid( in->img.csp ), "invalid colorspace arg %d\n", in->img.csp ) | |
41 | FAIL_IF_ERROR( x264_cli_csp_is_invalid( in->img.csp ), "invalid colorspace arg %d\n", in->img.csp ); | |
42 | 42 | FAIL_IF_ERROR( in->img.csp != out->img.csp || in->img.height != out->img.height |
43 | 43 | || in->img.width != out->img.width, "incompatible frame properties\n" ); |
44 | 44 | /* copy data */ |
264 | 264 | { |
265 | 265 | FAIL_IF_ERROR( 2 != sscanf( str_sar, "%u:%u", &out_sar_w, &out_sar_h ) && |
266 | 266 | 2 != sscanf( str_sar, "%u/%u", &out_sar_w, &out_sar_h ), |
267 | "invalid sar `%s'\n", str_sar ) | |
267 | "invalid sar `%s'\n", str_sar ); | |
268 | 268 | } |
269 | 269 | else |
270 | 270 | out_sar_w = out_sar_h = 1; |
274 | 274 | if( !strcasecmp( fittobox, "both" ) ) |
275 | 275 | { |
276 | 276 | FAIL_IF_ERROR( width <= 0 || height <= 0, "invalid box resolution %sx%s\n", |
277 | x264_otos( str_width, "<unset>" ), x264_otos( str_height, "<unset>" ) ) | |
277 | x264_otos( str_width, "<unset>" ), x264_otos( str_height, "<unset>" ) ); | |
278 | 278 | } |
279 | 279 | else if( !strcasecmp( fittobox, "width" ) ) |
280 | 280 | { |
281 | FAIL_IF_ERROR( width <= 0, "invalid box width `%s'\n", x264_otos( str_width, "<unset>" ) ) | |
281 | FAIL_IF_ERROR( width <= 0, "invalid box width `%s'\n", x264_otos( str_width, "<unset>" ) ); | |
282 | 282 | height = INT_MAX; |
283 | 283 | } |
284 | 284 | else if( !strcasecmp( fittobox, "height" ) ) |
285 | 285 | { |
286 | FAIL_IF_ERROR( height <= 0, "invalid box height `%s'\n", x264_otos( str_height, "<unset>" ) ) | |
286 | FAIL_IF_ERROR( height <= 0, "invalid box height `%s'\n", x264_otos( str_height, "<unset>" ) ); | |
287 | 287 | width = INT_MAX; |
288 | 288 | } |
289 | else FAIL_IF_ERROR( 1, "invalid fittobox mode `%s'\n", fittobox ) | |
289 | else FAIL_IF_ERROR( 1, "invalid fittobox mode `%s'\n", fittobox ); | |
290 | 290 | |
291 | 291 | /* maximally fit the new coded resolution to the box */ |
292 | 292 | const x264_cli_csp_t *csp = x264_cli_get_csp( h->dst_csp ); |
312 | 312 | if( str_width || str_height ) |
313 | 313 | { |
314 | 314 | FAIL_IF_ERROR( width <= 0 || height <= 0, "invalid resolution %sx%s\n", |
315 | x264_otos( str_width, "<unset>" ), x264_otos( str_height, "<unset>" ) ) | |
315 | x264_otos( str_width, "<unset>" ), x264_otos( str_height, "<unset>" ) ); | |
316 | 316 | if( !str_sar ) /* res only -> adjust sar */ |
317 | 317 | { |
318 | 318 | /* new_sar = (new_h * old_w * old_sar_w) / (old_h * new_w * old_sar_h) */ |
402 | 402 | return -1; |
403 | 403 | h->buffer_allocated = 1; |
404 | 404 | } |
405 | FAIL_IF_ERROR( x264_init_sws_context( h ), "swscale init failed\n" ) | |
405 | FAIL_IF_ERROR( x264_init_sws_context( h ), "swscale init failed\n" ); | |
406 | 406 | return 0; |
407 | 407 | } |
408 | 408 | |
439 | 439 | h->variable_input = 1; |
440 | 440 | h->dst_csp = pick_closest_supported_csp( info->csp ); |
441 | 441 | FAIL_IF_ERROR( h->dst_csp == X264_CSP_NONE, |
442 | "filter get invalid input pixel format %d (colorspace %d)\n", convert_csp_to_pix_fmt( info->csp ), info->csp ) | |
442 | "filter get invalid input pixel format %d (colorspace %d)\n", convert_csp_to_pix_fmt( info->csp ), info->csp ); | |
443 | 443 | } |
444 | 444 | else |
445 | 445 | { |
478 | 478 | FAIL_IF_ERROR( src_pix_fmt == AV_PIX_FMT_NONE && src_pix_fmt_inv != AV_PIX_FMT_NONE, |
479 | 479 | "input colorspace %s with bit depth %d is not supported\n", av_get_pix_fmt_name( src_pix_fmt_inv ), |
480 | 480 | info->csp & X264_CSP_HIGH_DEPTH ? 16 : 8 ); |
481 | FAIL_IF_ERROR( !sws_isSupportedInput( src_pix_fmt ), "input colorspace %s is not supported\n", av_get_pix_fmt_name( src_pix_fmt ) ) | |
481 | FAIL_IF_ERROR( !sws_isSupportedInput( src_pix_fmt ), "input colorspace %s is not supported\n", av_get_pix_fmt_name( src_pix_fmt ) ); | |
482 | 482 | FAIL_IF_ERROR( h->dst.pix_fmt == AV_PIX_FMT_NONE && dst_pix_fmt_inv != AV_PIX_FMT_NONE, |
483 | 483 | "input colorspace %s with bit depth %d is not supported\n", av_get_pix_fmt_name( dst_pix_fmt_inv ), |
484 | 484 | h->dst_csp & X264_CSP_HIGH_DEPTH ? 16 : 8 ); |
485 | FAIL_IF_ERROR( !sws_isSupportedOutput( h->dst.pix_fmt ), "output colorspace %s is not supported\n", av_get_pix_fmt_name( h->dst.pix_fmt ) ) | |
485 | FAIL_IF_ERROR( !sws_isSupportedOutput( h->dst.pix_fmt ), "output colorspace %s is not supported\n", av_get_pix_fmt_name( h->dst.pix_fmt ) ); | |
486 | 486 | FAIL_IF_ERROR( h->dst.height != info->height && info->interlaced, |
487 | "swscale is not compatible with interlaced vertical resizing\n" ) | |
487 | "swscale is not compatible with interlaced vertical resizing\n" ); | |
488 | 488 | /* confirm that the desired resolution meets the colorspace requirements */ |
489 | 489 | const x264_cli_csp_t *csp = x264_cli_get_csp( h->dst_csp ); |
490 | 490 | FAIL_IF_ERROR( h->dst.width % csp->mod_width || h->dst.height % csp->mod_height, |
491 | "resolution %dx%d is not compliant with colorspace %s\n", h->dst.width, h->dst.height, csp->name ) | |
491 | "resolution %dx%d is not compliant with colorspace %s\n", h->dst.width, h->dst.height, csp->name ); | |
492 | 492 | |
493 | 493 | if( h->dst.width != info->width || h->dst.height != info->height ) |
494 | 494 | x264_cli_log( NAME, X264_LOG_INFO, "resizing to %dx%d\n", h->dst.width, h->dst.height ); |
579 | 579 | } |
580 | 580 | |
581 | 581 | /* pass if nothing needs to be done, otherwise fail */ |
582 | FAIL_IF_ERROR( ret, "not compiled with swscale support\n" ) | |
582 | FAIL_IF_ERROR( ret, "not compiled with swscale support\n" ); | |
583 | 583 | return 0; |
584 | 584 | } |
585 | 585 |
66 | 66 | int val = x264_otoi( tok, -1 ); |
67 | 67 | if( p ) |
68 | 68 | { |
69 | FAIL_IF_ERROR( val <= 0, "invalid step `%s'\n", tok ) | |
69 | FAIL_IF_ERROR( val <= 0, "invalid step `%s'\n", tok ); | |
70 | 70 | h->step_size = val; |
71 | 71 | continue; |
72 | 72 | } |
73 | FAIL_IF_ERROR( val < 0 || val >= h->step_size, "invalid offset `%s'\n", tok ) | |
74 | FAIL_IF_ERROR( h->pattern_len >= MAX_PATTERN_SIZE, "max pattern size %d reached\n", MAX_PATTERN_SIZE ) | |
73 | FAIL_IF_ERROR( val < 0 || val >= h->step_size, "invalid offset `%s'\n", tok ); | |
74 | FAIL_IF_ERROR( h->pattern_len >= MAX_PATTERN_SIZE, "max pattern size %d reached\n", MAX_PATTERN_SIZE ); | |
75 | 75 | offsets[h->pattern_len++] = val; |
76 | 76 | } |
77 | FAIL_IF_ERROR( !h->step_size, "no step size provided\n" ) | |
78 | FAIL_IF_ERROR( !h->pattern_len, "no offsets supplied\n" ) | |
77 | FAIL_IF_ERROR( !h->step_size, "no step size provided\n" ); | |
78 | FAIL_IF_ERROR( !h->pattern_len, "no offsets supplied\n" ); | |
79 | 79 | |
80 | 80 | h->pattern = malloc( h->pattern_len * sizeof(int) ); |
81 | 81 | if( !h->pattern ) |
3 | 3 | * Copyright (C) 2009-2016 x264 project |
4 | 4 | * |
5 | 5 | * Authors: Steven Walters <kemuri9@gmail.com> |
6 | * Anton Mitrofanov <BugMaster@narod.ru> | |
6 | 7 | * |
7 | 8 | * This program is free software; you can redistribute it and/or modify |
8 | 9 | * it under the terms of the GNU General Public License as published by |
33 | 34 | #define avs_close dlclose |
34 | 35 | #define avs_address dlsym |
35 | 36 | #else |
36 | #include <windows.h> | |
37 | 37 | #define avs_open() LoadLibraryW( L"avisynth" ) |
38 | 38 | #define avs_close FreeLibrary |
39 | 39 | #define avs_address GetProcAddress |
57 | 57 | #include <libavutil/pixfmt.h> |
58 | 58 | #endif |
59 | 59 | |
60 | /* AvxSynth doesn't have yv24, yv16, yv411, or y8, so disable them. */ | |
61 | #if USE_AVXSYNTH | |
62 | #define avs_is_yv24( vi ) 0 | |
63 | #define avs_is_yv16( vi ) 0 | |
64 | #define avs_is_yv411( vi ) 0 | |
65 | #define avs_is_y8( vi ) 0 | |
66 | #endif | |
67 | ||
68 | 60 | /* maximum size of the sequence of filters to try on non script files */ |
69 | 61 | #define AVS_MAX_SEQUENCE 5 |
70 | 62 | |
71 | 63 | #define LOAD_AVS_FUNC(name, continue_on_fail)\ |
72 | 64 | {\ |
73 | 65 | h->func.name = (void*)avs_address( h->library, #name );\ |
66 | if( !continue_on_fail && !h->func.name )\ | |
67 | goto fail;\ | |
68 | } | |
69 | ||
70 | #define LOAD_AVS_FUNC_ALIAS(name, alias, continue_on_fail)\ | |
71 | {\ | |
72 | if( !h->func.name )\ | |
73 | h->func.name = (void*)avs_address( h->library, alias );\ | |
74 | 74 | if( !continue_on_fail && !h->func.name )\ |
75 | 75 | goto fail;\ |
76 | 76 | } |
95 | 95 | AVSC_DECLARE_FUNC( avs_release_value ); |
96 | 96 | AVSC_DECLARE_FUNC( avs_release_video_frame ); |
97 | 97 | AVSC_DECLARE_FUNC( avs_take_clip ); |
98 | #if !USE_AVXSYNTH | |
99 | // AviSynth+ extension | |
100 | AVSC_DECLARE_FUNC( avs_is_rgb48 ); | |
101 | AVSC_DECLARE_FUNC( avs_is_rgb64 ); | |
102 | AVSC_DECLARE_FUNC( avs_is_yuv444p16 ); | |
103 | AVSC_DECLARE_FUNC( avs_is_yuv422p16 ); | |
104 | AVSC_DECLARE_FUNC( avs_is_yuv420p16 ); | |
105 | AVSC_DECLARE_FUNC( avs_is_y16 ); | |
106 | AVSC_DECLARE_FUNC( avs_is_yuv444ps ); | |
107 | AVSC_DECLARE_FUNC( avs_is_yuv422ps ); | |
108 | AVSC_DECLARE_FUNC( avs_is_yuv420ps ); | |
109 | AVSC_DECLARE_FUNC( avs_is_y32 ); | |
110 | AVSC_DECLARE_FUNC( avs_is_444 ); | |
111 | AVSC_DECLARE_FUNC( avs_is_422 ); | |
112 | AVSC_DECLARE_FUNC( avs_is_420 ); | |
113 | AVSC_DECLARE_FUNC( avs_is_y ); | |
114 | AVSC_DECLARE_FUNC( avs_is_yuva ); | |
115 | AVSC_DECLARE_FUNC( avs_is_planar_rgb ); | |
116 | AVSC_DECLARE_FUNC( avs_is_planar_rgba ); | |
117 | AVSC_DECLARE_FUNC( avs_num_components ); | |
118 | AVSC_DECLARE_FUNC( avs_component_size ); | |
119 | AVSC_DECLARE_FUNC( avs_bits_per_component ); | |
120 | #endif | |
98 | 121 | } func; |
99 | 122 | } avs_hnd_t; |
100 | 123 | |
116 | 139 | LOAD_AVS_FUNC( avs_release_value, 0 ); |
117 | 140 | LOAD_AVS_FUNC( avs_release_video_frame, 0 ); |
118 | 141 | LOAD_AVS_FUNC( avs_take_clip, 0 ); |
142 | #if !USE_AVXSYNTH | |
143 | // AviSynth+ extension | |
144 | LOAD_AVS_FUNC( avs_is_rgb48, 1 ); | |
145 | LOAD_AVS_FUNC_ALIAS( avs_is_rgb48, "_avs_is_rgb48@4", 1 ); | |
146 | LOAD_AVS_FUNC( avs_is_rgb64, 1 ); | |
147 | LOAD_AVS_FUNC_ALIAS( avs_is_rgb64, "_avs_is_rgb64@4", 1 ); | |
148 | LOAD_AVS_FUNC( avs_is_yuv444p16, 1 ); | |
149 | LOAD_AVS_FUNC( avs_is_yuv422p16, 1 ); | |
150 | LOAD_AVS_FUNC( avs_is_yuv420p16, 1 ); | |
151 | LOAD_AVS_FUNC( avs_is_y16, 1 ); | |
152 | LOAD_AVS_FUNC( avs_is_yuv444ps, 1 ); | |
153 | LOAD_AVS_FUNC( avs_is_yuv422ps, 1 ); | |
154 | LOAD_AVS_FUNC( avs_is_yuv420ps, 1 ); | |
155 | LOAD_AVS_FUNC( avs_is_y32, 1 ); | |
156 | LOAD_AVS_FUNC( avs_is_444, 1 ); | |
157 | LOAD_AVS_FUNC( avs_is_422, 1 ); | |
158 | LOAD_AVS_FUNC( avs_is_420, 1 ); | |
159 | LOAD_AVS_FUNC( avs_is_y, 1 ); | |
160 | LOAD_AVS_FUNC( avs_is_yuva, 1 ); | |
161 | LOAD_AVS_FUNC( avs_is_planar_rgb, 1 ); | |
162 | LOAD_AVS_FUNC( avs_is_planar_rgba, 1 ); | |
163 | LOAD_AVS_FUNC( avs_num_components, 1 ); | |
164 | LOAD_AVS_FUNC( avs_component_size, 1 ); | |
165 | LOAD_AVS_FUNC( avs_bits_per_component, 1 ); | |
166 | #endif | |
119 | 167 | return 0; |
120 | 168 | fail: |
121 | 169 | avs_close( h->library ); |
170 | h->library = NULL; | |
122 | 171 | return -1; |
123 | 172 | } |
173 | ||
174 | /* AvxSynth doesn't have yv24, yv16, yv411, or y8, so disable them. */ | |
175 | #if USE_AVXSYNTH | |
176 | #define avs_is_yv24( vi ) (0) | |
177 | #define avs_is_yv16( vi ) (0) | |
178 | #define avs_is_yv411( vi ) (0) | |
179 | #define avs_is_y8( vi ) (0) | |
180 | /* AvxSynth doesn't support AviSynth+ pixel types. */ | |
181 | #define AVS_IS_AVISYNTHPLUS (0) | |
182 | #define AVS_IS_420( vi ) (0) | |
183 | #define AVS_IS_422( vi ) (0) | |
184 | #define AVS_IS_444( vi ) (0) | |
185 | #define AVS_IS_RGB48( vi ) (0) | |
186 | #define AVS_IS_RGB64( vi ) (0) | |
187 | #define AVS_IS_YUV420P16( vi ) (0) | |
188 | #define AVS_IS_YUV422P16( vi ) (0) | |
189 | #define AVS_IS_YUV444P16( vi ) (0) | |
190 | #else | |
191 | #define AVS_IS_AVISYNTHPLUS (h->func.avs_is_420 && h->func.avs_is_422 && h->func.avs_is_444) | |
192 | #define AVS_IS_420( vi ) (h->func.avs_is_420 ? h->func.avs_is_420( vi ) : avs_is_yv12( vi )) | |
193 | #define AVS_IS_422( vi ) (h->func.avs_is_422 ? h->func.avs_is_422( vi ) : avs_is_yv16( vi )) | |
194 | #define AVS_IS_444( vi ) (h->func.avs_is_444 ? h->func.avs_is_444( vi ) : avs_is_yv24( vi )) | |
195 | #define AVS_IS_RGB48( vi ) (h->func.avs_is_rgb48 && h->func.avs_is_rgb48( vi )) | |
196 | #define AVS_IS_RGB64( vi ) (h->func.avs_is_rgb64 && h->func.avs_is_rgb64( vi )) | |
197 | #define AVS_IS_YUV420P16( vi ) (h->func.avs_is_yuv420p16 && h->func.avs_is_yuv420p16( vi )) | |
198 | #define AVS_IS_YUV422P16( vi ) (h->func.avs_is_yuv422p16 && h->func.avs_is_yuv422p16( vi )) | |
199 | #define AVS_IS_YUV444P16( vi ) (h->func.avs_is_yuv444p16 && h->func.avs_is_yuv444p16( vi )) | |
200 | #endif | |
124 | 201 | |
125 | 202 | /* generate a filter sequence to try based on the filename extension */ |
126 | 203 | static void avs_build_filter_sequence( char *filename_ext, const char *filter[AVS_MAX_SEQUENCE+1] ) |
159 | 236 | #if USE_AVXSYNTH |
160 | 237 | return 2.58f; |
161 | 238 | #else |
162 | FAIL_IF_ERROR( !h->func.avs_function_exists( h->env, "VersionNumber" ), "VersionNumber does not exist\n" ) | |
239 | FAIL_IF_ERROR( !h->func.avs_function_exists( h->env, "VersionNumber" ), "VersionNumber does not exist\n" ); | |
163 | 240 | AVS_Value ver = h->func.avs_invoke( h->env, "VersionNumber", avs_new_value_array( NULL, 0 ), NULL ); |
164 | FAIL_IF_ERROR( avs_is_error( ver ), "unable to determine avisynth version: %s\n", avs_as_error( ver ) ) | |
241 | FAIL_IF_ERROR( avs_is_error( ver ), "unable to determine avisynth version: %s\n", avs_as_error( ver ) ); | |
165 | 242 | FAIL_IF_ERROR( !avs_is_float( ver ), "VersionNumber did not return a float value\n" ); |
166 | 243 | float ret = avs_as_float( ver ); |
167 | 244 | h->func.avs_release_value( ver ); |
178 | 255 | fclose( fh ); |
179 | 256 | FAIL_IF_ERROR( !b_regular, "AVS input is incompatible with non-regular file `%s'\n", psz_filename ); |
180 | 257 | |
181 | avs_hnd_t *h = malloc( sizeof(avs_hnd_t) ); | |
258 | avs_hnd_t *h = calloc( 1, sizeof(avs_hnd_t) ); | |
182 | 259 | if( !h ) |
183 | 260 | return -1; |
184 | FAIL_IF_ERROR( x264_avs_load_library( h ), "failed to load avisynth\n" ) | |
261 | FAIL_IF_ERROR( x264_avs_load_library( h ), "failed to load avisynth\n" ); | |
185 | 262 | h->env = h->func.avs_create_script_environment( AVS_INTERFACE_25 ); |
186 | 263 | if( h->func.avs_get_error ) |
187 | 264 | { |
208 | 285 | if( !strcasecmp( filename_ext, "avs" ) ) |
209 | 286 | { |
210 | 287 | res = h->func.avs_invoke( h->env, "Import", arg, NULL ); |
211 | FAIL_IF_ERROR( avs_is_error( res ), "%s\n", avs_as_string( res ) ) | |
288 | FAIL_IF_ERROR( avs_is_error( res ), "%s\n", avs_as_string( res ) ); | |
212 | 289 | /* check if the user is using a multi-threaded script and apply distributor if necessary. |
213 | 290 | adapted from avisynth's vfw interface */ |
214 | 291 | AVS_Value mt_test = h->func.avs_invoke( h->env, "GetMTMode", avs_new_value_bool( 0 ), NULL ); |
248 | 325 | } |
249 | 326 | x264_cli_printf( X264_LOG_INFO, "failed\n" ); |
250 | 327 | } |
251 | FAIL_IF_ERROR( !filter[i], "unable to find source filter to open `%s'\n", psz_filename ) | |
252 | } | |
253 | FAIL_IF_ERROR( !avs_is_clip( res ), "`%s' didn't return a video clip\n", psz_filename ) | |
328 | FAIL_IF_ERROR( !filter[i], "unable to find source filter to open `%s'\n", psz_filename ); | |
329 | } | |
330 | FAIL_IF_ERROR( !avs_is_clip( res ), "`%s' didn't return a video clip\n", psz_filename ); | |
254 | 331 | h->clip = h->func.avs_take_clip( res, h->env ); |
255 | 332 | const AVS_VideoInfo *vi = h->func.avs_get_video_info( h->clip ); |
256 | FAIL_IF_ERROR( !avs_has_video( vi ), "`%s' has no video data\n", psz_filename ) | |
333 | FAIL_IF_ERROR( !avs_has_video( vi ), "`%s' has no video data\n", psz_filename ); | |
257 | 334 | /* if the clip is made of fields instead of frames, call weave to make them frames */ |
258 | 335 | if( avs_is_field_based( vi ) ) |
259 | 336 | { |
260 | 337 | x264_cli_log( "avs", X264_LOG_WARNING, "detected fieldbased (separated) input, weaving to frames\n" ); |
261 | 338 | AVS_Value tmp = h->func.avs_invoke( h->env, "Weave", res, NULL ); |
262 | FAIL_IF_ERROR( avs_is_error( tmp ), "couldn't weave fields into frames\n" ) | |
339 | FAIL_IF_ERROR( avs_is_error( tmp ), "couldn't weave fields into frames\n" ); | |
263 | 340 | res = update_clip( h, &vi, tmp, res ); |
264 | 341 | info->interlaced = 1; |
265 | 342 | info->tff = avs_is_tff( vi ); |
267 | 344 | #if !HAVE_SWSCALE |
268 | 345 | /* if swscale is not available, convert the CSP if necessary */ |
269 | 346 | FAIL_IF_ERROR( avs_version < 2.6f && (opt->output_csp == X264_CSP_I422 || opt->output_csp == X264_CSP_I444), |
270 | "avisynth >= 2.6 is required for i422/i444 output\n" ) | |
271 | if( (opt->output_csp == X264_CSP_I420 && !avs_is_yv12( vi )) || (opt->output_csp == X264_CSP_I422 && !avs_is_yv16( vi )) || | |
272 | (opt->output_csp == X264_CSP_I444 && !avs_is_yv24( vi )) || (opt->output_csp == X264_CSP_RGB && !avs_is_rgb( vi )) ) | |
273 | { | |
274 | ||
275 | const char *csp = opt->output_csp == X264_CSP_I420 ? "YV12" : | |
276 | opt->output_csp == X264_CSP_I422 ? "YV16" : | |
277 | opt->output_csp == X264_CSP_I444 ? "YV24" : "RGB"; | |
347 | "avisynth >= 2.6 is required for i422/i444 output\n" ); | |
348 | if( (opt->output_csp == X264_CSP_I420 && !AVS_IS_420( vi )) || | |
349 | (opt->output_csp == X264_CSP_I422 && !AVS_IS_422( vi )) || | |
350 | (opt->output_csp == X264_CSP_I444 && !AVS_IS_444( vi )) || | |
351 | (opt->output_csp == X264_CSP_RGB && !avs_is_rgb( vi )) ) | |
352 | { | |
353 | const char *csp; | |
354 | if( AVS_IS_AVISYNTHPLUS ) | |
355 | { | |
356 | csp = opt->output_csp == X264_CSP_I420 ? "YUV420" : | |
357 | opt->output_csp == X264_CSP_I422 ? "YUV422" : | |
358 | opt->output_csp == X264_CSP_I444 ? "YUV444" : | |
359 | "RGB"; | |
360 | } | |
361 | else | |
362 | { | |
363 | csp = opt->output_csp == X264_CSP_I420 ? "YV12" : | |
364 | opt->output_csp == X264_CSP_I422 ? "YV16" : | |
365 | opt->output_csp == X264_CSP_I444 ? "YV24" : | |
366 | "RGB"; | |
367 | } | |
278 | 368 | x264_cli_log( "avs", X264_LOG_WARNING, "converting input clip to %s\n", csp ); |
279 | 369 | FAIL_IF_ERROR( opt->output_csp < X264_CSP_I444 && (vi->width&1), |
280 | "input clip width not divisible by 2 (%dx%d)\n", vi->width, vi->height ) | |
370 | "input clip width not divisible by 2 (%dx%d)\n", vi->width, vi->height ); | |
281 | 371 | FAIL_IF_ERROR( opt->output_csp == X264_CSP_I420 && info->interlaced && (vi->height&3), |
282 | "input clip height not divisible by 4 (%dx%d)\n", vi->width, vi->height ) | |
372 | "input clip height not divisible by 4 (%dx%d)\n", vi->width, vi->height ); | |
283 | 373 | FAIL_IF_ERROR( (opt->output_csp == X264_CSP_I420 || info->interlaced) && (vi->height&1), |
284 | "input clip height not divisible by 2 (%dx%d)\n", vi->width, vi->height ) | |
285 | char conv_func[14]; | |
374 | "input clip height not divisible by 2 (%dx%d)\n", vi->width, vi->height ); | |
375 | char conv_func[16]; | |
286 | 376 | snprintf( conv_func, sizeof(conv_func), "ConvertTo%s", csp ); |
287 | 377 | char matrix[7] = ""; |
288 | 378 | int arg_count = 2; |
302 | 392 | arg_arr[1] = avs_new_value_bool( info->interlaced ); |
303 | 393 | arg_arr[2] = avs_new_value_string( matrix ); |
304 | 394 | AVS_Value res2 = h->func.avs_invoke( h->env, conv_func, avs_new_value_array( arg_arr, arg_count ), arg_name ); |
305 | FAIL_IF_ERROR( avs_is_error( res2 ), "couldn't convert input clip to %s\n", csp ) | |
395 | FAIL_IF_ERROR( avs_is_error( res2 ), "couldn't convert input clip to %s\n", csp ); | |
306 | 396 | res = update_clip( h, &vi, res2, res ); |
307 | 397 | } |
308 | 398 | /* if swscale is not available, change the range if necessary. This only applies to YUV-based CSPs however */ |
315 | 405 | arg_arr[1] = avs_new_value_string( levels ); |
316 | 406 | const char *arg_name[] = { NULL, "levels" }; |
317 | 407 | AVS_Value res2 = h->func.avs_invoke( h->env, "ColorYUV", avs_new_value_array( arg_arr, 2 ), arg_name ); |
318 | FAIL_IF_ERROR( avs_is_error( res2 ), "couldn't convert range: %s\n", avs_as_error( res2 ) ) | |
408 | FAIL_IF_ERROR( avs_is_error( res2 ), "couldn't convert range: %s\n", avs_as_error( res2 ) ); | |
319 | 409 | res = update_clip( h, &vi, res2, res ); |
320 | 410 | // notification that the input range has changed to the desired one |
321 | 411 | opt->input_range = opt->output_range; |
330 | 420 | info->fps_den = vi->fps_denominator; |
331 | 421 | h->num_frames = info->num_frames = vi->num_frames; |
332 | 422 | info->thread_safe = 1; |
333 | if( avs_is_rgb32( vi ) ) | |
423 | if( AVS_IS_RGB64( vi ) ) | |
424 | info->csp = X264_CSP_BGRA | X264_CSP_VFLIP | X264_CSP_HIGH_DEPTH; | |
425 | else if( avs_is_rgb32( vi ) ) | |
334 | 426 | info->csp = X264_CSP_BGRA | X264_CSP_VFLIP; |
427 | else if( AVS_IS_RGB48( vi ) ) | |
428 | info->csp = X264_CSP_BGR | X264_CSP_VFLIP | X264_CSP_HIGH_DEPTH; | |
335 | 429 | else if( avs_is_rgb24( vi ) ) |
336 | 430 | info->csp = X264_CSP_BGR | X264_CSP_VFLIP; |
431 | else if( AVS_IS_YUV444P16( vi ) ) | |
432 | info->csp = X264_CSP_I444 | X264_CSP_HIGH_DEPTH; | |
337 | 433 | else if( avs_is_yv24( vi ) ) |
338 | 434 | info->csp = X264_CSP_I444; |
435 | else if( AVS_IS_YUV422P16( vi ) ) | |
436 | info->csp = X264_CSP_I422 | X264_CSP_HIGH_DEPTH; | |
339 | 437 | else if( avs_is_yv16( vi ) ) |
340 | 438 | info->csp = X264_CSP_I422; |
439 | else if( AVS_IS_YUV420P16( vi ) ) | |
440 | info->csp = X264_CSP_I420 | X264_CSP_HIGH_DEPTH; | |
341 | 441 | else if( avs_is_yv12( vi ) ) |
342 | 442 | info->csp = X264_CSP_I420; |
343 | 443 | #if HAVE_SWSCALE |
349 | 449 | info->csp = AV_PIX_FMT_GRAY8 | X264_CSP_OTHER; |
350 | 450 | #endif |
351 | 451 | else |
352 | info->csp = X264_CSP_NONE; | |
452 | { | |
453 | AVS_Value pixel_type = h->func.avs_invoke( h->env, "PixelType", res, NULL ); | |
454 | const char *pixel_type_name = avs_is_string( pixel_type ) ? avs_as_string( pixel_type ) : "unknown"; | |
455 | FAIL_IF_ERROR( 1, "not supported pixel type: %s\n", pixel_type_name ); | |
456 | } | |
353 | 457 | info->vfr = 0; |
354 | 458 | |
355 | 459 | *p_handle = h; |
381 | 485 | return -1; |
382 | 486 | AVS_VideoFrame *frm = pic->opaque = h->func.avs_get_frame( h->clip, i_frame ); |
383 | 487 | const char *err = h->func.avs_clip_get_error( h->clip ); |
384 | FAIL_IF_ERROR( err, "%s occurred while reading frame %d\n", err, i_frame ) | |
488 | FAIL_IF_ERROR( err, "%s occurred while reading frame %d\n", err, i_frame ); | |
385 | 489 | for( int i = 0; i < pic->img.planes; i++ ) |
386 | 490 | { |
387 | 491 | /* explicitly cast away the const attribute to avoid a warning */ |
406 | 510 | static int close_file( hnd_t handle ) |
407 | 511 | { |
408 | 512 | avs_hnd_t *h = handle; |
409 | h->func.avs_release_clip( h->clip ); | |
410 | if( h->func.avs_delete_script_environment ) | |
513 | if( h->func.avs_release_clip && h->clip ) | |
514 | h->func.avs_release_clip( h->clip ); | |
515 | if( h->func.avs_delete_script_environment && h->env ) | |
411 | 516 | h->func.avs_delete_script_environment( h->env ); |
412 | avs_close( h->library ); | |
517 | if( h->library ) | |
518 | avs_close( h->library ); | |
413 | 519 | free( h ); |
414 | 520 | return 0; |
415 | 521 | } |
31 | 31 | #undef DECLARE_ALIGNED |
32 | 32 | #include <libavcodec/avcodec.h> |
33 | 33 | #include <libswscale/swscale.h> |
34 | ||
35 | #ifdef _WIN32 | |
36 | #include <windows.h> | |
37 | #endif | |
38 | 34 | |
39 | 35 | #define PROGRESS_LENGTH 36 |
40 | 36 | |
105 | 101 | if( !idx ) |
106 | 102 | { |
107 | 103 | FFMS_Indexer *indexer = FFMS_CreateIndexer( psz_filename, &e ); |
108 | FAIL_IF_ERROR( !indexer, "could not create indexer\n" ) | |
104 | FAIL_IF_ERROR( !indexer, "could not create indexer\n" ); | |
109 | 105 | |
110 | 106 | if( opt->progress ) |
111 | 107 | FFMS_SetProgressCallback( indexer, update_progress, &h->time ); |
112 | 108 | |
113 | 109 | idx = FFMS_DoIndexing2( indexer, FFMS_IEH_ABORT, &e ); |
114 | 110 | fprintf( stderr, "%*c", PROGRESS_LENGTH+1, '\r' ); |
115 | FAIL_IF_ERROR( !idx, "could not create index\n" ) | |
111 | FAIL_IF_ERROR( !idx, "could not create index\n" ); | |
116 | 112 | |
117 | 113 | if( opt->index_file && FFMS_WriteIndex( opt->index_file, idx, &e ) ) |
118 | 114 | x264_cli_log( "ffms", X264_LOG_WARNING, "could not write index file\n" ); |
123 | 119 | h->video_source = FFMS_CreateVideoSource( psz_filename, trackno, idx, 1, seekmode, &e ); |
124 | 120 | FFMS_DestroyIndex( idx ); |
125 | 121 | |
126 | FAIL_IF_ERROR( trackno < 0, "could not find video track\n" ) | |
127 | FAIL_IF_ERROR( !h->video_source, "could not create video source\n" ) | |
122 | FAIL_IF_ERROR( trackno < 0, "could not find video track\n" ); | |
123 | FAIL_IF_ERROR( !h->video_source, "could not create video source\n" ); | |
128 | 124 | |
129 | 125 | const FFMS_VideoProperties *videop = FFMS_GetVideoProperties( h->video_source ); |
130 | 126 | info->num_frames = h->num_frames = videop->NumFrames; |
137 | 133 | info->thread_safe = 0; |
138 | 134 | |
139 | 135 | const FFMS_Frame *frame = FFMS_GetFrame( h->video_source, 0, &e ); |
140 | FAIL_IF_ERROR( !frame, "could not read frame 0\n" ) | |
136 | FAIL_IF_ERROR( !frame, "could not read frame 0\n" ); | |
141 | 137 | |
142 | 138 | info->fullrange = 0; |
143 | 139 | info->width = frame->EncodedWidth; |
188 | 184 | FFMS_ErrorInfo e; |
189 | 185 | e.BufferSize = 0; |
190 | 186 | const FFMS_Frame *frame = FFMS_GetFrame( h->video_source, i_frame, &e ); |
191 | FAIL_IF_ERROR( !frame, "could not read frame %d \n", i_frame ) | |
187 | FAIL_IF_ERROR( !frame, "could not read frame %d \n", i_frame ); | |
192 | 188 | |
193 | 189 | memcpy( pic->img.stride, frame->Linesize, sizeof(pic->img.stride) ); |
194 | 190 | memcpy( pic->img.plane, frame->Data, sizeof(pic->img.plane) ); |
197 | 193 | { |
198 | 194 | const FFMS_FrameInfo *info = FFMS_GetFrameInfo( h->track, i_frame ); |
199 | 195 | FAIL_IF_ERROR( info->PTS == AV_NOPTS_VALUE, "invalid timestamp. " |
200 | "Use --force-cfr and specify a framerate with --fps\n" ) | |
196 | "Use --force-cfr and specify a framerate with --fps\n" ); | |
201 | 197 | |
202 | 198 | pic->pts = info->PTS >> h->reduce_pts; |
203 | 199 | pic->duration = 0; |
27 | 27 | |
28 | 28 | #ifdef _WIN32 |
29 | 29 | #include <io.h> |
30 | #include <windows.h> | |
31 | 30 | #elif HAVE_MMAP |
32 | 31 | #include <sys/mman.h> |
33 | 32 | #include <unistd.h> |
153 | 152 | SYSTEM_INFO si; |
154 | 153 | GetSystemInfo( &si ); |
155 | 154 | h->align_mask = si.dwAllocationGranularity - 1; |
155 | h->prefetch_virtual_memory = (void*)GetProcAddress( GetModuleHandleW( L"kernel32.dll" ), "PrefetchVirtualMemory" ); | |
156 | h->process_handle = GetCurrentProcess(); | |
156 | 157 | h->map_handle = CreateFileMappingW( osfhandle, NULL, PAGE_READONLY, 0, 0, NULL ); |
157 | 158 | return !h->map_handle; |
158 | 159 | } |
172 | 173 | size += align; |
173 | 174 | #ifdef _WIN32 |
174 | 175 | uint8_t *base = MapViewOfFile( h->map_handle, FILE_MAP_READ, offset >> 32, offset, size ); |
175 | /* TODO: Would PrefetchVirtualMemory() (only available on Win8+) be beneficial? */ | |
176 | 176 | if( base ) |
177 | { | |
178 | /* PrefetchVirtualMemory() is only available on Windows 8 and newer. */ | |
179 | if( h->prefetch_virtual_memory ) | |
180 | { | |
181 | struct { void *addr; size_t size; } mem_range = { base, size }; | |
182 | h->prefetch_virtual_memory( h->process_handle, 1, &mem_range, 0 ); | |
183 | } | |
177 | 184 | return base + align; |
185 | } | |
178 | 186 | #else |
179 | 187 | uint8_t *base = mmap( NULL, size, PROT_READ, MAP_PRIVATE, h->fd, offset ); |
180 | 188 | if( base != MAP_FAILED ) |
28 | 28 | #define X264_INPUT_H |
29 | 29 | |
30 | 30 | #include "x264cli.h" |
31 | ||
32 | #ifdef _WIN32 | |
33 | #include <windows.h> | |
34 | #endif | |
31 | 35 | |
32 | 36 | /* options that are used by only some demuxers */ |
33 | 37 | typedef struct |
134 | 138 | { |
135 | 139 | int align_mask; |
136 | 140 | #ifdef _WIN32 |
137 | void *map_handle; | |
141 | BOOL (WINAPI *prefetch_virtual_memory)( HANDLE, ULONG_PTR, PVOID, ULONG ); | |
142 | HANDLE process_handle; | |
143 | HANDLE map_handle; | |
138 | 144 | #elif HAVE_MMAP |
139 | 145 | int fd; |
140 | 146 | #endif |
167 | 167 | if( opt->format ) |
168 | 168 | FAIL_IF_ERROR( !(format = av_find_input_format( opt->format )), "unknown file format: %s\n", opt->format ); |
169 | 169 | |
170 | FAIL_IF_ERROR( avformat_open_input( &h->lavf, psz_filename, format, &options ), "could not open input file\n" ) | |
170 | FAIL_IF_ERROR( avformat_open_input( &h->lavf, psz_filename, format, &options ), "could not open input file\n" ); | |
171 | 171 | if( options ) |
172 | 172 | av_dict_free( &options ); |
173 | FAIL_IF_ERROR( avformat_find_stream_info( h->lavf, NULL ) < 0, "could not find input stream info\n" ) | |
173 | FAIL_IF_ERROR( avformat_find_stream_info( h->lavf, NULL ) < 0, "could not find input stream info\n" ); | |
174 | 174 | |
175 | 175 | int i = 0; |
176 | 176 | while( i < h->lavf->nb_streams && h->lavf->streams[i]->codec->codec_type != AVMEDIA_TYPE_VIDEO ) |
177 | 177 | i++; |
178 | FAIL_IF_ERROR( i == h->lavf->nb_streams, "could not find video stream\n" ) | |
178 | FAIL_IF_ERROR( i == h->lavf->nb_streams, "could not find video stream\n" ); | |
179 | 179 | h->stream_id = i; |
180 | 180 | h->next_frame = 0; |
181 | 181 | AVCodecContext *c = h->lavf->streams[i]->codec; |
187 | 187 | info->thread_safe = 0; |
188 | 188 | h->vfr_input = info->vfr; |
189 | 189 | FAIL_IF_ERROR( avcodec_open2( c, avcodec_find_decoder( c->codec_id ), NULL ), |
190 | "could not find decoder for video stream\n" ) | |
190 | "could not find decoder for video stream\n" ); | |
191 | 191 | |
192 | 192 | /* prefetch the first frame and set/confirm flags */ |
193 | 193 | h->first_pic = malloc( sizeof(cli_pic_t) ); |
194 | 194 | FAIL_IF_ERROR( !h->first_pic || lavf_input.picture_alloc( h->first_pic, h, X264_CSP_OTHER, info->width, info->height ), |
195 | "malloc failed\n" ) | |
196 | else if( read_frame_internal( h->first_pic, h, 0, info ) ) | |
195 | "malloc failed\n" ); | |
196 | if( read_frame_internal( h->first_pic, h, 0, info ) ) | |
197 | 197 | return -1; |
198 | 198 | |
199 | 199 | info->width = c->width; |
53 | 53 | } |
54 | 54 | else |
55 | 55 | sscanf( opt->resolution, "%dx%d", &info->width, &info->height ); |
56 | FAIL_IF_ERROR( !info->width || !info->height, "raw input requires a resolution.\n" ) | |
56 | FAIL_IF_ERROR( !info->width || !info->height, "raw input requires a resolution.\n" ); | |
57 | 57 | if( opt->colorspace ) |
58 | 58 | { |
59 | 59 | for( info->csp = X264_CSP_CLI_MAX-1; info->csp > X264_CSP_NONE; info->csp-- ) |
48 | 48 | { |
49 | 49 | thread_hnd_t *h = malloc( sizeof(thread_hnd_t) ); |
50 | 50 | FAIL_IF_ERR( !h || cli_input.picture_alloc( &h->pic, *p_handle, info->csp, info->width, info->height ), |
51 | "x264", "malloc failed\n" ) | |
51 | "x264", "malloc failed\n" ); | |
52 | 52 | h->input = cli_input; |
53 | 53 | h->p_handle = *p_handle; |
54 | 54 | h->next_frame = -1; |
60 | 60 | fps_den = i * h->timebase_num; |
61 | 61 | fps_num = round( fps_den * fps_sig ) * exponent; |
62 | 62 | FAIL_IF_ERROR( fps_num > UINT32_MAX, "tcfile fps correction failed.\n" |
63 | " Specify an appropriate timebase manually or remake tcfile.\n" ) | |
63 | " Specify an appropriate timebase manually or remake tcfile.\n" ); | |
64 | 64 | if( fabs( ((double)fps_num / fps_den) / exponent - fps_sig ) < DOUBLE_EPSILON ) |
65 | 65 | break; |
66 | 66 | ++i; |
86 | 86 | fps_den = round( MKV_TIMEBASE_DEN / fps_sig ) / exponent; |
87 | 87 | h->timebase_num = fps_den && h->timebase_num ? gcd( h->timebase_num, fps_den ) : fps_den; |
88 | 88 | FAIL_IF_ERROR( h->timebase_num > UINT32_MAX || !h->timebase_num, "automatic timebase generation failed.\n" |
89 | " Specify timebase manually.\n" ) | |
89 | " Specify timebase manually.\n" ); | |
90 | 90 | } |
91 | 91 | return 0; |
92 | 92 | } |
99 | 99 | double *fpss = NULL; |
100 | 100 | |
101 | 101 | ret = fscanf( tcfile_in, "# timecode format v%d", &tcfv ); |
102 | FAIL_IF_ERROR( ret != 1 || (tcfv != 1 && tcfv != 2), "unsupported timecode format\n" ) | |
102 | FAIL_IF_ERROR( ret != 1 || (tcfv != 1 && tcfv != 2), "unsupported timecode format\n" ); | |
103 | 103 | #define NO_TIMECODE_LINE (buff[0] == '#' || buff[0] == '\n' || buff[0] == '\r') |
104 | 104 | if( tcfv == 1 ) |
105 | 105 | { |
114 | 114 | if( NO_TIMECODE_LINE ) |
115 | 115 | continue; |
116 | 116 | FAIL_IF_ERROR( sscanf( buff, "assume %lf", &h->assume_fps ) != 1 && sscanf( buff, "Assume %lf", &h->assume_fps ) != 1, |
117 | "tcfile parsing error: assumed fps not found\n" ) | |
117 | "tcfile parsing error: assumed fps not found\n" ); | |
118 | 118 | break; |
119 | 119 | } |
120 | FAIL_IF_ERROR( h->assume_fps <= 0, "invalid assumed fps %.6f\n", h->assume_fps ) | |
120 | FAIL_IF_ERROR( h->assume_fps <= 0, "invalid assumed fps %.6f\n", h->assume_fps ); | |
121 | 121 | |
122 | 122 | file_pos = ftell( tcfile_in ); |
123 | 123 | h->stored_pts_num = 0; |
130 | 130 | continue; |
131 | 131 | } |
132 | 132 | ret = sscanf( buff, "%d,%d,%lf", &start, &end, &seq_fps ); |
133 | FAIL_IF_ERROR( ret != 3 && ret != EOF, "invalid input tcfile\n" ) | |
133 | FAIL_IF_ERROR( ret != 3 && ret != EOF, "invalid input tcfile\n" ); | |
134 | 134 | FAIL_IF_ERROR( start > end || start <= prev_start || end <= prev_end || seq_fps <= 0, |
135 | "invalid input tcfile at line %d: %s\n", num, buff ) | |
135 | "invalid input tcfile at line %d: %s\n", num, buff ); | |
136 | 136 | prev_start = start; |
137 | 137 | prev_end = end; |
138 | 138 | if( h->auto_timebase_den || h->auto_timebase_num ) |
233 | 233 | h->stored_pts_num++; |
234 | 234 | } |
235 | 235 | timecodes_num = h->stored_pts_num; |
236 | FAIL_IF_ERROR( !timecodes_num, "input tcfile doesn't have any timecodes!\n" ) | |
236 | FAIL_IF_ERROR( !timecodes_num, "input tcfile doesn't have any timecodes!\n" ); | |
237 | 237 | fseek( tcfile_in, file_pos, SEEK_SET ); |
238 | 238 | |
239 | 239 | timecodes = malloc( timecodes_num * sizeof(double) ); |
245 | 245 | { |
246 | 246 | ret = sscanf( buff, "%lf", &timecodes[0] ); |
247 | 247 | timecodes[0] *= 1e-3; /* Timecode format v2 is expressed in milliseconds. */ |
248 | FAIL_IF_ERROR( ret != 1, "invalid input tcfile for frame 0\n" ) | |
248 | FAIL_IF_ERROR( ret != 1, "invalid input tcfile for frame 0\n" ); | |
249 | 249 | for( num = 1; num < timecodes_num && fgets( buff, sizeof(buff), tcfile_in ) != NULL; ) |
250 | 250 | { |
251 | 251 | if( NO_TIMECODE_LINE ) |
253 | 253 | ret = sscanf( buff, "%lf", &timecodes[num] ); |
254 | 254 | timecodes[num] *= 1e-3; /* Timecode format v2 is expressed in milliseconds. */ |
255 | 255 | FAIL_IF_ERROR( ret != 1 || timecodes[num] <= timecodes[num - 1], |
256 | "invalid input tcfile for frame %d\n", num ) | |
256 | "invalid input tcfile for frame %d\n", num ); | |
257 | 257 | ++num; |
258 | 258 | } |
259 | 259 | } |
260 | FAIL_IF_ERROR( num < timecodes_num, "failed to read input tcfile for frame %d", num ) | |
260 | FAIL_IF_ERROR( num < timecodes_num, "failed to read input tcfile for frame %d", num ); | |
261 | 261 | |
262 | 262 | if( timecodes_num == 1 ) |
263 | 263 | h->timebase_den = info->fps_num; |
313 | 313 | x264_cli_log( "timecode", X264_LOG_INFO, "automatic timebase generation %"PRIu64"/%"PRIu64"\n", h->timebase_num, h->timebase_den ); |
314 | 314 | } |
315 | 315 | else FAIL_IF_ERROR( h->timebase_den > UINT32_MAX || !h->timebase_den, "automatic timebase generation failed.\n" |
316 | " Specify an appropriate timebase manually.\n" ) | |
316 | " Specify an appropriate timebase manually.\n" ); | |
317 | 317 | |
318 | 318 | h->pts = malloc( h->stored_pts_num * sizeof(int64_t) ); |
319 | 319 | if( !h->pts ) |
321 | 321 | for( num = 0; num < h->stored_pts_num; num++ ) |
322 | 322 | { |
323 | 323 | h->pts[num] = timecodes[num] * ((double)h->timebase_den / h->timebase_num) + 0.5; |
324 | FAIL_IF_ERROR( num > 0 && h->pts[num] <= h->pts[num - 1], "invalid timebase or timecode for frame %d\n", num ) | |
324 | FAIL_IF_ERROR( num > 0 && h->pts[num] <= h->pts[num - 1], "invalid timebase or timecode for frame %d\n", num ); | |
325 | 325 | } |
326 | 326 | |
327 | 327 | free( timecodes ); |
343 | 343 | int ret = 0; |
344 | 344 | FILE *tcfile_in; |
345 | 345 | timecode_hnd_t *h = malloc( sizeof(timecode_hnd_t) ); |
346 | FAIL_IF_ERROR( !h, "malloc failed\n" ) | |
346 | FAIL_IF_ERROR( !h, "malloc failed\n" ); | |
347 | 347 | h->input = cli_input; |
348 | 348 | h->p_handle = *p_handle; |
349 | 349 | h->pts = NULL; |
356 | 356 | h->timebase_den = 0; /* set later by auto timebase generation */ |
357 | 357 | } |
358 | 358 | FAIL_IF_ERROR( h->timebase_num > UINT32_MAX || h->timebase_den > UINT32_MAX, |
359 | "timebase you specified exceeds H.264 maximum\n" ) | |
359 | "timebase you specified exceeds H.264 maximum\n" ); | |
360 | 360 | } |
361 | 361 | h->auto_timebase_num = !ret; |
362 | 362 | h->auto_timebase_den = ret < 2; |
366 | 366 | h->timebase_den = 0; /* set later by auto timebase generation */ |
367 | 367 | |
368 | 368 | tcfile_in = x264_fopen( psz_filename, "rb" ); |
369 | FAIL_IF_ERROR( !tcfile_in, "can't open `%s'\n", psz_filename ) | |
370 | else if( !x264_is_regular_file( tcfile_in ) ) | |
369 | FAIL_IF_ERROR( !tcfile_in, "can't open `%s'\n", psz_filename ); | |
370 | if( !x264_is_regular_file( tcfile_in ) ) | |
371 | 371 | { |
372 | 372 | x264_cli_log( "timecode", X264_LOG_ERROR, "tcfile input incompatible with non-regular file `%s'\n", psz_filename ); |
373 | 373 | fclose( tcfile_in ); |
98 | 98 | break; |
99 | 99 | } |
100 | 100 | } |
101 | FAIL_IF_ERROR( strncmp( header, Y4M_MAGIC, sizeof(Y4M_MAGIC)-1 ), "bad sequence header magic\n" ) | |
102 | FAIL_IF_ERROR( i == MAX_YUV4_HEADER, "bad sequence header length\n" ) | |
101 | FAIL_IF_ERROR( strncmp( header, Y4M_MAGIC, sizeof(Y4M_MAGIC)-1 ), "bad sequence header magic\n" ); | |
102 | FAIL_IF_ERROR( i == MAX_YUV4_HEADER, "bad sequence header length\n" ); | |
103 | 103 | |
104 | 104 | /* Scan properties */ |
105 | 105 | header_end = &header[i+1]; /* Include space */ |
186 | 186 | h->bit_depth = 8; |
187 | 187 | } |
188 | 188 | |
189 | FAIL_IF_ERROR( colorspace <= X264_CSP_NONE || colorspace >= X264_CSP_MAX, "colorspace unhandled\n" ) | |
189 | FAIL_IF_ERROR( colorspace <= X264_CSP_NONE || colorspace >= X264_CSP_MAX, "colorspace unhandled\n" ); | |
190 | 190 | FAIL_IF_ERROR( h->bit_depth < 8 || h->bit_depth > 16, "unsupported bit depth `%d'\n", h->bit_depth ); |
191 | 191 | |
192 | 192 | info->thread_safe = 1; |
214 | 214 | int len = 1; |
215 | 215 | while( len <= MAX_FRAME_HEADER && fgetc( h->fh ) != '\n' ) |
216 | 216 | len++; |
217 | FAIL_IF_ERROR( len > MAX_FRAME_HEADER || len < sizeof(Y4M_FRAME_MAGIC), "bad frame header length\n" ) | |
217 | FAIL_IF_ERROR( len > MAX_FRAME_HEADER || len < sizeof(Y4M_FRAME_MAGIC), "bad frame header length\n" ); | |
218 | 218 | h->frame_header_len = len; |
219 | 219 | h->frame_size += len; |
220 | 220 | |
251 | 251 | * produces y4m files with variable-length frame headers so just error out if that happens. */ |
252 | 252 | while( i <= h->frame_header_len && header[i-1] != '\n' ) |
253 | 253 | i++; |
254 | FAIL_IF_ERROR( i != h->frame_header_len, "bad frame header length\n" ) | |
254 | FAIL_IF_ERROR( i != h->frame_header_len, "bad frame header length\n" ); | |
255 | 255 | } |
256 | 256 | else |
257 | 257 | { |
260 | 260 | return -1; |
261 | 261 | while( i <= MAX_FRAME_HEADER && fgetc( h->fh ) != '\n' ) |
262 | 262 | i++; |
263 | FAIL_IF_ERROR( i > MAX_FRAME_HEADER, "bad frame header length\n" ) | |
264 | } | |
265 | FAIL_IF_ERROR( memcmp( header, Y4M_FRAME_MAGIC, slen ), "bad frame header magic\n" ) | |
263 | FAIL_IF_ERROR( i > MAX_FRAME_HEADER, "bad frame header length\n" ); | |
264 | } | |
265 | FAIL_IF_ERROR( memcmp( header, Y4M_FRAME_MAGIC, slen ), "bad frame header magic\n" ); | |
266 | 266 | |
267 | 267 | for( i = 0; i < pic->img.planes; i++ ) |
268 | 268 | { |
244 | 244 | { |
245 | 245 | CHECK( mk_write_id( c, id ) ); |
246 | 246 | CHECK( mk_write_size( c, size ) ); |
247 | CHECK( mk_append_context_data( c, data, size ) ) ; | |
247 | CHECK( mk_append_context_data( c, data, size ) ); | |
248 | 248 | return 0; |
249 | 249 | } |
250 | 250 |
170 | 170 | return -1; |
171 | 171 | int b_regular = x264_is_regular_file( fh ); |
172 | 172 | fclose( fh ); |
173 | FAIL_IF_ERR( !b_regular, "mp4", "MP4 output is incompatible with non-regular file `%s'\n", psz_filename ) | |
173 | FAIL_IF_ERR( !b_regular, "mp4", "MP4 output is incompatible with non-regular file `%s'\n", psz_filename ); | |
174 | 174 | |
175 | 175 | mp4_hnd_t *p_mp4 = calloc( 1, sizeof(mp4_hnd_t) ); |
176 | 176 | if( !p_mp4 ) |
179 | 179 | #ifdef _WIN32 |
180 | 180 | /* GPAC doesn't support Unicode filenames. */ |
181 | 181 | char ansi_filename[MAX_PATH]; |
182 | FAIL_IF_ERR( !x264_ansi_filename( psz_filename, ansi_filename, MAX_PATH, 1 ), "mp4", "invalid ansi filename\n" ) | |
182 | FAIL_IF_ERR( !x264_ansi_filename( psz_filename, ansi_filename, MAX_PATH, 1 ), "mp4", "invalid ansi filename\n" ); | |
183 | 183 | p_mp4->p_file = gf_isom_open( ansi_filename, GF_ISOM_OPEN_WRITE, NULL ); |
184 | 184 | #else |
185 | 185 | p_mp4->p_file = gf_isom_open( psz_filename, GF_ISOM_OPEN_WRITE, NULL ); |
209 | 209 | |
210 | 210 | p_mp4->i_time_res = (uint64_t)p_param->i_timebase_den * p_mp4->i_dts_compress_multiplier; |
211 | 211 | p_mp4->i_time_inc = (uint64_t)p_param->i_timebase_num * p_mp4->i_dts_compress_multiplier; |
212 | FAIL_IF_ERR( p_mp4->i_time_res > UINT32_MAX, "mp4", "MP4 media timescale %"PRIu64" exceeds maximum\n", p_mp4->i_time_res ) | |
212 | FAIL_IF_ERR( p_mp4->i_time_res > UINT32_MAX, "mp4", "MP4 media timescale %"PRIu64" exceeds maximum\n", p_mp4->i_time_res ); | |
213 | 213 | |
214 | 214 | p_mp4->i_track = gf_isom_new_track( p_mp4->p_file, 0, GF_ISOM_MEDIA_VISUAL, |
215 | 215 | p_mp4->i_time_res ); |
229 | 229 | uint64_t dh = p_param->i_height << 16; |
230 | 230 | double sar = (double)p_param->vui.i_sar_width / p_param->vui.i_sar_height; |
231 | 231 | if( sar > 1.0 ) |
232 | dw *= sar ; | |
232 | dw *= sar; | |
233 | 233 | else |
234 | 234 | dh /= sar; |
235 | 235 | gf_isom_set_pixel_aspect_ratio( p_mp4->p_file, p_mp4->i_track, p_mp4->i_descidx, p_param->vui.i_sar_width, p_param->vui.i_sar_height ); |
40 | 40 | |
41 | 41 | /* For close_file() */ |
42 | 42 | #define MP4_LOG_IF_ERR( cond, ... )\ |
43 | if( cond )\ | |
43 | do\ | |
44 | 44 | {\ |
45 | MP4_LOG_ERROR( __VA_ARGS__ );\ | |
46 | } | |
45 | if( cond )\ | |
46 | {\ | |
47 | MP4_LOG_ERROR( __VA_ARGS__ );\ | |
48 | }\ | |
49 | } while( 0 ) | |
47 | 50 | |
48 | 51 | /* For open_file() */ |
49 | 52 | #define MP4_FAIL_IF_ERR_EX( cond, ... )\ |
50 | if( cond )\ | |
53 | do\ | |
51 | 54 | {\ |
52 | remove_mp4_hnd( p_mp4 );\ | |
53 | MP4_LOG_ERROR( __VA_ARGS__ );\ | |
54 | return -1;\ | |
55 | } | |
55 | if( cond )\ | |
56 | {\ | |
57 | remove_mp4_hnd( p_mp4 );\ | |
58 | MP4_LOG_ERROR( __VA_ARGS__ );\ | |
59 | return -1;\ | |
60 | }\ | |
61 | } while( 0 ) | |
56 | 62 | |
57 | 63 | /*******************/ |
58 | 64 |
55 | 55 | // max number of args used by any x264 asm function. |
56 | 56 | #define MAX_ARGS 15 |
57 | 57 | |
58 | #define ARG_STACK ((8*(MAX_ARGS - 6) + 15) & ~15) | |
58 | #define ARG_STACK ((8*(MAX_ARGS - 8) + 15) & ~15) | |
59 | 59 | |
60 | 60 | function x264_checkasm_call, export=1 |
61 | 61 | stp x29, x30, [sp, #-16]! |
86 | 86 | sub sp, sp, #ARG_STACK |
87 | 87 | .equ pos, 0 |
88 | 88 | // first two stacked args are copied to x6, x7 |
89 | .rept MAX_ARGS-6 | |
89 | .rept MAX_ARGS-8 | |
90 | 90 | ldr x9, [x29, #16 + 16 + pos] |
91 | 91 | str x9, [sp, #pos] |
92 | 92 | .equ pos, pos + 8 |
44 | 44 | @ max number of args used by any x264 asm function. |
45 | 45 | #define MAX_ARGS 15 |
46 | 46 | |
47 | #define ARG_STACK 4*(MAX_ARGS - 2) | |
47 | #define ARG_STACK 4*(MAX_ARGS - 4) | |
48 | ||
49 | @ align the used stack space to 8 to preserve the stack alignment | |
50 | #define ARG_STACK_A (((ARG_STACK + pushed + 7) & ~7) - pushed) | |
48 | 51 | |
49 | 52 | .macro clobbercheck variant |
50 | 53 | .equ pushed, 4*10 |
63 | 66 | |
64 | 67 | push {r1} |
65 | 68 | |
66 | sub sp, sp, #ARG_STACK | |
69 | sub sp, sp, #ARG_STACK_A | |
67 | 70 | .equ pos, 0 |
68 | .rept MAX_ARGS-2 | |
69 | ldr r12, [sp, #ARG_STACK + pushed + 8 + pos] | |
71 | .rept MAX_ARGS-4 | |
72 | ldr r12, [sp, #ARG_STACK_A + pushed + 8 + pos] | |
70 | 73 | str r12, [sp, #pos] |
71 | 74 | .equ pos, pos + 4 |
72 | 75 | .endr |
74 | 77 | mov r12, r0 |
75 | 78 | mov r0, r2 |
76 | 79 | mov r1, r3 |
77 | ldrd r2, r3, [sp, #ARG_STACK + pushed] | |
80 | ldrd r2, r3, [sp, #ARG_STACK_A + pushed] | |
78 | 81 | blx r12 |
79 | add sp, sp, #ARG_STACK | |
82 | add sp, sp, #ARG_STACK_A | |
80 | 83 | pop {r2} |
81 | 84 | |
82 | 85 | push {r0, r1} |
1024 | 1024 | x264_zigzag_function_t zigzag_ref[2]; |
1025 | 1025 | x264_zigzag_function_t zigzag_asm[2]; |
1026 | 1026 | |
1027 | ALIGNED_16( dctcoef level1[64] ); | |
1028 | ALIGNED_16( dctcoef level2[64] ); | |
1027 | ALIGNED_ARRAY_16( dctcoef, level1,[64] ); | |
1028 | ALIGNED_ARRAY_16( dctcoef, level2,[64] ); | |
1029 | 1029 | |
1030 | 1030 | #define TEST_ZIGZAG_SCAN( name, t1, t2, dct, size ) \ |
1031 | 1031 | if( zigzag_asm[interlace].name != zigzag_ref[interlace].name ) \ |
2200 | 2200 | int dmf = h->dequant4_mf[CQM_4IC][qpdc%6][0] << qpdc/6; \ |
2201 | 2201 | if( dmf > 32*64 ) \ |
2202 | 2202 | continue; \ |
2203 | for( int i = 16; ; i <<= 1 ) \ | |
2203 | for( int i = 16;; i <<= 1 ) \ | |
2204 | 2204 | { \ |
2205 | 2205 | int res_c, res_asm; \ |
2206 | 2206 | int max = X264_MIN( i, PIXEL_MAX*16 ); \ |
0 | 0 | #!/bin/sh |
1 | 1 | # Script modified from upstream source for Debian packaging since packaging |
2 | 2 | # won't include .git repository. |
3 | echo '#define X264_VERSION " r2708 86b7198"' | |
4 | echo '#define X264_POINTVER "0.148.2708 86b7198"' | |
3 | echo '#define X264_VERSION " r2728 4d5c8b0"' | |
4 | echo '#define X264_POINTVER "0.148.2728 4d5c8b0"' |
354 | 354 | cli_opt_t opt = {0}; |
355 | 355 | int ret = 0; |
356 | 356 | |
357 | FAIL_IF_ERROR( x264_threading_init(), "unable to initialize threading\n" ) | |
357 | FAIL_IF_ERROR( x264_threading_init(), "unable to initialize threading\n" ); | |
358 | 358 | |
359 | 359 | #ifdef _WIN32 |
360 | FAIL_IF_ERROR( !get_argv_utf8( &argc, &argv ), "unable to convert command line to UTF-8\n" ) | |
360 | FAIL_IF_ERROR( !get_argv_utf8( &argc, &argv ), "unable to convert command line to UTF-8\n" ); | |
361 | 361 | |
362 | 362 | GetConsoleTitleW( org_console_title, CONSOLE_TITLE_SIZE ); |
363 | 363 | _setmode( _fileno( stdin ), _O_BINARY ); |
602 | 602 | " - medium:\n" |
603 | 603 | " Default settings apply.\n" |
604 | 604 | " - slow:\n" |
605 | " --b-adapt 2 --direct auto --me umh\n" | |
606 | " --rc-lookahead 50 --ref 5 --subme 8\n" | |
605 | " --direct auto --rc-lookahead 50 --ref 5\n" | |
606 | " --subme 8 --trellis 2\n" | |
607 | 607 | " - slower:\n" |
608 | 608 | " --b-adapt 2 --direct auto --me umh\n" |
609 | 609 | " --partitions all --rc-lookahead 60\n" |
1255 | 1255 | cli_input = raw_input; |
1256 | 1256 | } |
1257 | 1257 | |
1258 | FAIL_IF_ERROR( !(*p_handle), "could not open input file `%s' via any method!\n", filename ) | |
1258 | FAIL_IF_ERROR( !(*p_handle), "could not open input file `%s' via any method!\n", filename ); | |
1259 | 1259 | } |
1260 | 1260 | strcpy( used_demuxer, module ); |
1261 | 1261 | |
1431 | 1431 | output_filename = optarg; |
1432 | 1432 | break; |
1433 | 1433 | case OPT_MUXER: |
1434 | FAIL_IF_ERROR( parse_enum_name( optarg, muxer_names, &muxer ), "Unknown muxer `%s'\n", optarg ) | |
1434 | FAIL_IF_ERROR( parse_enum_name( optarg, muxer_names, &muxer ), "Unknown muxer `%s'\n", optarg ); | |
1435 | 1435 | break; |
1436 | 1436 | case OPT_DEMUXER: |
1437 | FAIL_IF_ERROR( parse_enum_name( optarg, demuxer_names, &demuxer ), "Unknown demuxer `%s'\n", optarg ) | |
1437 | FAIL_IF_ERROR( parse_enum_name( optarg, demuxer_names, &demuxer ), "Unknown demuxer `%s'\n", optarg ); | |
1438 | 1438 | break; |
1439 | 1439 | case OPT_INDEX: |
1440 | 1440 | input_opt.index_file = optarg; |
1441 | 1441 | break; |
1442 | 1442 | case OPT_QPFILE: |
1443 | 1443 | opt->qpfile = x264_fopen( optarg, "rb" ); |
1444 | FAIL_IF_ERROR( !opt->qpfile, "can't open qpfile `%s'\n", optarg ) | |
1444 | FAIL_IF_ERROR( !opt->qpfile, "can't open qpfile `%s'\n", optarg ); | |
1445 | 1445 | if( !x264_is_regular_file( opt->qpfile ) ) |
1446 | 1446 | { |
1447 | 1447 | x264_cli_log( "x264", X264_LOG_ERROR, "qpfile incompatible with non-regular file `%s'\n", optarg ); |
1492 | 1492 | break; |
1493 | 1493 | case OPT_TCFILE_OUT: |
1494 | 1494 | opt->tcfile_out = x264_fopen( optarg, "wb" ); |
1495 | FAIL_IF_ERROR( !opt->tcfile_out, "can't open `%s'\n", optarg ) | |
1495 | FAIL_IF_ERROR( !opt->tcfile_out, "can't open `%s'\n", optarg ); | |
1496 | 1496 | break; |
1497 | 1497 | case OPT_TIMEBASE: |
1498 | 1498 | input_opt.timebase = optarg; |
1499 | 1499 | break; |
1500 | 1500 | case OPT_PULLDOWN: |
1501 | FAIL_IF_ERROR( parse_enum_value( optarg, pulldown_names, &opt->i_pulldown ), "Unknown pulldown `%s'\n", optarg ) | |
1501 | FAIL_IF_ERROR( parse_enum_value( optarg, pulldown_names, &opt->i_pulldown ), "Unknown pulldown `%s'\n", optarg ); | |
1502 | 1502 | break; |
1503 | 1503 | case OPT_VIDEO_FILTER: |
1504 | 1504 | vid_filters = optarg; |
1519 | 1519 | output_opt.use_dts_compress = 1; |
1520 | 1520 | break; |
1521 | 1521 | case OPT_OUTPUT_CSP: |
1522 | FAIL_IF_ERROR( parse_enum_value( optarg, output_csp_names, &output_csp ), "Unknown output csp `%s'\n", optarg ) | |
1522 | FAIL_IF_ERROR( parse_enum_value( optarg, output_csp_names, &output_csp ), "Unknown output csp `%s'\n", optarg ); | |
1523 | 1523 | // correct the parsed value to the libx264 csp value |
1524 | 1524 | #if X264_CHROMA_FORMAT |
1525 | 1525 | static const uint8_t output_csp_fix[] = { X264_CHROMA_FORMAT, X264_CSP_RGB }; |
1529 | 1529 | param->i_csp = output_csp = output_csp_fix[output_csp]; |
1530 | 1530 | break; |
1531 | 1531 | case OPT_INPUT_RANGE: |
1532 | FAIL_IF_ERROR( parse_enum_value( optarg, range_names, &input_opt.input_range ), "Unknown input range `%s'\n", optarg ) | |
1532 | FAIL_IF_ERROR( parse_enum_value( optarg, range_names, &input_opt.input_range ), "Unknown input range `%s'\n", optarg ); | |
1533 | 1533 | input_opt.input_range += RANGE_AUTO; |
1534 | 1534 | break; |
1535 | 1535 | case OPT_RANGE: |
1576 | 1576 | |
1577 | 1577 | /* Get the file name */ |
1578 | 1578 | FAIL_IF_ERROR( optind > argc - 1 || !output_filename, "No %s file. Run x264 --help for a list of options.\n", |
1579 | optind > argc - 1 ? "input" : "output" ) | |
1579 | optind > argc - 1 ? "input" : "output" ); | |
1580 | 1580 | |
1581 | 1581 | if( select_output( muxer, output_filename, param ) ) |
1582 | 1582 | return -1; |
1583 | FAIL_IF_ERROR( cli_output.open_file( output_filename, &opt->hout, &output_opt ), "could not open output file `%s'\n", output_filename ) | |
1583 | FAIL_IF_ERROR( cli_output.open_file( output_filename, &opt->hout, &output_opt ), "could not open output file `%s'\n", output_filename ); | |
1584 | 1584 | |
1585 | 1585 | input_filename = argv[optind++]; |
1586 | 1586 | video_info_t info = {0}; |
1608 | 1608 | return -1; |
1609 | 1609 | |
1610 | 1610 | FAIL_IF_ERROR( !opt->hin && cli_input.open_file( input_filename, &opt->hin, &info, &input_opt ), |
1611 | "could not open input file `%s'\n", input_filename ) | |
1611 | "could not open input file `%s'\n", input_filename ); | |
1612 | 1612 | |
1613 | 1613 | x264_reduce_fraction( &info.sar_width, &info.sar_height ); |
1614 | 1614 | x264_reduce_fraction( &info.fps_num, &info.fps_den ); |
1618 | 1618 | |
1619 | 1619 | if( tcfile_name ) |
1620 | 1620 | { |
1621 | FAIL_IF_ERROR( b_user_fps, "--fps + --tcfile-in is incompatible.\n" ) | |
1622 | FAIL_IF_ERROR( timecode_input.open_file( tcfile_name, &opt->hin, &info, &input_opt ), "timecode input failed\n" ) | |
1621 | FAIL_IF_ERROR( b_user_fps, "--fps + --tcfile-in is incompatible.\n" ); | |
1622 | FAIL_IF_ERROR( timecode_input.open_file( tcfile_name, &opt->hin, &info, &input_opt ), "timecode input failed\n" ); | |
1623 | 1623 | cli_input = timecode_input; |
1624 | 1624 | } |
1625 | else FAIL_IF_ERROR( !info.vfr && input_opt.timebase, "--timebase is incompatible with cfr input\n" ) | |
1625 | else FAIL_IF_ERROR( !info.vfr && input_opt.timebase, "--timebase is incompatible with cfr input\n" ); | |
1626 | 1626 | |
1627 | 1627 | /* init threaded input while the information about the input video is unaltered by filtering */ |
1628 | 1628 | #if HAVE_THREAD |
1659 | 1659 | uint64_t i_user_timebase_num; |
1660 | 1660 | uint64_t i_user_timebase_den; |
1661 | 1661 | int ret = sscanf( input_opt.timebase, "%"SCNu64"/%"SCNu64, &i_user_timebase_num, &i_user_timebase_den ); |
1662 | FAIL_IF_ERROR( !ret, "invalid argument: timebase = %s\n", input_opt.timebase ) | |
1663 | else if( ret == 1 ) | |
1662 | FAIL_IF_ERROR( !ret, "invalid argument: timebase = %s\n", input_opt.timebase ); | |
1663 | if( ret == 1 ) | |
1664 | 1664 | { |
1665 | 1665 | i_user_timebase_num = info.timebase_num; |
1666 | 1666 | i_user_timebase_den = strtoul( input_opt.timebase, NULL, 10 ); |
1667 | 1667 | } |
1668 | 1668 | FAIL_IF_ERROR( i_user_timebase_num > UINT32_MAX || i_user_timebase_den > UINT32_MAX, |
1669 | "timebase you specified exceeds H.264 maximum\n" ) | |
1669 | "timebase you specified exceeds H.264 maximum\n" ); | |
1670 | 1670 | opt->timebase_convert_multiplier = ((double)i_user_timebase_den / info.timebase_den) |
1671 | 1671 | * ((double)info.timebase_num / i_user_timebase_num); |
1672 | 1672 | info.timebase_num = i_user_timebase_num; |
1718 | 1718 | if( input_opt.output_range == RANGE_AUTO ) |
1719 | 1719 | param->vui.b_fullrange = RANGE_PC; |
1720 | 1720 | /* otherwise fail if they specified tv */ |
1721 | FAIL_IF_ERROR( !param->vui.b_fullrange, "RGB must be PC range" ) | |
1721 | FAIL_IF_ERROR( !param->vui.b_fullrange, "RGB must be PC range" ); | |
1722 | 1722 | } |
1723 | 1723 | |
1724 | 1724 | /* Automatically reduce reference frame count to match the user's target level |
1839 | 1839 | } |
1840 | 1840 | |
1841 | 1841 | #define FAIL_IF_ERROR2( cond, ... )\ |
1842 | if( cond )\ | |
1842 | do\ | |
1843 | 1843 | {\ |
1844 | x264_cli_log( "x264", X264_LOG_ERROR, __VA_ARGS__ );\ | |
1845 | retval = -1;\ | |
1846 | goto fail;\ | |
1847 | } | |
1844 | if( cond )\ | |
1845 | {\ | |
1846 | x264_cli_log( "x264", X264_LOG_ERROR, __VA_ARGS__ );\ | |
1847 | retval = -1;\ | |
1848 | goto fail;\ | |
1849 | }\ | |
1850 | } while( 0 ) | |
1848 | 1851 | |
1849 | 1852 | static int encode( x264_param_t *param, cli_opt_t *opt ) |
1850 | 1853 | { |
1880 | 1883 | pulldown = &pulldown_values[opt->i_pulldown]; |
1881 | 1884 | param->i_timebase_num = param->i_fps_den; |
1882 | 1885 | FAIL_IF_ERROR2( fmod( param->i_fps_num * pulldown->fps_factor, 1 ), |
1883 | "unsupported framerate for chosen pulldown\n" ) | |
1886 | "unsupported framerate for chosen pulldown\n" ); | |
1884 | 1887 | param->i_timebase_den = param->i_fps_num * pulldown->fps_factor; |
1885 | 1888 | } |
1886 | 1889 | |
1895 | 1898 | |
1896 | 1899 | /* ticks/frame = ticks/second / frames/second */ |
1897 | 1900 | ticks_per_frame = (int64_t)param->i_timebase_den * param->i_fps_den / param->i_timebase_num / param->i_fps_num; |
1898 | FAIL_IF_ERROR2( ticks_per_frame < 1 && !param->b_vfr_input, "ticks_per_frame invalid: %"PRId64"\n", ticks_per_frame ) | |
1901 | FAIL_IF_ERROR2( ticks_per_frame < 1 && !param->b_vfr_input, "ticks_per_frame invalid: %"PRId64"\n", ticks_per_frame ); | |
1899 | 1902 | ticks_per_frame = X264_MAX( ticks_per_frame, 1 ); |
1900 | 1903 | |
1901 | 1904 | if( !param->b_repeat_headers ) |
1904 | 1907 | x264_nal_t *headers; |
1905 | 1908 | int i_nal; |
1906 | 1909 | |
1907 | FAIL_IF_ERROR2( x264_encoder_headers( h, &headers, &i_nal ) < 0, "x264_encoder_headers failed\n" ) | |
1910 | FAIL_IF_ERROR2( x264_encoder_headers( h, &headers, &i_nal ) < 0, "x264_encoder_headers failed\n" ); | |
1908 | 1911 | FAIL_IF_ERROR2( (i_file = cli_output.write_headers( opt->hout, headers )) < 0, "error writing headers to output file\n" ); |
1909 | 1912 | } |
1910 | 1913 |
70 | 70 | #endif |
71 | 71 | |
72 | 72 | #define RETURN_IF_ERR( cond, name, ret, ... )\ |
73 | if( cond )\ | |
73 | do\ | |
74 | 74 | {\ |
75 | x264_cli_log( name, X264_LOG_ERROR, __VA_ARGS__ );\ | |
76 | return ret;\ | |
77 | } | |
75 | if( cond )\ | |
76 | {\ | |
77 | x264_cli_log( name, X264_LOG_ERROR, __VA_ARGS__ );\ | |
78 | return ret;\ | |
79 | }\ | |
80 | } while( 0 ) | |
78 | 81 | |
79 | 82 | #define FAIL_IF_ERR( cond, name, ... ) RETURN_IF_ERR( cond, name, -1, __VA_ARGS__ ) |
80 | 83 |