+static void OutputFrame( sout_stream_t *p_stream, picture_t *p_pic, sout_stream_id_sys_t *id, block_t **out )
+{
+ sout_stream_sys_t *p_sys = p_stream->p_sys;
+ picture_t *p_pic2 = NULL;
+
+ /*
+ * Encoding
+ */
+ /* Check if we have a subpicture to overlay */
+ if( p_sys->p_spu )
+ {
+ video_format_t fmt = id->p_encoder->fmt_in.video;
+ if( fmt.i_visible_width <= 0 || fmt.i_visible_height <= 0 )
+ {
+ fmt.i_visible_width = fmt.i_width;
+ fmt.i_visible_height = fmt.i_height;
+ fmt.i_x_offset = 0;
+ fmt.i_y_offset = 0;
+ }
+
+ subpicture_t *p_subpic = spu_Render( p_sys->p_spu, NULL, &fmt,
+ &id->p_decoder->fmt_out.video,
+ p_pic->date, p_pic->date, false );
+
+ /* Overlay subpicture */
+ if( p_subpic )
+ {
+ if( picture_IsReferenced( p_pic ) && !filter_chain_GetLength( id->p_f_chain ) )
+ {
+ /* We can't modify the picture, we need to duplicate it,
+ * in this point the picture is already p_encoder->fmt.in format*/
+ picture_t *p_tmp = video_new_buffer_encoder( id->p_encoder );
+ if( likely( p_tmp ) )
+ {
+ picture_Copy( p_tmp, p_pic );
+ picture_Release( p_pic );
+ p_pic = p_tmp;
+ }
+ }
+ if( unlikely( !p_sys->p_spu_blend ) )
+ p_sys->p_spu_blend = filter_NewBlend( VLC_OBJECT( p_sys->p_spu ), &fmt );
+ if( likely( p_sys->p_spu_blend ) )
+ picture_BlendSubpicture( p_pic, p_sys->p_spu_blend, p_subpic );
+ subpicture_Delete( p_subpic );
+ }
+ }
+
+ if( p_sys->i_threads == 0 )
+ {
+ block_t *p_block;
+
+ p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
+ block_ChainAppend( out, p_block );
+ }
+
+ if( p_sys->i_threads )
+ {
+ vlc_mutex_lock( &p_sys->lock_out );
+ picture_fifo_Push( p_sys->pp_pics, p_pic );
+ vlc_cond_signal( &p_sys->cond );
+ vlc_mutex_unlock( &p_sys->lock_out );
+ }
+
+ if( p_sys->i_threads && p_pic2 )
+ picture_Release( p_pic2 );
+ else if ( p_sys->i_threads == 0 )
+ picture_Release( p_pic );
+}
+
+int transcode_video_process( sout_stream_t *p_stream, sout_stream_id_sys_t *id,