fix lowres padding, which failed to extrapolate the right side for some resolutions.
[x262.git] / common / frame.c
1 /*****************************************************************************
2  * frame.c: h264 encoder library
3  *****************************************************************************
4  * Copyright (C) 2003-2008 x264 project
5  *
6  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
7  *          Loren Merritt <lorenm@u.washington.edu>
8  *          Jason Garrett-Glaser <darkshikari@gmail.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
25 #include "common.h"
26
27 #define ALIGN(x,a) (((x)+((a)-1))&~((a)-1))
28
29 x264_frame_t *x264_frame_new( x264_t *h )
30 {
31     x264_frame_t *frame;
32     int i, j;
33
34     int i_mb_count = h->mb.i_mb_count;
35     int i_stride, i_width, i_lines;
36     int i_padv = PADV << h->param.b_interlaced;
37     int luma_plane_size;
38     int chroma_plane_size;
39     int align = h->param.cpu&X264_CPU_CACHELINE_64 ? 64 : h->param.cpu&X264_CPU_CACHELINE_32 ? 32 : 16;
40
41     CHECKED_MALLOCZERO( frame, sizeof(x264_frame_t) );
42
43     /* allocate frame data (+64 for extra data for me) */
44     i_width  = ALIGN( h->param.i_width, 16 );
45     i_stride = ALIGN( i_width + 2*PADH, align );
46     i_lines  = ALIGN( h->param.i_height, 16<<h->param.b_interlaced );
47
48     frame->i_plane = 3;
49     for( i = 0; i < 3; i++ )
50     {
51         frame->i_stride[i] = ALIGN( i_stride >> !!i, align );
52         frame->i_width[i] = i_width >> !!i;
53         frame->i_lines[i] = i_lines >> !!i;
54     }
55
56     luma_plane_size = (frame->i_stride[0] * ( frame->i_lines[0] + 2*i_padv ));
57     chroma_plane_size = (frame->i_stride[1] * ( frame->i_lines[1] + 2*i_padv ));
58     for( i = 1; i < 3; i++ )
59     {
60         CHECKED_MALLOC( frame->buffer[i], chroma_plane_size );
61         frame->plane[i] = frame->buffer[i] + (frame->i_stride[i] * i_padv + PADH)/2;
62     }
63     /* all 4 luma planes allocated together, since the cacheline split code
64      * requires them to be in-phase wrt cacheline alignment. */
65     if( h->param.analyse.i_subpel_refine )
66     {
67         CHECKED_MALLOC( frame->buffer[0], 4*luma_plane_size);
68         for( i = 0; i < 4; i++ )
69             frame->filtered[i] = frame->buffer[0] + i*luma_plane_size + frame->i_stride[0] * i_padv + PADH;
70         frame->plane[0] = frame->filtered[0];
71     }
72     else
73     {
74         CHECKED_MALLOC( frame->buffer[0], luma_plane_size);
75         frame->plane[0] = frame->buffer[0] + frame->i_stride[0] * i_padv + PADH;
76     }
77
78     if( h->frames.b_have_lowres )
79     {
80         frame->i_width_lowres = frame->i_width[0]/2;
81         frame->i_stride_lowres = ALIGN( frame->i_width_lowres + 2*PADH, align );
82         frame->i_lines_lowres = frame->i_lines[0]/2;
83
84         luma_plane_size = frame->i_stride_lowres * ( frame->i_lines[0]/2 + 2*i_padv );
85
86         CHECKED_MALLOC( frame->buffer_lowres[0], 4 * luma_plane_size );
87         for( i = 0; i < 4; i++ )
88             frame->lowres[i] = frame->buffer_lowres[0] + (frame->i_stride_lowres * i_padv + PADH) + i * luma_plane_size;
89
90         for( j = 0; j <= !!h->param.i_bframe; j++ )
91             for( i = 0; i <= h->param.i_bframe; i++ )
92             {
93                 CHECKED_MALLOCZERO( frame->lowres_mvs[j][i], 2*h->mb.i_mb_count*sizeof(int16_t) );
94                 CHECKED_MALLOC( frame->lowres_mv_costs[j][i], h->mb.i_mb_count*sizeof(int) );
95             }
96         CHECKED_MALLOC( frame->i_propagate_cost, (i_mb_count+3) * sizeof(uint16_t) );
97         for( j = 0; j <= h->param.i_bframe+1; j++ )
98             for( i = 0; i <= h->param.i_bframe+1; i++ )
99             {
100                 CHECKED_MALLOC( frame->lowres_costs[j][i], (i_mb_count+3) * sizeof(uint16_t) );
101                 CHECKED_MALLOC( frame->lowres_inter_types[j][i], (i_mb_count+3) * sizeof(uint8_t) );
102             }
103         frame->i_intra_cost = frame->lowres_costs[0][0];
104         memset( frame->i_intra_cost, -1, (i_mb_count+3) * sizeof(uint16_t) );
105     }
106
107     if( h->param.analyse.i_me_method >= X264_ME_ESA )
108     {
109         CHECKED_MALLOC( frame->buffer[3],
110                         frame->i_stride[0] * (frame->i_lines[0] + 2*i_padv) * sizeof(uint16_t) << h->frames.b_have_sub8x8_esa );
111         frame->integral = (uint16_t*)frame->buffer[3] + frame->i_stride[0] * i_padv + PADH;
112     }
113
114     frame->i_poc = -1;
115     frame->i_type = X264_TYPE_AUTO;
116     frame->i_qpplus1 = 0;
117     frame->i_pts = -1;
118     frame->i_frame = -1;
119     frame->i_frame_num = -1;
120     frame->i_lines_completed = -1;
121
122     CHECKED_MALLOC( frame->mb_type, i_mb_count * sizeof(int8_t));
123     CHECKED_MALLOC( frame->mv[0], 2*16 * i_mb_count * sizeof(int16_t) );
124     CHECKED_MALLOC( frame->ref[0], 4 * i_mb_count * sizeof(int8_t) );
125     if( h->param.i_bframe )
126     {
127         CHECKED_MALLOC( frame->mv[1], 2*16 * i_mb_count * sizeof(int16_t) );
128         CHECKED_MALLOC( frame->ref[1], 4 * i_mb_count * sizeof(int8_t) );
129     }
130     else
131     {
132         frame->mv[1]  = NULL;
133         frame->ref[1] = NULL;
134     }
135
136     CHECKED_MALLOC( frame->i_row_bits, i_lines/16 * sizeof(int) );
137     CHECKED_MALLOC( frame->i_row_qp, i_lines/16 * sizeof(int) );
138     for( i = 0; i < h->param.i_bframe + 2; i++ )
139         for( j = 0; j < h->param.i_bframe + 2; j++ )
140             CHECKED_MALLOC( frame->i_row_satds[i][j], i_lines/16 * sizeof(int) );
141
142     if( h->param.rc.i_aq_mode )
143     {
144         CHECKED_MALLOC( frame->f_qp_offset, h->mb.i_mb_count * sizeof(float) );
145         if( h->frames.b_have_lowres )
146             /* shouldn't really be initialized, just silences a valgrind false-positive in x264_mbtree_propagate_cost_sse2 */
147             CHECKED_MALLOCZERO( frame->i_inv_qscale_factor, (h->mb.i_mb_count+3) * sizeof(uint16_t) );
148     }
149
150     if( x264_pthread_mutex_init( &frame->mutex, NULL ) )
151         goto fail;
152     if( x264_pthread_cond_init( &frame->cv, NULL ) )
153         goto fail;
154
155     return frame;
156
157 fail:
158     x264_free( frame );
159     return NULL;
160 }
161
162 void x264_frame_delete( x264_frame_t *frame )
163 {
164     int i, j;
165     for( i = 0; i < 4; i++ )
166         x264_free( frame->buffer[i] );
167     for( i = 0; i < 4; i++ )
168         x264_free( frame->buffer_lowres[i] );
169     for( i = 0; i < X264_BFRAME_MAX+2; i++ )
170         for( j = 0; j < X264_BFRAME_MAX+2; j++ )
171             x264_free( frame->i_row_satds[i][j] );
172     for( j = 0; j < 2; j++ )
173         for( i = 0; i <= X264_BFRAME_MAX; i++ )
174         {
175             x264_free( frame->lowres_mvs[j][i] );
176             x264_free( frame->lowres_mv_costs[j][i] );
177         }
178     x264_free( frame->i_propagate_cost );
179     for( j = 0; j <= X264_BFRAME_MAX+1; j++ )
180         for( i = 0; i <= X264_BFRAME_MAX+1; i++ )
181         {
182             x264_free( frame->lowres_costs[j][i] );
183             x264_free( frame->lowres_inter_types[j][i] );
184         }
185     x264_free( frame->f_qp_offset );
186     x264_free( frame->i_inv_qscale_factor );
187     x264_free( frame->i_row_bits );
188     x264_free( frame->i_row_qp );
189     x264_free( frame->mb_type );
190     x264_free( frame->mv[0] );
191     x264_free( frame->mv[1] );
192     x264_free( frame->ref[0] );
193     x264_free( frame->ref[1] );
194     x264_pthread_mutex_destroy( &frame->mutex );
195     x264_pthread_cond_destroy( &frame->cv );
196     x264_free( frame );
197 }
198
199 int x264_frame_copy_picture( x264_t *h, x264_frame_t *dst, x264_picture_t *src )
200 {
201     int i_csp = src->img.i_csp & X264_CSP_MASK;
202     int i;
203     if( i_csp != X264_CSP_I420 && i_csp != X264_CSP_YV12 )
204     {
205         x264_log( h, X264_LOG_ERROR, "Arg invalid CSP\n" );
206         return -1;
207     }
208
209     dst->i_type     = src->i_type;
210     dst->i_qpplus1  = src->i_qpplus1;
211     dst->i_pts      = src->i_pts;
212
213     for( i=0; i<3; i++ )
214     {
215         int s = (i_csp == X264_CSP_YV12 && i) ? i^3 : i;
216         uint8_t *plane = src->img.plane[s];
217         int stride = src->img.i_stride[s];
218         int width = h->param.i_width >> !!i;
219         int height = h->param.i_height >> !!i;
220         if( src->img.i_csp & X264_CSP_VFLIP )
221         {
222             plane += (height-1)*stride;
223             stride = -stride;
224         }
225         h->mc.plane_copy( dst->plane[i], dst->i_stride[i], plane, stride, width, height );
226     }
227     return 0;
228 }
229
230
231
232 static void plane_expand_border( uint8_t *pix, int i_stride, int i_width, int i_height, int i_padh, int i_padv, int b_pad_top, int b_pad_bottom )
233 {
234 #define PPIXEL(x, y) ( pix + (x) + (y)*i_stride )
235     int y;
236     for( y = 0; y < i_height; y++ )
237     {
238         /* left band */
239         memset( PPIXEL(-i_padh, y), PPIXEL(0, y)[0], i_padh );
240         /* right band */
241         memset( PPIXEL(i_width, y), PPIXEL(i_width-1, y)[0], i_padh );
242     }
243     /* upper band */
244     if( b_pad_top )
245     for( y = 0; y < i_padv; y++ )
246         memcpy( PPIXEL(-i_padh, -y-1), PPIXEL(-i_padh, 0), i_width+2*i_padh );
247     /* lower band */
248     if( b_pad_bottom )
249     for( y = 0; y < i_padv; y++ )
250         memcpy( PPIXEL(-i_padh, i_height+y), PPIXEL(-i_padh, i_height-1), i_width+2*i_padh );
251 #undef PPIXEL
252 }
253
254 void x264_frame_expand_border( x264_t *h, x264_frame_t *frame, int mb_y, int b_end )
255 {
256     int i;
257     int b_start = !mb_y;
258     if( mb_y & h->sh.b_mbaff )
259         return;
260     for( i = 0; i < frame->i_plane; i++ )
261     {
262         int stride = frame->i_stride[i];
263         int width = 16*h->sps->i_mb_width >> !!i;
264         int height = (b_end ? 16*(h->sps->i_mb_height - mb_y) >> h->sh.b_mbaff : 16) >> !!i;
265         int padh = PADH >> !!i;
266         int padv = PADV >> !!i;
267         // buffer: 2 chroma, 3 luma (rounded to 4) because deblocking goes beyond the top of the mb
268         uint8_t *pix = frame->plane[i] + X264_MAX(0, (16*mb_y-4)*stride >> !!i);
269         if( b_end && !b_start )
270             height += 4 >> (!!i + h->sh.b_mbaff);
271         if( h->sh.b_mbaff )
272         {
273             plane_expand_border( pix, stride*2, width, height, padh, padv, b_start, b_end );
274             plane_expand_border( pix+stride, stride*2, width, height, padh, padv, b_start, b_end );
275         }
276         else
277         {
278             plane_expand_border( pix, stride, width, height, padh, padv, b_start, b_end );
279         }
280     }
281 }
282
283 void x264_frame_expand_border_filtered( x264_t *h, x264_frame_t *frame, int mb_y, int b_end )
284 {
285     /* during filtering, 8 extra pixels were filtered on each edge,
286      * but up to 3 of the horizontal ones may be wrong.
287        we want to expand border from the last filtered pixel */
288     int b_start = !mb_y;
289     int stride = frame->i_stride[0];
290     int width = 16*h->sps->i_mb_width + 8;
291     int height = b_end ? (16*(h->sps->i_mb_height - mb_y) >> h->sh.b_mbaff) + 16 : 16;
292     int padh = PADH - 4;
293     int padv = PADV - 8;
294     int i;
295     for( i = 1; i < 4; i++ )
296     {
297         // buffer: 8 luma, to match the hpel filter
298         uint8_t *pix = frame->filtered[i] + (16*mb_y - (8 << h->sh.b_mbaff)) * stride - 4;
299         if( h->sh.b_mbaff )
300         {
301             plane_expand_border( pix, stride*2, width, height, padh, padv, b_start, b_end );
302             plane_expand_border( pix+stride, stride*2, width, height, padh, padv, b_start, b_end );
303         }
304         else
305         {
306             plane_expand_border( pix, stride, width, height, padh, padv, b_start, b_end );
307         }
308     }
309 }
310
311 void x264_frame_expand_border_lowres( x264_frame_t *frame )
312 {
313     int i;
314     for( i = 0; i < 4; i++ )
315         plane_expand_border( frame->lowres[i], frame->i_stride_lowres, frame->i_width_lowres, frame->i_lines_lowres, PADH, PADV, 1, 1 );
316 }
317
318 void x264_frame_expand_border_mod16( x264_t *h, x264_frame_t *frame )
319 {
320     int i, y;
321     for( i = 0; i < frame->i_plane; i++ )
322     {
323         int i_subsample = i ? 1 : 0;
324         int i_width = h->param.i_width >> i_subsample;
325         int i_height = h->param.i_height >> i_subsample;
326         int i_padx = ( h->sps->i_mb_width * 16 - h->param.i_width ) >> i_subsample;
327         int i_pady = ( h->sps->i_mb_height * 16 - h->param.i_height ) >> i_subsample;
328
329         if( i_padx )
330         {
331             for( y = 0; y < i_height; y++ )
332                 memset( &frame->plane[i][y*frame->i_stride[i] + i_width],
333                          frame->plane[i][y*frame->i_stride[i] + i_width - 1],
334                          i_padx );
335         }
336         if( i_pady )
337         {
338             //FIXME interlace? or just let it pad using the wrong field
339             for( y = i_height; y < i_height + i_pady; y++ )
340                 memcpy( &frame->plane[i][y*frame->i_stride[i]],
341                         &frame->plane[i][(i_height-1)*frame->i_stride[i]],
342                         i_width + i_padx );
343         }
344     }
345 }
346
347
348 /* cavlc + 8x8 transform stores nnz per 16 coeffs for the purpose of
349  * entropy coding, but per 64 coeffs for the purpose of deblocking */
350 static void munge_cavlc_nnz_row( x264_t *h, int mb_y, uint8_t (*buf)[16] )
351 {
352     uint32_t (*src)[6] = (uint32_t(*)[6])h->mb.non_zero_count + mb_y * h->sps->i_mb_width;
353     int8_t *transform = h->mb.mb_transform_size + mb_y * h->sps->i_mb_width;
354     int x, nnz;
355     for( x=0; x<h->sps->i_mb_width; x++ )
356     {
357         memcpy( buf+x, src+x, 16 );
358         if( transform[x] )
359         {
360             nnz = src[x][0] | src[x][1];
361             src[x][0] = src[x][1] = ((uint16_t)nnz ? 0x0101 : 0) + (nnz>>16 ? 0x01010000 : 0);
362             nnz = src[x][2] | src[x][3];
363             src[x][2] = src[x][3] = ((uint16_t)nnz ? 0x0101 : 0) + (nnz>>16 ? 0x01010000 : 0);
364         }
365     }
366 }
367
368 static void restore_cavlc_nnz_row( x264_t *h, int mb_y, uint8_t (*buf)[16] )
369 {
370     uint8_t (*dst)[24] = h->mb.non_zero_count + mb_y * h->sps->i_mb_width;
371     int x;
372     for( x=0; x<h->sps->i_mb_width; x++ )
373         memcpy( dst+x, buf+x, 16 );
374 }
375
376 static void munge_cavlc_nnz( x264_t *h, int mb_y, uint8_t (*buf)[16], void (*func)(x264_t*, int, uint8_t (*)[16]) )
377 {
378     func( h, mb_y, buf );
379     if( mb_y > 0 )
380         func( h, mb_y-1, buf + h->sps->i_mb_width );
381     if( h->sh.b_mbaff )
382     {
383         func( h, mb_y+1, buf + h->sps->i_mb_width * 2 );
384         if( mb_y > 0 )
385             func( h, mb_y-2, buf + h->sps->i_mb_width * 3 );
386     }
387 }
388
389
390 /* Deblocking filter */
391 static const uint8_t i_alpha_table[52+12*2] =
392 {
393      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
394      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
395      0,  0,  0,  0,  0,  0,  4,  4,  5,  6,
396      7,  8,  9, 10, 12, 13, 15, 17, 20, 22,
397     25, 28, 32, 36, 40, 45, 50, 56, 63, 71,
398     80, 90,101,113,127,144,162,182,203,226,
399    255,255,
400    255,255,255,255,255,255,255,255,255,255,255,255,
401 };
402 static const uint8_t i_beta_table[52+12*2] =
403 {
404      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
405      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
406      0,  0,  0,  0,  0,  0,  2,  2,  2,  3,
407      3,  3,  3,  4,  4,  4,  6,  6,  7,  7,
408      8,  8,  9,  9, 10, 10, 11, 11, 12, 12,
409     13, 13, 14, 14, 15, 15, 16, 16, 17, 17,
410     18, 18,
411     18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
412 };
413 static const int8_t i_tc0_table[52+12*2][4] =
414 {
415     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
416     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
417     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
418     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
419     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 1 },
420     {-1, 0, 0, 1 }, {-1, 0, 0, 1 }, {-1, 0, 0, 1 }, {-1, 0, 1, 1 }, {-1, 0, 1, 1 }, {-1, 1, 1, 1 },
421     {-1, 1, 1, 1 }, {-1, 1, 1, 1 }, {-1, 1, 1, 1 }, {-1, 1, 1, 2 }, {-1, 1, 1, 2 }, {-1, 1, 1, 2 },
422     {-1, 1, 1, 2 }, {-1, 1, 2, 3 }, {-1, 1, 2, 3 }, {-1, 2, 2, 3 }, {-1, 2, 2, 4 }, {-1, 2, 3, 4 },
423     {-1, 2, 3, 4 }, {-1, 3, 3, 5 }, {-1, 3, 4, 6 }, {-1, 3, 4, 6 }, {-1, 4, 5, 7 }, {-1, 4, 5, 8 },
424     {-1, 4, 6, 9 }, {-1, 5, 7,10 }, {-1, 6, 8,11 }, {-1, 6, 8,13 }, {-1, 7,10,14 }, {-1, 8,11,16 },
425     {-1, 9,12,18 }, {-1,10,13,20 }, {-1,11,15,23 }, {-1,13,17,25 },
426     {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 },
427     {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 },
428 };
429 #define alpha_table(x) i_alpha_table[(x)+12]
430 #define beta_table(x)  i_beta_table[(x)+12]
431 #define tc0_table(x)   i_tc0_table[(x)+12]
432
433 /* From ffmpeg */
434 static inline void deblock_luma_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0 )
435 {
436     int i, d;
437     for( i = 0; i < 4; i++ )
438     {
439         if( tc0[i] < 0 )
440         {
441             pix += 4*ystride;
442             continue;
443         }
444         for( d = 0; d < 4; d++ )
445         {
446             const int p2 = pix[-3*xstride];
447             const int p1 = pix[-2*xstride];
448             const int p0 = pix[-1*xstride];
449             const int q0 = pix[ 0*xstride];
450             const int q1 = pix[ 1*xstride];
451             const int q2 = pix[ 2*xstride];
452
453             if( abs( p0 - q0 ) < alpha && abs( p1 - p0 ) < beta && abs( q1 - q0 ) < beta )
454             {
455                 int tc = tc0[i];
456                 int delta;
457                 if( abs( p2 - p0 ) < beta )
458                 {
459                     pix[-2*xstride] = p1 + x264_clip3( (( p2 + ((p0 + q0 + 1) >> 1)) >> 1) - p1, -tc0[i], tc0[i] );
460                     tc++;
461                 }
462                 if( abs( q2 - q0 ) < beta )
463                 {
464                     pix[ 1*xstride] = q1 + x264_clip3( (( q2 + ((p0 + q0 + 1) >> 1)) >> 1) - q1, -tc0[i], tc0[i] );
465                     tc++;
466                 }
467
468                 delta = x264_clip3( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
469                 pix[-1*xstride] = x264_clip_uint8( p0 + delta );    /* p0' */
470                 pix[ 0*xstride] = x264_clip_uint8( q0 - delta );    /* q0' */
471             }
472             pix += ystride;
473         }
474     }
475 }
476 static void deblock_v_luma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
477 {
478     deblock_luma_c( pix, stride, 1, alpha, beta, tc0 );
479 }
480 static void deblock_h_luma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
481 {
482     deblock_luma_c( pix, 1, stride, alpha, beta, tc0 );
483 }
484
485 static inline void deblock_chroma_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0 )
486 {
487     int i, d;
488     for( i = 0; i < 4; i++ )
489     {
490         const int tc = tc0[i];
491         if( tc <= 0 )
492         {
493             pix += 2*ystride;
494             continue;
495         }
496         for( d = 0; d < 2; d++ )
497         {
498             const int p1 = pix[-2*xstride];
499             const int p0 = pix[-1*xstride];
500             const int q0 = pix[ 0*xstride];
501             const int q1 = pix[ 1*xstride];
502
503             if( abs( p0 - q0 ) < alpha && abs( p1 - p0 ) < beta && abs( q1 - q0 ) < beta )
504             {
505                 int delta = x264_clip3( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
506                 pix[-1*xstride] = x264_clip_uint8( p0 + delta );    /* p0' */
507                 pix[ 0*xstride] = x264_clip_uint8( q0 - delta );    /* q0' */
508             }
509             pix += ystride;
510         }
511     }
512 }
513 static void deblock_v_chroma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
514 {
515     deblock_chroma_c( pix, stride, 1, alpha, beta, tc0 );
516 }
517 static void deblock_h_chroma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
518 {
519     deblock_chroma_c( pix, 1, stride, alpha, beta, tc0 );
520 }
521
522 static inline void deblock_luma_intra_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta )
523 {
524     int d;
525     for( d = 0; d < 16; d++ )
526     {
527         const int p2 = pix[-3*xstride];
528         const int p1 = pix[-2*xstride];
529         const int p0 = pix[-1*xstride];
530         const int q0 = pix[ 0*xstride];
531         const int q1 = pix[ 1*xstride];
532         const int q2 = pix[ 2*xstride];
533
534         if( abs( p0 - q0 ) < alpha && abs( p1 - p0 ) < beta && abs( q1 - q0 ) < beta )
535         {
536             if(abs( p0 - q0 ) < ((alpha >> 2) + 2) )
537             {
538                 if( abs( p2 - p0 ) < beta ) /* p0', p1', p2' */
539                 {
540                     const int p3 = pix[-4*xstride];
541                     pix[-1*xstride] = ( p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4 ) >> 3;
542                     pix[-2*xstride] = ( p2 + p1 + p0 + q0 + 2 ) >> 2;
543                     pix[-3*xstride] = ( 2*p3 + 3*p2 + p1 + p0 + q0 + 4 ) >> 3;
544                 }
545                 else /* p0' */
546                     pix[-1*xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2;
547                 if( abs( q2 - q0 ) < beta ) /* q0', q1', q2' */
548                 {
549                     const int q3 = pix[3*xstride];
550                     pix[0*xstride] = ( p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4 ) >> 3;
551                     pix[1*xstride] = ( p0 + q0 + q1 + q2 + 2 ) >> 2;
552                     pix[2*xstride] = ( 2*q3 + 3*q2 + q1 + q0 + p0 + 4 ) >> 3;
553                 }
554                 else /* q0' */
555                     pix[0*xstride] = ( 2*q1 + q0 + p1 + 2 ) >> 2;
556             }
557             else /* p0', q0' */
558             {
559                 pix[-1*xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2;
560                 pix[ 0*xstride] = ( 2*q1 + q0 + p1 + 2 ) >> 2;
561             }
562         }
563         pix += ystride;
564     }
565 }
566 static void deblock_v_luma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
567 {
568     deblock_luma_intra_c( pix, stride, 1, alpha, beta );
569 }
570 static void deblock_h_luma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
571 {
572     deblock_luma_intra_c( pix, 1, stride, alpha, beta );
573 }
574
575 static inline void deblock_chroma_intra_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta )
576 {
577     int d;
578     for( d = 0; d < 8; d++ )
579     {
580         const int p1 = pix[-2*xstride];
581         const int p0 = pix[-1*xstride];
582         const int q0 = pix[ 0*xstride];
583         const int q1 = pix[ 1*xstride];
584
585         if( abs( p0 - q0 ) < alpha && abs( p1 - p0 ) < beta && abs( q1 - q0 ) < beta )
586         {
587             pix[-1*xstride] = (2*p1 + p0 + q1 + 2) >> 2;   /* p0' */
588             pix[ 0*xstride] = (2*q1 + q0 + p1 + 2) >> 2;   /* q0' */
589         }
590         pix += ystride;
591     }
592 }
593 static void deblock_v_chroma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
594 {
595     deblock_chroma_intra_c( pix, stride, 1, alpha, beta );
596 }
597 static void deblock_h_chroma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
598 {
599     deblock_chroma_intra_c( pix, 1, stride, alpha, beta );
600 }
601
602 static inline void deblock_edge( x264_t *h, uint8_t *pix1, uint8_t *pix2, int i_stride, uint8_t bS[4], int i_qp, int b_chroma, x264_deblock_inter_t pf_inter )
603 {
604     const int index_a = i_qp + h->sh.i_alpha_c0_offset;
605     const int alpha = alpha_table(index_a);
606     const int beta  = beta_table(i_qp + h->sh.i_beta_offset);
607     int8_t tc[4];
608
609     if( !alpha || !beta )
610         return;
611
612     tc[0] = tc0_table(index_a)[bS[0]] + b_chroma;
613     tc[1] = tc0_table(index_a)[bS[1]] + b_chroma;
614     tc[2] = tc0_table(index_a)[bS[2]] + b_chroma;
615     tc[3] = tc0_table(index_a)[bS[3]] + b_chroma;
616
617     pf_inter( pix1, i_stride, alpha, beta, tc );
618     if( b_chroma )
619         pf_inter( pix2, i_stride, alpha, beta, tc );
620 }
621
622 static inline void deblock_edge_intra( x264_t *h, uint8_t *pix1, uint8_t *pix2, int i_stride, uint8_t bS[4], int i_qp, int b_chroma, x264_deblock_intra_t pf_intra )
623 {
624     const int alpha = alpha_table(i_qp + h->sh.i_alpha_c0_offset);
625     const int beta  = beta_table(i_qp + h->sh.i_beta_offset);
626
627     if( !alpha || !beta )
628         return;
629
630     pf_intra( pix1, i_stride, alpha, beta );
631     if( b_chroma )
632         pf_intra( pix2, i_stride, alpha, beta );
633 }
634
635 void x264_frame_deblock_row( x264_t *h, int mb_y )
636 {
637     const int s8x8 = 2 * h->mb.i_mb_stride;
638     const int s4x4 = 4 * h->mb.i_mb_stride;
639     const int b_interlaced = h->sh.b_mbaff;
640     const int mvy_limit = 4 >> b_interlaced;
641     const int qp_thresh = 15 - X264_MIN(h->sh.i_alpha_c0_offset, h->sh.i_beta_offset) - X264_MAX(0, h->param.analyse.i_chroma_qp_offset);
642     const int no_sub8x8 = !(h->param.analyse.inter & X264_ANALYSE_PSUB8x8);
643     int mb_x;
644     int stridey   = h->fdec->i_stride[0];
645     int stride2y  = stridey << b_interlaced;
646     int strideuv  = h->fdec->i_stride[1];
647     int stride2uv = strideuv << b_interlaced;
648
649     if( !h->pps->b_cabac && h->pps->b_transform_8x8_mode )
650         munge_cavlc_nnz( h, mb_y, h->mb.nnz_backup, munge_cavlc_nnz_row );
651
652     for( mb_x = 0; mb_x < h->sps->i_mb_width; mb_x += (~b_interlaced | mb_y)&1, mb_y ^= b_interlaced )
653     {
654         const int mb_xy  = mb_y * h->mb.i_mb_stride + mb_x;
655         const int mb_8x8 = 2 * s8x8 * mb_y + 2 * mb_x;
656         const int mb_4x4 = 4 * s4x4 * mb_y + 4 * mb_x;
657         const int b_8x8_transform = h->mb.mb_transform_size[mb_xy];
658         const int i_qp = h->mb.qp[mb_xy];
659         int i_edge_end = (h->mb.type[mb_xy] == P_SKIP) ? 1 : 4;
660         uint8_t *pixy = h->fdec->plane[0] + 16*mb_y*stridey  + 16*mb_x;
661         uint8_t *pixu = h->fdec->plane[1] +  8*mb_y*strideuv +  8*mb_x;
662         uint8_t *pixv = h->fdec->plane[2] +  8*mb_y*strideuv +  8*mb_x;
663         if( b_interlaced && (mb_y&1) )
664         {
665             pixy -= 15*stridey;
666             pixu -=  7*strideuv;
667             pixv -=  7*strideuv;
668         }
669
670         x264_prefetch_fenc( h, h->fdec, mb_x, mb_y );
671
672         if( i_qp <= qp_thresh )
673             i_edge_end = 1;
674
675         #define FILTER_DIR(intra, i_dir)\
676         {\
677             /* Y plane */\
678             i_qpn= h->mb.qp[mbn_xy];\
679             if( i_dir == 0 )\
680             {\
681                 /* vertical edge */\
682                 deblock_edge##intra( h, pixy + 4*i_edge, NULL,\
683                               stride2y, bS, (i_qp+i_qpn+1) >> 1, 0,\
684                               h->loopf.deblock_h_luma##intra );\
685                 if( !(i_edge & 1) )\
686                 {\
687                     /* U/V planes */\
688                     int i_qpc = (h->chroma_qp_table[i_qp] + h->chroma_qp_table[i_qpn] + 1) >> 1;\
689                     deblock_edge##intra( h, pixu + 2*i_edge, pixv + 2*i_edge,\
690                                   stride2uv, bS, i_qpc, 1,\
691                                   h->loopf.deblock_h_chroma##intra );\
692                 }\
693             }\
694             else\
695             {\
696                 /* horizontal edge */\
697                 deblock_edge##intra( h, pixy + 4*i_edge*stride2y, NULL,\
698                               stride2y, bS, (i_qp+i_qpn+1) >> 1, 0,\
699                               h->loopf.deblock_v_luma##intra );\
700                 /* U/V planes */\
701                 if( !(i_edge & 1) )\
702                 {\
703                     int i_qpc = (h->chroma_qp_table[i_qp] + h->chroma_qp_table[i_qpn] + 1) >> 1;\
704                     deblock_edge##intra( h, pixu + 2*i_edge*stride2uv, pixv + 2*i_edge*stride2uv,\
705                                   stride2uv, bS, i_qpc, 1,\
706                                   h->loopf.deblock_v_chroma##intra );\
707                 }\
708             }\
709         }
710
711         #define DEBLOCK_STRENGTH(i_dir)\
712         {\
713             /* *** Get bS for each 4px for the current edge *** */\
714             if( IS_INTRA( h->mb.type[mb_xy] ) || IS_INTRA( h->mb.type[mbn_xy]) )\
715                 *(uint32_t*)bS = 0x03030303;\
716             else\
717             {\
718                 *(uint32_t*)bS = 0x00000000;\
719                 for( i = 0; i < 4; i++ )\
720                 {\
721                     int x  = i_dir == 0 ? i_edge : i;\
722                     int y  = i_dir == 0 ? i      : i_edge;\
723                     int xn = i_dir == 0 ? (x - 1)&0x03 : x;\
724                     int yn = i_dir == 0 ? y : (y - 1)&0x03;\
725                     if( h->mb.non_zero_count[mb_xy][x+y*4] != 0 ||\
726                         h->mb.non_zero_count[mbn_xy][xn+yn*4] != 0 )\
727                         bS[i] = 2;\
728                     else if(!(i_edge&no_sub8x8))\
729                     {\
730                         if((i&no_sub8x8) && bS[i-1] != 2)\
731                             bS[i] = bS[i-1];\
732                         else\
733                         {\
734                             /* FIXME: A given frame may occupy more than one position in\
735                              * the reference list. So we should compare the frame numbers,\
736                              * not the indices in the ref list.\
737                              * No harm yet, as we don't generate that case.*/\
738                             int i8p= mb_8x8+(x>>1)+(y>>1)*s8x8;\
739                             int i8q= mbn_8x8+(xn>>1)+(yn>>1)*s8x8;\
740                             int i4p= mb_4x4+x+y*s4x4;\
741                             int i4q= mbn_4x4+xn+yn*s4x4;\
742                             if((h->mb.ref[0][i8p] != h->mb.ref[0][i8q] ||\
743                                 abs( h->mb.mv[0][i4p][0] - h->mb.mv[0][i4q][0] ) >= 4 ||\
744                                 abs( h->mb.mv[0][i4p][1] - h->mb.mv[0][i4q][1] ) >= mvy_limit ) ||\
745                                (h->sh.i_type == SLICE_TYPE_B &&\
746                                (h->mb.ref[1][i8p] != h->mb.ref[1][i8q] ||\
747                                 abs( h->mb.mv[1][i4p][0] - h->mb.mv[1][i4q][0] ) >= 4 ||\
748                                 abs( h->mb.mv[1][i4p][1] - h->mb.mv[1][i4q][1] ) >= mvy_limit )))\
749                             {\
750                                 bS[i] = 1;\
751                             }\
752                         }\
753                     }\
754                 }\
755             }\
756         }
757
758         /* i_dir == 0 -> vertical edge
759          * i_dir == 1 -> horizontal edge */
760         #define DEBLOCK_DIR(i_dir)\
761         {\
762             int i_edge = (i_dir ? (mb_y <= b_interlaced) : (mb_x == 0));\
763             int i_qpn, i, mbn_xy, mbn_8x8, mbn_4x4;\
764             DECLARE_ALIGNED_4( uint8_t bS[4] );  /* filtering strength */\
765             if( i_edge )\
766                 i_edge+= b_8x8_transform;\
767             else\
768             {\
769                 mbn_xy  = i_dir == 0 ? mb_xy  - 1 : mb_xy - h->mb.i_mb_stride;\
770                 mbn_8x8 = i_dir == 0 ? mb_8x8 - 2 : mb_8x8 - 2 * s8x8;\
771                 mbn_4x4 = i_dir == 0 ? mb_4x4 - 4 : mb_4x4 - 4 * s4x4;\
772                 if( b_interlaced && i_dir == 1 )\
773                 {\
774                     mbn_xy -= h->mb.i_mb_stride;\
775                     mbn_8x8 -= 2 * s8x8;\
776                     mbn_4x4 -= 4 * s4x4;\
777                 }\
778                 else if( IS_INTRA( h->mb.type[mb_xy] ) || IS_INTRA( h->mb.type[mbn_xy]) )\
779                 {\
780                     FILTER_DIR( _intra, i_dir );\
781                     goto end##i_dir;\
782                 }\
783                 DEBLOCK_STRENGTH(i_dir);\
784                 if( *(uint32_t*)bS )\
785                     FILTER_DIR( , i_dir);\
786                 end##i_dir:\
787                 i_edge += b_8x8_transform+1;\
788             }\
789             mbn_xy  = mb_xy;\
790             mbn_8x8 = mb_8x8;\
791             mbn_4x4 = mb_4x4;\
792             for( ; i_edge < i_edge_end; i_edge+=b_8x8_transform+1 )\
793             {\
794                 DEBLOCK_STRENGTH(i_dir);\
795                 if( *(uint32_t*)bS )\
796                     FILTER_DIR( , i_dir);\
797             }\
798         }
799
800         DEBLOCK_DIR(0);
801         DEBLOCK_DIR(1);
802     }
803
804     if( !h->pps->b_cabac && h->pps->b_transform_8x8_mode )
805         munge_cavlc_nnz( h, mb_y, h->mb.nnz_backup, restore_cavlc_nnz_row );
806 }
807
808 void x264_frame_deblock( x264_t *h )
809 {
810     int mb_y;
811     for( mb_y = 0; mb_y < h->sps->i_mb_height; mb_y += 1 + h->sh.b_mbaff )
812         x264_frame_deblock_row( h, mb_y );
813 }
814
815 #ifdef HAVE_MMX
816 void x264_deblock_v_chroma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
817 void x264_deblock_h_chroma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
818 void x264_deblock_v_chroma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta );
819 void x264_deblock_h_chroma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta );
820
821 void x264_deblock_v_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
822 void x264_deblock_h_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
823 void x264_deblock_v_luma_intra_sse2( uint8_t *pix, int stride, int alpha, int beta );
824 void x264_deblock_h_luma_intra_sse2( uint8_t *pix, int stride, int alpha, int beta );
825 #ifdef ARCH_X86
826 void x264_deblock_h_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
827 void x264_deblock_v8_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
828 void x264_deblock_h_luma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta );
829 void x264_deblock_v8_luma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta );
830
831 static void x264_deblock_v_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
832 {
833     x264_deblock_v8_luma_mmxext( pix,   stride, alpha, beta, tc0   );
834     x264_deblock_v8_luma_mmxext( pix+8, stride, alpha, beta, tc0+2 );
835 }
836 static void x264_deblock_v_luma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta )
837 {
838     x264_deblock_v8_luma_intra_mmxext( pix,   stride, alpha, beta );
839     x264_deblock_v8_luma_intra_mmxext( pix+8, stride, alpha, beta );
840 }
841 #endif
842 #endif
843
844 #ifdef ARCH_PPC
845 void x264_deblock_v_luma_altivec( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
846 void x264_deblock_h_luma_altivec( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
847 #endif // ARCH_PPC
848
849 void x264_deblock_init( int cpu, x264_deblock_function_t *pf )
850 {
851     pf->deblock_v_luma = deblock_v_luma_c;
852     pf->deblock_h_luma = deblock_h_luma_c;
853     pf->deblock_v_chroma = deblock_v_chroma_c;
854     pf->deblock_h_chroma = deblock_h_chroma_c;
855     pf->deblock_v_luma_intra = deblock_v_luma_intra_c;
856     pf->deblock_h_luma_intra = deblock_h_luma_intra_c;
857     pf->deblock_v_chroma_intra = deblock_v_chroma_intra_c;
858     pf->deblock_h_chroma_intra = deblock_h_chroma_intra_c;
859
860 #ifdef HAVE_MMX
861     if( cpu&X264_CPU_MMXEXT )
862     {
863         pf->deblock_v_chroma = x264_deblock_v_chroma_mmxext;
864         pf->deblock_h_chroma = x264_deblock_h_chroma_mmxext;
865         pf->deblock_v_chroma_intra = x264_deblock_v_chroma_intra_mmxext;
866         pf->deblock_h_chroma_intra = x264_deblock_h_chroma_intra_mmxext;
867 #ifdef ARCH_X86
868         pf->deblock_v_luma = x264_deblock_v_luma_mmxext;
869         pf->deblock_h_luma = x264_deblock_h_luma_mmxext;
870         pf->deblock_v_luma_intra = x264_deblock_v_luma_intra_mmxext;
871         pf->deblock_h_luma_intra = x264_deblock_h_luma_intra_mmxext;
872 #endif
873         if( (cpu&X264_CPU_SSE2) && !(cpu&X264_CPU_STACK_MOD4) )
874         {
875             pf->deblock_v_luma = x264_deblock_v_luma_sse2;
876             pf->deblock_h_luma = x264_deblock_h_luma_sse2;
877             pf->deblock_v_luma_intra = x264_deblock_v_luma_intra_sse2;
878             pf->deblock_h_luma_intra = x264_deblock_h_luma_intra_sse2;
879         }
880     }
881 #endif
882
883 #ifdef ARCH_PPC
884     if( cpu&X264_CPU_ALTIVEC )
885     {
886         pf->deblock_v_luma = x264_deblock_v_luma_altivec;
887         pf->deblock_h_luma = x264_deblock_h_luma_altivec;
888    }
889 #endif // ARCH_PPC
890 }
891
892
893 /* threading */
894 void x264_frame_cond_broadcast( x264_frame_t *frame, int i_lines_completed )
895 {
896     x264_pthread_mutex_lock( &frame->mutex );
897     frame->i_lines_completed = i_lines_completed;
898     x264_pthread_cond_broadcast( &frame->cv );
899     x264_pthread_mutex_unlock( &frame->mutex );
900 }
901
902 void x264_frame_cond_wait( x264_frame_t *frame, int i_lines_completed )
903 {
904     x264_pthread_mutex_lock( &frame->mutex );
905     while( frame->i_lines_completed < i_lines_completed )
906         x264_pthread_cond_wait( &frame->cv, &frame->mutex );
907     x264_pthread_mutex_unlock( &frame->mutex );
908 }
909
910 /* list operators */
911
912 void x264_frame_push( x264_frame_t **list, x264_frame_t *frame )
913 {
914     int i = 0;
915     while( list[i] ) i++;
916     list[i] = frame;
917 }
918
919 x264_frame_t *x264_frame_pop( x264_frame_t **list )
920 {
921     x264_frame_t *frame;
922     int i = 0;
923     assert( list[0] );
924     while( list[i+1] ) i++;
925     frame = list[i];
926     list[i] = NULL;
927     return frame;
928 }
929
930 void x264_frame_unshift( x264_frame_t **list, x264_frame_t *frame )
931 {
932     int i = 0;
933     while( list[i] ) i++;
934     while( i-- )
935         list[i+1] = list[i];
936     list[0] = frame;
937 }
938
939 x264_frame_t *x264_frame_shift( x264_frame_t **list )
940 {
941     x264_frame_t *frame = list[0];
942     int i;
943     for( i = 0; list[i]; i++ )
944         list[i] = list[i+1];
945     assert(frame);
946     return frame;
947 }
948
949 void x264_frame_push_unused( x264_t *h, x264_frame_t *frame )
950 {
951     assert( frame->i_reference_count > 0 );
952     frame->i_reference_count--;
953     if( frame->i_reference_count == 0 )
954         x264_frame_push( h->frames.unused, frame );
955     assert( h->frames.unused[ sizeof(h->frames.unused) / sizeof(*h->frames.unused) - 1 ] == NULL );
956 }
957
958 x264_frame_t *x264_frame_pop_unused( x264_t *h )
959 {
960     x264_frame_t *frame;
961     if( h->frames.unused[0] )
962         frame = x264_frame_pop( h->frames.unused );
963     else
964         frame = x264_frame_new( h );
965     if( !frame )
966         return NULL;
967     frame->i_reference_count = 1;
968     frame->b_intra_calculated = 0;
969     return frame;
970 }
971
972 void x264_frame_sort( x264_frame_t **list, int b_dts )
973 {
974     int i, b_ok;
975     do {
976         b_ok = 1;
977         for( i = 0; list[i+1]; i++ )
978         {
979             int dtype = list[i]->i_type - list[i+1]->i_type;
980             int dtime = list[i]->i_frame - list[i+1]->i_frame;
981             int swap = b_dts ? dtype > 0 || ( dtype == 0 && dtime > 0 )
982                              : dtime > 0;
983             if( swap )
984             {
985                 XCHG( x264_frame_t*, list[i], list[i+1] );
986                 b_ok = 0;
987             }
988         }
989     } while( !b_ok );
990 }