Line | Count | Source |
1 | | /***************************************************************************** |
2 | | * frame.c: frame handling |
3 | | ***************************************************************************** |
4 | | * Copyright (C) 2003-2025 x264 project |
5 | | * |
6 | | * Authors: Laurent Aimar <fenrir@via.ecp.fr> |
7 | | * Loren Merritt <lorenm@u.washington.edu> |
8 | | * Fiona Glaser <fiona@x264.com> |
9 | | * |
10 | | * This program is free software; you can redistribute it and/or modify |
11 | | * it under the terms of the GNU General Public License as published by |
12 | | * the Free Software Foundation; either version 2 of the License, or |
13 | | * (at your option) any later version. |
14 | | * |
15 | | * This program is distributed in the hope that it will be useful, |
16 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 | | * GNU General Public License for more details. |
19 | | * |
20 | | * You should have received a copy of the GNU General Public License |
21 | | * along with this program; if not, write to the Free Software |
22 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. |
23 | | * |
24 | | * This program is also available under a commercial proprietary license. |
25 | | * For more information, contact us at licensing@x264.com. |
26 | | *****************************************************************************/ |
27 | | |
28 | | #include "common.h" |
29 | | |
30 | | static int align_stride( int x, int align, int disalign ) |
31 | 0 | { |
32 | 0 | x = ALIGN( x, align ); |
33 | 0 | if( !(x&(disalign-1)) ) |
34 | 0 | x += align; |
35 | 0 | return x; |
36 | 0 | } |
37 | | |
38 | | static int align_plane_size( int x, int disalign ) |
39 | 0 | { |
40 | 0 | if( !(x&(disalign-1)) ) |
41 | 0 | x += X264_MAX( 128, NATIVE_ALIGN ) / SIZEOF_PIXEL; |
42 | 0 | return x; |
43 | 0 | } |
44 | | |
45 | | static int frame_internal_csp( int external_csp ) |
46 | 0 | { |
47 | 0 | int csp = external_csp & X264_CSP_MASK; |
48 | 0 | if( csp == X264_CSP_I400 ) |
49 | 0 | return X264_CSP_I400; |
50 | 0 | if( csp >= X264_CSP_I420 && csp < X264_CSP_I422 ) |
51 | 0 | return X264_CSP_NV12; |
52 | 0 | if( csp >= X264_CSP_I422 && csp < X264_CSP_I444 ) |
53 | 0 | return X264_CSP_NV16; |
54 | 0 | if( csp >= X264_CSP_I444 && csp <= X264_CSP_RGB ) |
55 | 0 | return X264_CSP_I444; |
56 | 0 | return X264_CSP_NONE; |
57 | 0 | } |
58 | | |
59 | | static x264_frame_t *frame_new( x264_t *h, int b_fdec ) |
60 | 0 | { |
61 | 0 | x264_frame_t *frame; |
62 | 0 | int i_csp = frame_internal_csp( h->param.i_csp ); |
63 | 0 | int i_mb_count = h->mb.i_mb_count; |
64 | 0 | int i_stride, i_width, i_lines, luma_plane_count; |
65 | 0 | int i_padv = PADV << PARAM_INTERLACED; |
66 | 0 | int align = NATIVE_ALIGN / SIZEOF_PIXEL; |
67 | 0 | #if ARCH_X86 || ARCH_X86_64 |
68 | 0 | if( h->param.cpu&X264_CPU_CACHELINE_64 || h->param.cpu&X264_CPU_AVX512 ) |
69 | 0 | align = 64 / SIZEOF_PIXEL; |
70 | 0 | else if( h->param.cpu&X264_CPU_CACHELINE_32 || h->param.cpu&X264_CPU_AVX ) |
71 | 0 | align = 32 / SIZEOF_PIXEL; |
72 | 0 | else |
73 | 0 | align = 16 / SIZEOF_PIXEL; |
74 | 0 | #endif |
75 | | #if ARCH_PPC |
76 | | int disalign = (1<<9) / SIZEOF_PIXEL; |
77 | | #else |
78 | 0 | int disalign = (1<<10) / SIZEOF_PIXEL; |
79 | 0 | #endif |
80 | |
|
81 | 0 | CHECKED_MALLOCZERO( frame, sizeof(x264_frame_t) ); |
82 | 0 | PREALLOC_INIT |
83 | | |
84 | | /* allocate frame data (+64 for extra data for me) */ |
85 | 0 | i_width = h->mb.i_mb_width*16; |
86 | 0 | i_lines = h->mb.i_mb_height*16; |
87 | 0 | i_stride = align_stride( i_width + PADH2, align, disalign ); |
88 | |
|
89 | 0 | if( i_csp == X264_CSP_NV12 || i_csp == X264_CSP_NV16 ) |
90 | 0 | { |
91 | 0 | luma_plane_count = 1; |
92 | 0 | frame->i_plane = 2; |
93 | 0 | for( int i = 0; i < 2; i++ ) |
94 | 0 | { |
95 | 0 | frame->i_width[i] = i_width >> i; |
96 | 0 | frame->i_lines[i] = i_lines >> (i && i_csp == X264_CSP_NV12); |
97 | 0 | frame->i_stride[i] = i_stride; |
98 | 0 | } |
99 | 0 | } |
100 | 0 | else if( i_csp == X264_CSP_I444 ) |
101 | 0 | { |
102 | 0 | luma_plane_count = 3; |
103 | 0 | frame->i_plane = 3; |
104 | 0 | for( int i = 0; i < 3; i++ ) |
105 | 0 | { |
106 | 0 | frame->i_width[i] = i_width; |
107 | 0 | frame->i_lines[i] = i_lines; |
108 | 0 | frame->i_stride[i] = i_stride; |
109 | 0 | } |
110 | 0 | } |
111 | 0 | else if( i_csp == X264_CSP_I400 ) |
112 | 0 | { |
113 | 0 | luma_plane_count = 1; |
114 | 0 | frame->i_plane = 1; |
115 | 0 | frame->i_width[0] = i_width; |
116 | 0 | frame->i_lines[0] = i_lines; |
117 | 0 | frame->i_stride[0] = i_stride; |
118 | 0 | } |
119 | 0 | else |
120 | 0 | goto fail; |
121 | | |
122 | 0 | frame->i_csp = i_csp; |
123 | 0 | frame->i_width_lowres = frame->i_width[0]/2; |
124 | 0 | frame->i_lines_lowres = frame->i_lines[0]/2; |
125 | 0 | frame->i_stride_lowres = align_stride( frame->i_width_lowres + PADH2, align, disalign<<1 ); |
126 | |
|
127 | 0 | for( int i = 0; i < h->param.i_bframe + 2; i++ ) |
128 | 0 | for( int j = 0; j < h->param.i_bframe + 2; j++ ) |
129 | 0 | PREALLOC( frame->i_row_satds[i][j], i_lines/16 * sizeof(int) ); |
130 | |
|
131 | 0 | frame->i_poc = -1; |
132 | 0 | frame->i_type = X264_TYPE_AUTO; |
133 | 0 | frame->i_qpplus1 = X264_QP_AUTO; |
134 | 0 | frame->i_pts = -1; |
135 | 0 | frame->i_frame = -1; |
136 | 0 | frame->i_frame_num = -1; |
137 | 0 | frame->i_lines_completed = -1; |
138 | 0 | frame->b_fdec = b_fdec; |
139 | 0 | frame->i_pic_struct = PIC_STRUCT_AUTO; |
140 | 0 | frame->i_field_cnt = -1; |
141 | 0 | frame->i_duration = |
142 | 0 | frame->i_cpb_duration = |
143 | 0 | frame->i_dpb_output_delay = |
144 | 0 | frame->i_cpb_delay = 0; |
145 | 0 | frame->i_coded_fields_lookahead = |
146 | 0 | frame->i_cpb_delay_lookahead = -1; |
147 | |
|
148 | 0 | frame->orig = frame; |
149 | |
|
150 | 0 | if( i_csp == X264_CSP_NV12 || i_csp == X264_CSP_NV16 ) |
151 | 0 | { |
152 | 0 | int chroma_padv = i_padv >> (i_csp == X264_CSP_NV12); |
153 | 0 | int chroma_plane_size = (frame->i_stride[1] * (frame->i_lines[1] + 2*chroma_padv)); |
154 | 0 | PREALLOC( frame->buffer[1], chroma_plane_size * SIZEOF_PIXEL ); |
155 | 0 | if( PARAM_INTERLACED ) |
156 | 0 | PREALLOC( frame->buffer_fld[1], chroma_plane_size * SIZEOF_PIXEL ); |
157 | 0 | } |
158 | | |
159 | | /* all 4 luma planes allocated together, since the cacheline split code |
160 | | * requires them to be in-phase wrt cacheline alignment. */ |
161 | |
|
162 | 0 | for( int p = 0; p < luma_plane_count; p++ ) |
163 | 0 | { |
164 | 0 | int64_t luma_plane_size = align_plane_size( frame->i_stride[p] * (frame->i_lines[p] + 2*i_padv), disalign ); |
165 | 0 | if( h->param.analyse.i_subpel_refine && b_fdec ) |
166 | 0 | luma_plane_size *= 4; |
167 | | |
168 | | /* FIXME: Don't allocate both buffers in non-adaptive MBAFF. */ |
169 | 0 | PREALLOC( frame->buffer[p], luma_plane_size * SIZEOF_PIXEL ); |
170 | 0 | if( PARAM_INTERLACED ) |
171 | 0 | PREALLOC( frame->buffer_fld[p], luma_plane_size * SIZEOF_PIXEL ); |
172 | 0 | } |
173 | |
|
174 | 0 | frame->b_duplicate = 0; |
175 | |
|
176 | 0 | if( b_fdec ) /* fdec frame */ |
177 | 0 | { |
178 | 0 | PREALLOC( frame->mb_type, i_mb_count * sizeof(int8_t) ); |
179 | 0 | PREALLOC( frame->mb_partition, i_mb_count * sizeof(uint8_t) ); |
180 | 0 | PREALLOC( frame->mv[0], 2*16 * i_mb_count * sizeof(int16_t) ); |
181 | 0 | PREALLOC( frame->mv16x16, 2*(i_mb_count+1) * sizeof(int16_t) ); |
182 | 0 | PREALLOC( frame->ref[0], 4 * i_mb_count * sizeof(int8_t) ); |
183 | 0 | if( h->param.i_bframe ) |
184 | 0 | { |
185 | 0 | PREALLOC( frame->mv[1], 2*16 * i_mb_count * sizeof(int16_t) ); |
186 | 0 | PREALLOC( frame->ref[1], 4 * i_mb_count * sizeof(int8_t) ); |
187 | 0 | } |
188 | 0 | else |
189 | 0 | { |
190 | 0 | frame->mv[1] = NULL; |
191 | 0 | frame->ref[1] = NULL; |
192 | 0 | } |
193 | 0 | PREALLOC( frame->i_row_bits, i_lines/16 * sizeof(int) ); |
194 | 0 | PREALLOC( frame->f_row_qp, i_lines/16 * sizeof(float) ); |
195 | 0 | PREALLOC( frame->f_row_qscale, i_lines/16 * sizeof(float) ); |
196 | 0 | if( h->param.analyse.i_me_method >= X264_ME_ESA ) |
197 | 0 | PREALLOC( frame->buffer[3], frame->i_stride[0] * (frame->i_lines[0] + 2*i_padv) * sizeof(uint16_t) << h->frames.b_have_sub8x8_esa ); |
198 | 0 | if( PARAM_INTERLACED ) |
199 | 0 | PREALLOC( frame->field, i_mb_count * sizeof(uint8_t) ); |
200 | 0 | if( h->param.analyse.b_mb_info ) |
201 | 0 | PREALLOC( frame->effective_qp, i_mb_count * sizeof(uint8_t) ); |
202 | 0 | } |
203 | 0 | else /* fenc frame */ |
204 | 0 | { |
205 | 0 | if( h->frames.b_have_lowres ) |
206 | 0 | { |
207 | 0 | int64_t luma_plane_size = align_plane_size( frame->i_stride_lowres * (frame->i_lines[0]/2 + 2*PADV), disalign ); |
208 | |
|
209 | 0 | PREALLOC( frame->buffer_lowres, 4 * luma_plane_size * SIZEOF_PIXEL ); |
210 | |
|
211 | 0 | for( int j = 0; j <= !!h->param.i_bframe; j++ ) |
212 | 0 | for( int i = 0; i <= h->param.i_bframe; i++ ) |
213 | 0 | { |
214 | 0 | PREALLOC( frame->lowres_mvs[j][i], 2*i_mb_count*sizeof(int16_t) ); |
215 | 0 | PREALLOC( frame->lowres_mv_costs[j][i], i_mb_count*sizeof(int) ); |
216 | 0 | } |
217 | 0 | PREALLOC( frame->i_propagate_cost, i_mb_count * sizeof(uint16_t) ); |
218 | 0 | for( int j = 0; j <= h->param.i_bframe+1; j++ ) |
219 | 0 | for( int i = 0; i <= h->param.i_bframe+1; i++ ) |
220 | 0 | PREALLOC( frame->lowres_costs[j][i], i_mb_count * sizeof(uint16_t) ); |
221 | 0 | } |
222 | 0 | if( h->param.rc.i_aq_mode ) |
223 | 0 | { |
224 | 0 | PREALLOC( frame->f_qp_offset, i_mb_count * sizeof(float) ); |
225 | 0 | PREALLOC( frame->f_qp_offset_aq, i_mb_count * sizeof(float) ); |
226 | 0 | if( h->frames.b_have_lowres ) |
227 | 0 | PREALLOC( frame->i_inv_qscale_factor, i_mb_count * sizeof(uint16_t) ); |
228 | 0 | } |
229 | | |
230 | | /* mbtree asm can overread the input buffers, make sure we don't read outside of allocated memory. */ |
231 | 0 | if( h->frames.b_have_lowres ) |
232 | 0 | prealloc_size += NATIVE_ALIGN; |
233 | 0 | } |
234 | |
|
235 | 0 | PREALLOC_END( frame->base ); |
236 | | |
237 | 0 | if( i_csp == X264_CSP_NV12 || i_csp == X264_CSP_NV16 ) |
238 | 0 | { |
239 | 0 | int chroma_padv = i_padv >> (i_csp == X264_CSP_NV12); |
240 | 0 | frame->plane[1] = frame->buffer[1] + frame->i_stride[1] * chroma_padv + PADH_ALIGN; |
241 | 0 | if( PARAM_INTERLACED ) |
242 | 0 | frame->plane_fld[1] = frame->buffer_fld[1] + frame->i_stride[1] * chroma_padv + PADH_ALIGN; |
243 | 0 | } |
244 | |
|
245 | 0 | for( int p = 0; p < luma_plane_count; p++ ) |
246 | 0 | { |
247 | 0 | int64_t luma_plane_size = align_plane_size( frame->i_stride[p] * (frame->i_lines[p] + 2*i_padv), disalign ); |
248 | 0 | if( h->param.analyse.i_subpel_refine && b_fdec ) |
249 | 0 | { |
250 | 0 | for( int i = 0; i < 4; i++ ) |
251 | 0 | { |
252 | 0 | frame->filtered[p][i] = frame->buffer[p] + i*luma_plane_size + frame->i_stride[p] * i_padv + PADH_ALIGN; |
253 | 0 | if( PARAM_INTERLACED ) |
254 | 0 | frame->filtered_fld[p][i] = frame->buffer_fld[p] + i*luma_plane_size + frame->i_stride[p] * i_padv + PADH_ALIGN; |
255 | 0 | } |
256 | 0 | frame->plane[p] = frame->filtered[p][0]; |
257 | 0 | frame->plane_fld[p] = frame->filtered_fld[p][0]; |
258 | 0 | } |
259 | 0 | else |
260 | 0 | { |
261 | 0 | frame->filtered[p][0] = frame->plane[p] = frame->buffer[p] + frame->i_stride[p] * i_padv + PADH_ALIGN; |
262 | 0 | if( PARAM_INTERLACED ) |
263 | 0 | frame->filtered_fld[p][0] = frame->plane_fld[p] = frame->buffer_fld[p] + frame->i_stride[p] * i_padv + PADH_ALIGN; |
264 | 0 | } |
265 | 0 | } |
266 | |
|
267 | 0 | if( b_fdec ) |
268 | 0 | { |
269 | 0 | M32( frame->mv16x16[0] ) = 0; |
270 | 0 | frame->mv16x16++; |
271 | |
|
272 | 0 | if( h->param.analyse.i_me_method >= X264_ME_ESA ) |
273 | 0 | frame->integral = (uint16_t*)frame->buffer[3] + frame->i_stride[0] * i_padv + PADH_ALIGN; |
274 | 0 | } |
275 | 0 | else |
276 | 0 | { |
277 | 0 | if( h->frames.b_have_lowres ) |
278 | 0 | { |
279 | 0 | int64_t luma_plane_size = align_plane_size( frame->i_stride_lowres * (frame->i_lines[0]/2 + 2*PADV), disalign ); |
280 | 0 | for( int i = 0; i < 4; i++ ) |
281 | 0 | frame->lowres[i] = frame->buffer_lowres + frame->i_stride_lowres * PADV + PADH_ALIGN + i * luma_plane_size; |
282 | |
|
283 | 0 | for( int j = 0; j <= !!h->param.i_bframe; j++ ) |
284 | 0 | for( int i = 0; i <= h->param.i_bframe; i++ ) |
285 | 0 | memset( frame->lowres_mvs[j][i], 0, 2*i_mb_count*sizeof(int16_t) ); |
286 | |
|
287 | 0 | frame->i_intra_cost = frame->lowres_costs[0][0]; |
288 | 0 | memset( frame->i_intra_cost, -1, i_mb_count * sizeof(uint16_t) ); |
289 | |
|
290 | 0 | if( h->param.rc.i_aq_mode ) |
291 | | /* shouldn't really be initialized, just silences a valgrind false-positive in x264_mbtree_propagate_cost_sse2 */ |
292 | 0 | memset( frame->i_inv_qscale_factor, 0, i_mb_count * sizeof(uint16_t) ); |
293 | 0 | } |
294 | 0 | } |
295 | |
|
296 | 0 | if( x264_pthread_mutex_init( &frame->mutex, NULL ) ) |
297 | 0 | goto fail; |
298 | 0 | if( x264_pthread_cond_init( &frame->cv, NULL ) ) |
299 | 0 | goto fail; |
300 | | |
301 | | #if HAVE_OPENCL |
302 | | frame->opencl.ocl = h->opencl.ocl; |
303 | | #endif |
304 | | |
305 | 0 | return frame; |
306 | | |
307 | 0 | fail: |
308 | 0 | x264_free( frame ); |
309 | 0 | return NULL; |
310 | 0 | } |
311 | | |
312 | | void x264_frame_delete( x264_frame_t *frame ) |
313 | 0 | { |
314 | | /* Duplicate frames are blank copies of real frames (including pointers), |
315 | | * so freeing those pointers would cause a double free later. */ |
316 | 0 | if( !frame->b_duplicate ) |
317 | 0 | { |
318 | 0 | x264_free( frame->base ); |
319 | |
|
320 | 0 | if( frame->param && frame->param->param_free ) |
321 | 0 | { |
322 | 0 | x264_param_cleanup( frame->param ); |
323 | 0 | frame->param->param_free( frame->param ); |
324 | 0 | } |
325 | 0 | if( frame->mb_info_free ) |
326 | 0 | frame->mb_info_free( frame->mb_info ); |
327 | 0 | if( frame->extra_sei.sei_free ) |
328 | 0 | { |
329 | 0 | for( int i = 0; i < frame->extra_sei.num_payloads; i++ ) |
330 | 0 | frame->extra_sei.sei_free( frame->extra_sei.payloads[i].payload ); |
331 | 0 | frame->extra_sei.sei_free( frame->extra_sei.payloads ); |
332 | 0 | } |
333 | 0 | x264_pthread_mutex_destroy( &frame->mutex ); |
334 | 0 | x264_pthread_cond_destroy( &frame->cv ); |
335 | | #if HAVE_OPENCL |
336 | | x264_opencl_frame_delete( frame ); |
337 | | #endif |
338 | 0 | } |
339 | 0 | x264_free( frame ); |
340 | 0 | } Unexecuted instantiation: x264_8_frame_delete Unexecuted instantiation: x264_10_frame_delete |
341 | | |
342 | | static int get_plane_ptr( x264_t *h, x264_picture_t *src, uint8_t **pix, int *stride, int plane, int xshift, int yshift ) |
343 | 0 | { |
344 | 0 | int width = h->param.i_width >> xshift; |
345 | 0 | int height = h->param.i_height >> yshift; |
346 | 0 | *pix = src->img.plane[plane]; |
347 | 0 | *stride = src->img.i_stride[plane]; |
348 | 0 | if( src->img.i_csp & X264_CSP_VFLIP ) |
349 | 0 | { |
350 | 0 | *pix += (height-1) * *stride; |
351 | 0 | *stride = -*stride; |
352 | 0 | } |
353 | 0 | if( width > abs(*stride) ) |
354 | 0 | { |
355 | 0 | x264_log( h, X264_LOG_ERROR, "Input picture width (%d) is greater than stride (%d)\n", width, *stride ); |
356 | 0 | return -1; |
357 | 0 | } |
358 | 0 | return 0; |
359 | 0 | } |
360 | | |
361 | 0 | #define get_plane_ptr(...) do { if( get_plane_ptr(__VA_ARGS__) < 0 ) return -1; } while( 0 ) |
362 | | |
363 | | int x264_frame_copy_picture( x264_t *h, x264_frame_t *dst, x264_picture_t *src ) |
364 | 0 | { |
365 | 0 | int i_csp = src->img.i_csp & X264_CSP_MASK; |
366 | 0 | if( dst->i_csp != frame_internal_csp( i_csp ) ) |
367 | 0 | { |
368 | 0 | x264_log( h, X264_LOG_ERROR, "Invalid input colorspace\n" ); |
369 | 0 | return -1; |
370 | 0 | } |
371 | | |
372 | | #if HIGH_BIT_DEPTH |
373 | 0 | if( !(src->img.i_csp & X264_CSP_HIGH_DEPTH) ) |
374 | 0 | { |
375 | 0 | x264_log( h, X264_LOG_ERROR, "This build of x264 requires high depth input. Rebuild to support 8-bit input.\n" ); |
376 | 0 | return -1; |
377 | 0 | } |
378 | | #else |
379 | 0 | if( src->img.i_csp & X264_CSP_HIGH_DEPTH ) |
380 | 0 | { |
381 | 0 | x264_log( h, X264_LOG_ERROR, "This build of x264 requires 8-bit input. Rebuild to support high depth input.\n" ); |
382 | 0 | return -1; |
383 | 0 | } |
384 | 0 | #endif |
385 | | |
386 | 0 | if( BIT_DEPTH != 10 && i_csp == X264_CSP_V210 ) |
387 | 0 | { |
388 | 0 | x264_log( h, X264_LOG_ERROR, "v210 input is only compatible with bit-depth of 10 bits\n" ); |
389 | 0 | return -1; |
390 | 0 | } |
391 | | |
392 | 0 | if( src->i_type < X264_TYPE_AUTO || src->i_type > X264_TYPE_KEYFRAME ) |
393 | 0 | { |
394 | 0 | x264_log( h, X264_LOG_WARNING, "forced frame type (%d) at %d is unknown\n", src->i_type, h->frames.i_input ); |
395 | 0 | dst->i_forced_type = X264_TYPE_AUTO; |
396 | 0 | } |
397 | 0 | else |
398 | 0 | dst->i_forced_type = src->i_type; |
399 | |
|
400 | 0 | dst->i_type = dst->i_forced_type; |
401 | 0 | dst->i_qpplus1 = src->i_qpplus1; |
402 | 0 | dst->i_pts = dst->i_reordered_pts = src->i_pts; |
403 | 0 | dst->param = src->param; |
404 | 0 | dst->i_pic_struct = src->i_pic_struct; |
405 | 0 | dst->extra_sei = src->extra_sei; |
406 | 0 | dst->opaque = src->opaque; |
407 | 0 | dst->mb_info = h->param.analyse.b_mb_info ? src->prop.mb_info : NULL; |
408 | 0 | dst->mb_info_free = h->param.analyse.b_mb_info ? src->prop.mb_info_free : NULL; |
409 | |
|
410 | 0 | uint8_t *pix[3]; |
411 | 0 | int stride[3]; |
412 | 0 | if( i_csp == X264_CSP_YUYV || i_csp == X264_CSP_UYVY ) |
413 | 0 | { |
414 | 0 | int p = i_csp == X264_CSP_UYVY; |
415 | 0 | h->mc.plane_copy_deinterleave_yuyv( dst->plane[p], dst->i_stride[p], dst->plane[p^1], dst->i_stride[p^1], |
416 | 0 | (pixel*)src->img.plane[0], src->img.i_stride[0]/SIZEOF_PIXEL, h->param.i_width, h->param.i_height ); |
417 | 0 | } |
418 | 0 | else if( i_csp == X264_CSP_V210 ) |
419 | 0 | { |
420 | 0 | stride[0] = src->img.i_stride[0]; |
421 | 0 | pix[0] = src->img.plane[0]; |
422 | |
|
423 | 0 | h->mc.plane_copy_deinterleave_v210( dst->plane[0], dst->i_stride[0], |
424 | 0 | dst->plane[1], dst->i_stride[1], |
425 | 0 | (uint32_t *)pix[0], stride[0]/(int)sizeof(uint32_t), h->param.i_width, h->param.i_height ); |
426 | 0 | } |
427 | 0 | else if( i_csp >= X264_CSP_BGR ) |
428 | 0 | { |
429 | 0 | stride[0] = src->img.i_stride[0]; |
430 | 0 | pix[0] = src->img.plane[0]; |
431 | 0 | if( src->img.i_csp & X264_CSP_VFLIP ) |
432 | 0 | { |
433 | 0 | pix[0] += (h->param.i_height-1) * stride[0]; |
434 | 0 | stride[0] = -stride[0]; |
435 | 0 | } |
436 | 0 | int b = i_csp==X264_CSP_RGB; |
437 | 0 | h->mc.plane_copy_deinterleave_rgb( dst->plane[1+b], dst->i_stride[1+b], |
438 | 0 | dst->plane[0], dst->i_stride[0], |
439 | 0 | dst->plane[2-b], dst->i_stride[2-b], |
440 | 0 | (pixel*)pix[0], stride[0]/SIZEOF_PIXEL, i_csp==X264_CSP_BGRA ? 4 : 3, h->param.i_width, h->param.i_height ); |
441 | 0 | } |
442 | 0 | else |
443 | 0 | { |
444 | 0 | int v_shift = CHROMA_V_SHIFT; |
445 | 0 | get_plane_ptr( h, src, &pix[0], &stride[0], 0, 0, 0 ); |
446 | 0 | h->mc.plane_copy( dst->plane[0], dst->i_stride[0], (pixel*)pix[0], |
447 | 0 | stride[0]/SIZEOF_PIXEL, h->param.i_width, h->param.i_height ); |
448 | 0 | if( i_csp == X264_CSP_NV12 || i_csp == X264_CSP_NV16 ) |
449 | 0 | { |
450 | 0 | get_plane_ptr( h, src, &pix[1], &stride[1], 1, 0, v_shift ); |
451 | 0 | h->mc.plane_copy( dst->plane[1], dst->i_stride[1], (pixel*)pix[1], |
452 | 0 | stride[1]/SIZEOF_PIXEL, h->param.i_width, h->param.i_height>>v_shift ); |
453 | 0 | } |
454 | 0 | else if( i_csp == X264_CSP_NV21 ) |
455 | 0 | { |
456 | 0 | get_plane_ptr( h, src, &pix[1], &stride[1], 1, 0, v_shift ); |
457 | 0 | h->mc.plane_copy_swap( dst->plane[1], dst->i_stride[1], (pixel*)pix[1], |
458 | 0 | stride[1]/SIZEOF_PIXEL, h->param.i_width>>1, h->param.i_height>>v_shift ); |
459 | 0 | } |
460 | 0 | else if( i_csp == X264_CSP_I420 || i_csp == X264_CSP_I422 || i_csp == X264_CSP_YV12 || i_csp == X264_CSP_YV16 ) |
461 | 0 | { |
462 | 0 | int uv_swap = i_csp == X264_CSP_YV12 || i_csp == X264_CSP_YV16; |
463 | 0 | get_plane_ptr( h, src, &pix[1], &stride[1], uv_swap ? 2 : 1, 1, v_shift ); |
464 | 0 | get_plane_ptr( h, src, &pix[2], &stride[2], uv_swap ? 1 : 2, 1, v_shift ); |
465 | 0 | h->mc.plane_copy_interleave( dst->plane[1], dst->i_stride[1], |
466 | 0 | (pixel*)pix[1], stride[1]/SIZEOF_PIXEL, |
467 | 0 | (pixel*)pix[2], stride[2]/SIZEOF_PIXEL, |
468 | 0 | h->param.i_width>>1, h->param.i_height>>v_shift ); |
469 | 0 | } |
470 | 0 | else if( i_csp == X264_CSP_I444 || i_csp == X264_CSP_YV24 ) |
471 | 0 | { |
472 | 0 | get_plane_ptr( h, src, &pix[1], &stride[1], i_csp==X264_CSP_I444 ? 1 : 2, 0, 0 ); |
473 | 0 | get_plane_ptr( h, src, &pix[2], &stride[2], i_csp==X264_CSP_I444 ? 2 : 1, 0, 0 ); |
474 | 0 | h->mc.plane_copy( dst->plane[1], dst->i_stride[1], (pixel*)pix[1], |
475 | 0 | stride[1]/SIZEOF_PIXEL, h->param.i_width, h->param.i_height ); |
476 | 0 | h->mc.plane_copy( dst->plane[2], dst->i_stride[2], (pixel*)pix[2], |
477 | 0 | stride[2]/SIZEOF_PIXEL, h->param.i_width, h->param.i_height ); |
478 | 0 | } |
479 | 0 | } |
480 | 0 | return 0; |
481 | 0 | } Unexecuted instantiation: x264_8_frame_copy_picture Unexecuted instantiation: x264_10_frame_copy_picture |
482 | | |
483 | | static ALWAYS_INLINE void pixel_memset( pixel *dst, pixel *src, int len, int size ) |
484 | 0 | { |
485 | 0 | uint8_t *dstp = (uint8_t*)dst; |
486 | 0 | uint32_t v1 = *src; |
487 | 0 | uint32_t v2 = size == 1 ? v1 + (v1 << 8) : M16( src ); |
488 | 0 | uint32_t v4 = size <= 2 ? v2 + (v2 << 16) : M32( src ); |
489 | 0 | int i = 0; |
490 | 0 | len *= size; |
491 | | |
492 | | /* Align the input pointer if it isn't already */ |
493 | 0 | if( (intptr_t)dstp & (WORD_SIZE - 1) ) |
494 | 0 | { |
495 | 0 | if( size <= 2 && ((intptr_t)dstp & 3) ) |
496 | 0 | { |
497 | 0 | if( size == 1 && ((intptr_t)dstp & 1) ) |
498 | 0 | dstp[i++] = v1; |
499 | 0 | if( (intptr_t)dstp & 2 ) |
500 | 0 | { |
501 | 0 | M16( dstp+i ) = v2; |
502 | 0 | i += 2; |
503 | 0 | } |
504 | 0 | } |
505 | 0 | if( WORD_SIZE == 8 && (intptr_t)dstp & 4 ) |
506 | 0 | { |
507 | 0 | M32( dstp+i ) = v4; |
508 | 0 | i += 4; |
509 | 0 | } |
510 | 0 | } |
511 | | |
512 | | /* Main copy loop */ |
513 | 0 | if( WORD_SIZE == 8 ) |
514 | 0 | { |
515 | 0 | uint64_t v8 = v4 + ((uint64_t)v4<<32); |
516 | 0 | for( ; i < len - 7; i+=8 ) |
517 | 0 | M64( dstp+i ) = v8; |
518 | 0 | } |
519 | 0 | for( ; i < len - 3; i+=4 ) |
520 | 0 | M32( dstp+i ) = v4; |
521 | | |
522 | | /* Finish up the last few bytes */ |
523 | 0 | if( size <= 2 ) |
524 | 0 | { |
525 | 0 | if( i < len - 1 ) |
526 | 0 | { |
527 | 0 | M16( dstp+i ) = v2; |
528 | 0 | i += 2; |
529 | 0 | } |
530 | 0 | if( size == 1 && i != len ) |
531 | 0 | dstp[i] = v1; |
532 | 0 | } |
533 | 0 | } |
534 | | |
535 | | static ALWAYS_INLINE void plane_expand_border( pixel *pix, int i_stride, int i_width, int i_height, int i_padh, int i_padv, int b_pad_top, int b_pad_bottom, int b_chroma ) |
536 | 0 | { |
537 | 0 | #define PPIXEL(x, y) ( pix + (x) + (y)*i_stride ) |
538 | 0 | for( int y = 0; y < i_height; y++ ) |
539 | 0 | { |
540 | | /* left band */ |
541 | 0 | pixel_memset( PPIXEL(-i_padh, y), PPIXEL(0, y), i_padh>>b_chroma, SIZEOF_PIXEL<<b_chroma ); |
542 | | /* right band */ |
543 | 0 | pixel_memset( PPIXEL(i_width, y), PPIXEL(i_width-1-b_chroma, y), i_padh>>b_chroma, SIZEOF_PIXEL<<b_chroma ); |
544 | 0 | } |
545 | | /* upper band */ |
546 | 0 | if( b_pad_top ) |
547 | 0 | for( int y = 0; y < i_padv; y++ ) |
548 | 0 | memcpy( PPIXEL(-i_padh, -y-1), PPIXEL(-i_padh, 0), (i_width+2*i_padh) * SIZEOF_PIXEL ); |
549 | | /* lower band */ |
550 | 0 | if( b_pad_bottom ) |
551 | 0 | for( int y = 0; y < i_padv; y++ ) |
552 | 0 | memcpy( PPIXEL(-i_padh, i_height+y), PPIXEL(-i_padh, i_height-1), (i_width+2*i_padh) * SIZEOF_PIXEL ); |
553 | 0 | #undef PPIXEL |
554 | 0 | } |
555 | | |
556 | | void x264_frame_expand_border( x264_t *h, x264_frame_t *frame, int mb_y ) |
557 | 0 | { |
558 | 0 | int pad_top = mb_y == 0; |
559 | 0 | int pad_bot = mb_y == h->mb.i_mb_height - (1 << SLICE_MBAFF); |
560 | 0 | int b_start = mb_y == h->i_threadslice_start; |
561 | 0 | int b_end = mb_y == h->i_threadslice_end - (1 << SLICE_MBAFF); |
562 | 0 | if( mb_y & SLICE_MBAFF ) |
563 | 0 | return; |
564 | 0 | for( int i = 0; i < frame->i_plane; i++ ) |
565 | 0 | { |
566 | 0 | int h_shift = i && CHROMA_H_SHIFT; |
567 | 0 | int v_shift = i && CHROMA_V_SHIFT; |
568 | 0 | int stride = frame->i_stride[i]; |
569 | 0 | int width = 16*h->mb.i_mb_width; |
570 | 0 | int height = (pad_bot ? 16*(h->mb.i_mb_height - mb_y) >> SLICE_MBAFF : 16) >> v_shift; |
571 | 0 | int padh = PADH; |
572 | 0 | int padv = PADV >> v_shift; |
573 | | // buffer: 2 chroma, 3 luma (rounded to 4) because deblocking goes beyond the top of the mb |
574 | 0 | if( b_end && !b_start ) |
575 | 0 | height += 4 >> (v_shift + SLICE_MBAFF); |
576 | 0 | pixel *pix; |
577 | 0 | int starty = 16*mb_y - 4*!b_start; |
578 | 0 | if( SLICE_MBAFF ) |
579 | 0 | { |
580 | | // border samples for each field are extended separately |
581 | 0 | pix = frame->plane_fld[i] + (starty*stride >> v_shift); |
582 | 0 | plane_expand_border( pix, stride*2, width, height, padh, padv, pad_top, pad_bot, h_shift ); |
583 | 0 | plane_expand_border( pix+stride, stride*2, width, height, padh, padv, pad_top, pad_bot, h_shift ); |
584 | |
|
585 | 0 | height = (pad_bot ? 16*(h->mb.i_mb_height - mb_y) : 32) >> v_shift; |
586 | 0 | if( b_end && !b_start ) |
587 | 0 | height += 4 >> v_shift; |
588 | 0 | pix = frame->plane[i] + (starty*stride >> v_shift); |
589 | 0 | plane_expand_border( pix, stride, width, height, padh, padv, pad_top, pad_bot, h_shift ); |
590 | 0 | } |
591 | 0 | else |
592 | 0 | { |
593 | 0 | pix = frame->plane[i] + (starty*stride >> v_shift); |
594 | 0 | plane_expand_border( pix, stride, width, height, padh, padv, pad_top, pad_bot, h_shift ); |
595 | 0 | } |
596 | 0 | } |
597 | 0 | } Unexecuted instantiation: x264_8_frame_expand_border Unexecuted instantiation: x264_10_frame_expand_border |
598 | | |
599 | | void x264_frame_expand_border_filtered( x264_t *h, x264_frame_t *frame, int mb_y, int b_end ) |
600 | 0 | { |
601 | | /* during filtering, 8 extra pixels were filtered on each edge, |
602 | | * but up to 3 of the horizontal ones may be wrong. |
603 | | we want to expand border from the last filtered pixel */ |
604 | 0 | int b_start = !mb_y; |
605 | 0 | int width = 16*h->mb.i_mb_width + 8; |
606 | 0 | int height = b_end ? (16*(h->mb.i_mb_height - mb_y) >> SLICE_MBAFF) + 16 : 16; |
607 | 0 | int padh = PADH - 4; |
608 | 0 | int padv = PADV - 8; |
609 | 0 | for( int p = 0; p < (CHROMA444 ? 3 : 1); p++ ) |
610 | 0 | for( int i = 1; i < 4; i++ ) |
611 | 0 | { |
612 | 0 | int stride = frame->i_stride[p]; |
613 | | // buffer: 8 luma, to match the hpel filter |
614 | 0 | pixel *pix; |
615 | 0 | if( SLICE_MBAFF ) |
616 | 0 | { |
617 | 0 | pix = frame->filtered_fld[p][i] + (16*mb_y - 16) * stride - 4; |
618 | 0 | plane_expand_border( pix, stride*2, width, height, padh, padv, b_start, b_end, 0 ); |
619 | 0 | plane_expand_border( pix+stride, stride*2, width, height, padh, padv, b_start, b_end, 0 ); |
620 | 0 | } |
621 | |
|
622 | 0 | pix = frame->filtered[p][i] + (16*mb_y - 8) * stride - 4; |
623 | 0 | plane_expand_border( pix, stride, width, height << SLICE_MBAFF, padh, padv, b_start, b_end, 0 ); |
624 | 0 | } |
625 | 0 | } Unexecuted instantiation: x264_8_frame_expand_border_filtered Unexecuted instantiation: x264_10_frame_expand_border_filtered |
626 | | |
627 | | void x264_frame_expand_border_lowres( x264_frame_t *frame ) |
628 | 0 | { |
629 | 0 | for( int i = 0; i < 4; i++ ) |
630 | 0 | plane_expand_border( frame->lowres[i], frame->i_stride_lowres, frame->i_width_lowres, frame->i_lines_lowres, PADH, PADV, 1, 1, 0 ); |
631 | 0 | } Unexecuted instantiation: x264_8_frame_expand_border_lowres Unexecuted instantiation: x264_10_frame_expand_border_lowres |
632 | | |
633 | | void x264_frame_expand_border_chroma( x264_t *h, x264_frame_t *frame, int plane ) |
634 | 0 | { |
635 | 0 | int v_shift = CHROMA_V_SHIFT; |
636 | 0 | plane_expand_border( frame->plane[plane], frame->i_stride[plane], 16*h->mb.i_mb_width, 16*h->mb.i_mb_height>>v_shift, |
637 | 0 | PADH, PADV>>v_shift, 1, 1, CHROMA_H_SHIFT ); |
638 | 0 | } Unexecuted instantiation: x264_8_frame_expand_border_chroma Unexecuted instantiation: x264_10_frame_expand_border_chroma |
639 | | |
640 | | void x264_frame_expand_border_mod16( x264_t *h, x264_frame_t *frame ) |
641 | 0 | { |
642 | 0 | for( int i = 0; i < frame->i_plane; i++ ) |
643 | 0 | { |
644 | 0 | int i_width = h->param.i_width; |
645 | 0 | int h_shift = i && CHROMA_H_SHIFT; |
646 | 0 | int v_shift = i && CHROMA_V_SHIFT; |
647 | 0 | int i_height = h->param.i_height >> v_shift; |
648 | 0 | int i_padx = (h->mb.i_mb_width * 16 - h->param.i_width); |
649 | 0 | int i_pady = (h->mb.i_mb_height * 16 - h->param.i_height) >> v_shift; |
650 | |
|
651 | 0 | if( i_padx ) |
652 | 0 | { |
653 | 0 | for( int y = 0; y < i_height; y++ ) |
654 | 0 | pixel_memset( &frame->plane[i][y*frame->i_stride[i] + i_width], |
655 | 0 | &frame->plane[i][y*frame->i_stride[i] + i_width - 1-h_shift], |
656 | 0 | i_padx>>h_shift, SIZEOF_PIXEL<<h_shift ); |
657 | 0 | } |
658 | 0 | if( i_pady ) |
659 | 0 | { |
660 | 0 | for( int y = i_height; y < i_height + i_pady; y++ ) |
661 | 0 | memcpy( &frame->plane[i][y*frame->i_stride[i]], |
662 | 0 | &frame->plane[i][(i_height-(~y&PARAM_INTERLACED)-1)*frame->i_stride[i]], |
663 | 0 | (i_width + i_padx) * SIZEOF_PIXEL ); |
664 | 0 | } |
665 | 0 | } |
666 | 0 | } Unexecuted instantiation: x264_8_frame_expand_border_mod16 Unexecuted instantiation: x264_10_frame_expand_border_mod16 |
667 | | |
668 | | void x264_expand_border_mbpair( x264_t *h, int mb_x, int mb_y ) |
669 | 0 | { |
670 | 0 | for( int i = 0; i < h->fenc->i_plane; i++ ) |
671 | 0 | { |
672 | 0 | int v_shift = i && CHROMA_V_SHIFT; |
673 | 0 | int stride = h->fenc->i_stride[i]; |
674 | 0 | int height = h->param.i_height >> v_shift; |
675 | 0 | int pady = (h->mb.i_mb_height * 16 - h->param.i_height) >> v_shift; |
676 | 0 | pixel *fenc = h->fenc->plane[i] + 16*mb_x; |
677 | 0 | for( int y = height; y < height + pady; y++ ) |
678 | 0 | memcpy( fenc + y*stride, fenc + (height-1)*stride, 16*SIZEOF_PIXEL ); |
679 | 0 | } |
680 | 0 | } Unexecuted instantiation: x264_8_expand_border_mbpair Unexecuted instantiation: x264_10_expand_border_mbpair |
681 | | |
682 | | /* threading */ |
683 | | void x264_frame_cond_broadcast( x264_frame_t *frame, int i_lines_completed ) |
684 | 0 | { |
685 | 0 | x264_pthread_mutex_lock( &frame->mutex ); |
686 | 0 | frame->i_lines_completed = i_lines_completed; |
687 | 0 | x264_pthread_cond_broadcast( &frame->cv ); |
688 | 0 | x264_pthread_mutex_unlock( &frame->mutex ); |
689 | 0 | } Unexecuted instantiation: x264_8_frame_cond_broadcast Unexecuted instantiation: x264_10_frame_cond_broadcast |
690 | | |
691 | | int x264_frame_cond_wait( x264_frame_t *frame, int i_lines_completed ) |
692 | 0 | { |
693 | 0 | int completed; |
694 | 0 | x264_pthread_mutex_lock( &frame->mutex ); |
695 | 0 | while( (completed = frame->i_lines_completed) < i_lines_completed && i_lines_completed >= 0 ) |
696 | 0 | x264_pthread_cond_wait( &frame->cv, &frame->mutex ); |
697 | 0 | x264_pthread_mutex_unlock( &frame->mutex ); |
698 | 0 | return completed; |
699 | 0 | } Unexecuted instantiation: x264_8_frame_cond_wait Unexecuted instantiation: x264_10_frame_cond_wait |
700 | | |
701 | | void x264_threadslice_cond_broadcast( x264_t *h, int pass ) |
702 | 0 | { |
703 | 0 | x264_pthread_mutex_lock( &h->mutex ); |
704 | 0 | h->i_threadslice_pass = pass; |
705 | 0 | if( pass > 0 ) |
706 | 0 | x264_pthread_cond_broadcast( &h->cv ); |
707 | 0 | x264_pthread_mutex_unlock( &h->mutex ); |
708 | 0 | } Unexecuted instantiation: x264_8_threadslice_cond_broadcast Unexecuted instantiation: x264_10_threadslice_cond_broadcast |
709 | | |
710 | | void x264_threadslice_cond_wait( x264_t *h, int pass ) |
711 | 0 | { |
712 | 0 | x264_pthread_mutex_lock( &h->mutex ); |
713 | 0 | while( h->i_threadslice_pass < pass ) |
714 | 0 | x264_pthread_cond_wait( &h->cv, &h->mutex ); |
715 | 0 | x264_pthread_mutex_unlock( &h->mutex ); |
716 | 0 | } Unexecuted instantiation: x264_8_threadslice_cond_wait Unexecuted instantiation: x264_10_threadslice_cond_wait |
717 | | |
718 | | int x264_frame_new_slice( x264_t *h, x264_frame_t *frame ) |
719 | 0 | { |
720 | 0 | if( h->param.i_slice_count_max ) |
721 | 0 | { |
722 | 0 | int slice_count; |
723 | 0 | if( h->param.b_sliced_threads ) |
724 | 0 | slice_count = x264_pthread_fetch_and_add( &frame->i_slice_count, 1, &frame->mutex ); |
725 | 0 | else |
726 | 0 | slice_count = frame->i_slice_count++; |
727 | 0 | if( slice_count >= h->param.i_slice_count_max ) |
728 | 0 | return -1; |
729 | 0 | } |
730 | 0 | return 0; |
731 | 0 | } Unexecuted instantiation: x264_8_frame_new_slice Unexecuted instantiation: x264_10_frame_new_slice |
732 | | |
733 | | /* list operators */ |
734 | | |
735 | | void x264_frame_push( x264_frame_t **list, x264_frame_t *frame ) |
736 | 0 | { |
737 | 0 | int i = 0; |
738 | 0 | while( list[i] ) i++; |
739 | 0 | list[i] = frame; |
740 | 0 | } Unexecuted instantiation: x264_8_frame_push Unexecuted instantiation: x264_10_frame_push |
741 | | |
742 | | x264_frame_t *x264_frame_pop( x264_frame_t **list ) |
743 | 0 | { |
744 | 0 | x264_frame_t *frame; |
745 | 0 | int i = 0; |
746 | 0 | assert( list[0] ); |
747 | 0 | while( list[i+1] ) i++; |
748 | 0 | frame = list[i]; |
749 | 0 | list[i] = NULL; |
750 | 0 | return frame; |
751 | 0 | } Unexecuted instantiation: x264_8_frame_pop Unexecuted instantiation: x264_10_frame_pop |
752 | | |
753 | | void x264_frame_unshift( x264_frame_t **list, x264_frame_t *frame ) |
754 | 0 | { |
755 | 0 | int i = 0; |
756 | 0 | while( list[i] ) i++; |
757 | 0 | while( i-- ) |
758 | 0 | list[i+1] = list[i]; |
759 | 0 | list[0] = frame; |
760 | 0 | } Unexecuted instantiation: x264_8_frame_unshift Unexecuted instantiation: x264_10_frame_unshift |
761 | | |
762 | | x264_frame_t *x264_frame_shift( x264_frame_t **list ) |
763 | 0 | { |
764 | 0 | x264_frame_t *frame = list[0]; |
765 | 0 | int i; |
766 | 0 | for( i = 0; list[i]; i++ ) |
767 | 0 | list[i] = list[i+1]; |
768 | 0 | assert(frame); |
769 | 0 | return frame; |
770 | 0 | } Unexecuted instantiation: x264_8_frame_shift Unexecuted instantiation: x264_10_frame_shift |
771 | | |
772 | | void x264_frame_push_unused( x264_t *h, x264_frame_t *frame ) |
773 | 0 | { |
774 | 0 | assert( frame->i_reference_count > 0 ); |
775 | 0 | frame->i_reference_count--; |
776 | 0 | if( frame->i_reference_count == 0 ) |
777 | 0 | x264_frame_push( h->frames.unused[frame->b_fdec], frame ); |
778 | 0 | } Unexecuted instantiation: x264_8_frame_push_unused Unexecuted instantiation: x264_10_frame_push_unused |
779 | | |
780 | | x264_frame_t *x264_frame_pop_unused( x264_t *h, int b_fdec ) |
781 | 0 | { |
782 | 0 | x264_frame_t *frame; |
783 | 0 | if( h->frames.unused[b_fdec][0] ) |
784 | 0 | frame = x264_frame_pop( h->frames.unused[b_fdec] ); |
785 | 0 | else |
786 | 0 | frame = frame_new( h, b_fdec ); |
787 | 0 | if( !frame ) |
788 | 0 | return NULL; |
789 | 0 | frame->b_last_minigop_bframe = 0; |
790 | 0 | frame->i_reference_count = 1; |
791 | 0 | frame->b_intra_calculated = 0; |
792 | 0 | frame->b_scenecut = 1; |
793 | 0 | frame->b_keyframe = 0; |
794 | 0 | frame->b_corrupt = 0; |
795 | 0 | frame->i_slice_count = h->param.b_sliced_threads ? h->param.i_threads : 1; |
796 | |
|
797 | 0 | memset( frame->weight, 0, sizeof(frame->weight) ); |
798 | 0 | memset( frame->f_weighted_cost_delta, 0, sizeof(frame->f_weighted_cost_delta) ); |
799 | |
|
800 | 0 | return frame; |
801 | 0 | } Unexecuted instantiation: x264_8_frame_pop_unused Unexecuted instantiation: x264_10_frame_pop_unused |
802 | | |
803 | | void x264_frame_push_blank_unused( x264_t *h, x264_frame_t *frame ) |
804 | 0 | { |
805 | 0 | assert( frame->i_reference_count > 0 ); |
806 | 0 | frame->i_reference_count--; |
807 | 0 | if( frame->i_reference_count == 0 ) |
808 | 0 | x264_frame_push( h->frames.blank_unused, frame ); |
809 | 0 | } Unexecuted instantiation: x264_8_frame_push_blank_unused Unexecuted instantiation: x264_10_frame_push_blank_unused |
810 | | |
811 | | x264_frame_t *x264_frame_pop_blank_unused( x264_t *h ) |
812 | 0 | { |
813 | 0 | x264_frame_t *frame; |
814 | 0 | if( h->frames.blank_unused[0] ) |
815 | 0 | frame = x264_frame_pop( h->frames.blank_unused ); |
816 | 0 | else |
817 | 0 | frame = x264_malloc( sizeof(x264_frame_t) ); |
818 | 0 | if( !frame ) |
819 | 0 | return NULL; |
820 | 0 | frame->b_duplicate = 1; |
821 | 0 | frame->i_reference_count = 1; |
822 | 0 | return frame; |
823 | 0 | } Unexecuted instantiation: x264_8_frame_pop_blank_unused Unexecuted instantiation: x264_10_frame_pop_blank_unused |
824 | | |
825 | | void x264_weight_scale_plane( x264_t *h, pixel *dst, intptr_t i_dst_stride, pixel *src, intptr_t i_src_stride, |
826 | | int i_width, int i_height, x264_weight_t *w ) |
827 | 0 | { |
828 | | /* Weight horizontal strips of height 16. This was found to be the optimal height |
829 | | * in terms of the cache loads. */ |
830 | 0 | while( i_height > 0 ) |
831 | 0 | { |
832 | 0 | int x; |
833 | 0 | for( x = 0; x < i_width-8; x += 16 ) |
834 | 0 | w->weightfn[16>>2]( dst+x, i_dst_stride, src+x, i_src_stride, w, X264_MIN( i_height, 16 ) ); |
835 | 0 | if( x < i_width ) |
836 | 0 | w->weightfn[ 8>>2]( dst+x, i_dst_stride, src+x, i_src_stride, w, X264_MIN( i_height, 16 ) ); |
837 | 0 | i_height -= 16; |
838 | 0 | dst += 16 * i_dst_stride; |
839 | 0 | src += 16 * i_src_stride; |
840 | 0 | } |
841 | 0 | } Unexecuted instantiation: x264_8_weight_scale_plane Unexecuted instantiation: x264_10_weight_scale_plane |
842 | | |
843 | | void x264_frame_delete_list( x264_frame_t **list ) |
844 | 0 | { |
845 | 0 | int i = 0; |
846 | 0 | if( !list ) |
847 | 0 | return; |
848 | 0 | while( list[i] ) |
849 | 0 | x264_frame_delete( list[i++] ); |
850 | 0 | x264_free( list ); |
851 | 0 | } Unexecuted instantiation: x264_8_frame_delete_list Unexecuted instantiation: x264_10_frame_delete_list |
852 | | |
853 | | int x264_sync_frame_list_init( x264_sync_frame_list_t *slist, int max_size ) |
854 | 0 | { |
855 | 0 | if( max_size < 0 ) |
856 | 0 | return -1; |
857 | 0 | slist->i_max_size = max_size; |
858 | 0 | slist->i_size = 0; |
859 | 0 | CHECKED_MALLOCZERO( slist->list, (max_size+1) * sizeof(x264_frame_t*) ); |
860 | 0 | if( x264_pthread_mutex_init( &slist->mutex, NULL ) || |
861 | 0 | x264_pthread_cond_init( &slist->cv_fill, NULL ) || |
862 | 0 | x264_pthread_cond_init( &slist->cv_empty, NULL ) ) |
863 | 0 | return -1; |
864 | 0 | return 0; |
865 | 0 | fail: |
866 | 0 | return -1; |
867 | 0 | } Unexecuted instantiation: x264_8_sync_frame_list_init Unexecuted instantiation: x264_10_sync_frame_list_init |
868 | | |
869 | | void x264_sync_frame_list_delete( x264_sync_frame_list_t *slist ) |
870 | 0 | { |
871 | 0 | x264_pthread_mutex_destroy( &slist->mutex ); |
872 | 0 | x264_pthread_cond_destroy( &slist->cv_fill ); |
873 | 0 | x264_pthread_cond_destroy( &slist->cv_empty ); |
874 | 0 | x264_frame_delete_list( slist->list ); |
875 | 0 | } Unexecuted instantiation: x264_8_sync_frame_list_delete Unexecuted instantiation: x264_10_sync_frame_list_delete |
876 | | |
877 | | void x264_sync_frame_list_push( x264_sync_frame_list_t *slist, x264_frame_t *frame ) |
878 | 0 | { |
879 | 0 | x264_pthread_mutex_lock( &slist->mutex ); |
880 | 0 | while( slist->i_size == slist->i_max_size ) |
881 | 0 | x264_pthread_cond_wait( &slist->cv_empty, &slist->mutex ); |
882 | 0 | slist->list[ slist->i_size++ ] = frame; |
883 | 0 | x264_pthread_mutex_unlock( &slist->mutex ); |
884 | 0 | x264_pthread_cond_broadcast( &slist->cv_fill ); |
885 | 0 | } Unexecuted instantiation: x264_8_sync_frame_list_push Unexecuted instantiation: x264_10_sync_frame_list_push |
886 | | |
887 | | x264_frame_t *x264_sync_frame_list_pop( x264_sync_frame_list_t *slist ) |
888 | 0 | { |
889 | 0 | x264_frame_t *frame; |
890 | 0 | x264_pthread_mutex_lock( &slist->mutex ); |
891 | 0 | while( !slist->i_size ) |
892 | 0 | x264_pthread_cond_wait( &slist->cv_fill, &slist->mutex ); |
893 | 0 | frame = slist->list[ --slist->i_size ]; |
894 | 0 | slist->list[ slist->i_size ] = NULL; |
895 | 0 | x264_pthread_cond_broadcast( &slist->cv_empty ); |
896 | 0 | x264_pthread_mutex_unlock( &slist->mutex ); |
897 | 0 | return frame; |
898 | 0 | } Unexecuted instantiation: x264_8_sync_frame_list_pop Unexecuted instantiation: x264_10_sync_frame_list_pop |