+
+ return 0;
+}
+
+static inline int x264_slices_write( x264_t *h )
+{
+ int i_frame_size;
+
+#if VISUALIZE
+ if( h->param.b_visualize )
+ x264_visualize_init( h );
+#endif
+
+ if( h->param.i_threads == 1 )
+ {
+ x264_slice_write( h );
+ i_frame_size = h->out.nal[h->out.i_nal-1].i_payload;
+ }
+ else
+ {
+ int i_nal = h->out.i_nal;
+ int i_bs_size = h->out.i_bitstream / h->param.i_threads;
+ int i;
+ /* duplicate contexts */
+ for( i = 0; i < h->param.i_threads; i++ )
+ {
+ x264_t *t = h->thread[i];
+ if( i > 0 )
+ {
+ memcpy( t, h, sizeof(x264_t) );
+ t->out.p_bitstream += i*i_bs_size;
+ bs_init( &t->out.bs, t->out.p_bitstream, i_bs_size );
+ }
+ t->sh.i_first_mb = (i * h->sps->i_mb_height / h->param.i_threads) * h->sps->i_mb_width;
+ t->sh.i_last_mb = ((i+1) * h->sps->i_mb_height / h->param.i_threads) * h->sps->i_mb_width;
+ t->out.i_nal = i_nal + i;
+ }
+
+ /* dispatch */
+#if HAVE_PTHREAD
+ {
+ pthread_t handles[X264_SLICE_MAX];
+ void *status;
+ for( i = 0; i < h->param.i_threads; i++ )
+ pthread_create( &handles[i], NULL, (void*)x264_slice_write, (void*)h->thread[i] );
+ for( i = 0; i < h->param.i_threads; i++ )
+ pthread_join( handles[i], &status );
+ }
+#else
+ for( i = 0; i < h->param.i_threads; i++ )
+ x264_slice_write( h->thread[i] );
+#endif
+
+ /* merge contexts */
+ i_frame_size = h->out.nal[i_nal].i_payload;
+ for( i = 1; i < h->param.i_threads; i++ )
+ {
+ int j;
+ x264_t *t = h->thread[i];
+ h->out.nal[i_nal+i] = t->out.nal[i_nal+i];
+ i_frame_size += t->out.nal[i_nal+i].i_payload;
+ // all entries in stat.frame are ints
+ for( j = 0; j < sizeof(h->stat.frame) / sizeof(int); j++ )
+ ((int*)&h->stat.frame)[j] += ((int*)&t->stat.frame)[j];
+ }
+ h->out.i_nal = i_nal + h->param.i_threads;
+ }
+
+#if VISUALIZE
+ if( h->param.b_visualize )
+ {
+ x264_visualize_show( h );
+ x264_visualize_close( h );
+ }
+#endif
+
+ return i_frame_size;