cpu: do not define capabilities on platforms that do not have them
[vlc.git] / modules / stream_out / switcher.c
1 /*****************************************************************************
2  * switcher.c: MPEG2 video switcher module
3  *****************************************************************************
4  * Copyright (C) 2004 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Christophe Massiot <massiot@via.ecp.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <math.h>
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <vlc_common.h>
34 #include <vlc_plugin.h>
35 #include <vlc_sout.h>
36 #include <vlc_avcodec.h>
37 #include <vlc_filter.h>
38 #include <vlc_cpu.h>
39
40 #include <vlc_block.h>
41
42 #include <vlc_fs.h>
43 #include <vlc_network.h>
44
45 #define HAVE_MMX
46 #ifdef HAVE_LIBAVCODEC_AVCODEC_H
47 #   include <libavcodec/avcodec.h>
48 #elif defined(HAVE_FFMPEG_AVCODEC_H)
49 #   include <ffmpeg/avcodec.h>
50 #else
51 #   include <avcodec.h>
52 #endif
53
54 #include "../codec/avcodec/avcodec.h"
55 #include "../codec/avcodec/avcommon.h"
56
57 #define SOUT_CFG_PREFIX "sout-switcher-"
58 #define MAX_PICTURES 10
59 #define MAX_AUDIO 30
60 #define MAX_THRESHOLD 99999999
61
62 /*****************************************************************************
63  * Local prototypes
64  *****************************************************************************/
65 static int      Open    ( vlc_object_t * );
66 static void     Close   ( vlc_object_t * );
67
68 static sout_stream_id_t *Add( sout_stream_t *, es_format_t * );
69 static int Del( sout_stream_t *, sout_stream_id_t * );
70 static int Send( sout_stream_t *, sout_stream_id_t *, block_t * );
71
72 static mtime_t Process( sout_stream_t *p_stream, sout_stream_id_t *id,
73                         mtime_t i_max_dts );
74 static int UnpackFromFile( sout_stream_t *p_stream, const char *psz_file,
75                            int i_width, int i_height,
76                            picture_t *p_pic );
77 static void NetCommand( sout_stream_t *p_stream );
78 static mtime_t VideoCommand( sout_stream_t *p_stream, sout_stream_id_t *id );
79 static block_t *VideoGetBuffer( sout_stream_t *p_stream, sout_stream_id_t *id,
80                                 block_t *p_buffer );
81 static block_t *AudioGetBuffer( sout_stream_t *p_stream, sout_stream_id_t *id,
82                                 block_t *p_buffer );
83
84 /*****************************************************************************
85  * Module descriptor
86  *****************************************************************************/
87 #define FILES_TEXT N_("Files")
88 #define FILES_LONGTEXT N_( \
89     "Full paths of the files separated by colons." )
90 #define SIZES_TEXT N_("Sizes")
91 #define SIZES_LONGTEXT N_( \
92     "List of sizes separated by colons (720x576:480x576)." )
93 #define RATIO_TEXT N_("Aspect ratio")
94 #define RATIO_LONGTEXT N_( \
95     "Aspect ratio (4:3, 16:9)." )
96 #define PORT_TEXT N_("Command UDP port")
97 #define PORT_LONGTEXT N_( \
98     "UDP port to listen to for commands." )
99 #define COMMAND_TEXT N_("Command")
100 #define COMMAND_LONGTEXT N_( \
101     "Initial command to execute." )
102 #define GOP_TEXT N_("GOP size")
103 #define GOP_LONGTEXT N_( \
104     "Number of P frames between two I frames." )
105 #define QSCALE_TEXT N_("Quantizer scale")
106 #define QSCALE_LONGTEXT N_( \
107     "Fixed quantizer scale to use." )
108 #define AUDIO_TEXT N_("Mute audio")
109 #define AUDIO_LONGTEXT N_( \
110     "Mute audio when command is not 0." )
111
112 vlc_module_begin ()
113     set_description( N_("MPEG2 video switcher stream output") )
114     set_capability( "sout stream", 50 )
115     add_shortcut( "switcher" )
116     set_callbacks( Open, Close )
117
118     add_string( SOUT_CFG_PREFIX "files", "", FILES_TEXT,
119                 FILES_LONGTEXT, false )
120     add_string( SOUT_CFG_PREFIX "sizes", "", SIZES_TEXT,
121                 SIZES_LONGTEXT, false )
122     add_string( SOUT_CFG_PREFIX "aspect-ratio", "4:3", RATIO_TEXT,
123                 RATIO_LONGTEXT, false )
124     add_integer( SOUT_CFG_PREFIX "port", 5001,
125                  PORT_TEXT, PORT_LONGTEXT, true )
126     add_integer( SOUT_CFG_PREFIX "command", 0,
127                  COMMAND_TEXT, COMMAND_LONGTEXT, true )
128     add_integer( SOUT_CFG_PREFIX "gop", 8,
129                  GOP_TEXT, GOP_LONGTEXT, true )
130     add_integer( SOUT_CFG_PREFIX "qscale", 5,
131                  QSCALE_TEXT, QSCALE_LONGTEXT, true )
132     add_bool( SOUT_CFG_PREFIX "mute-audio", true,
133               AUDIO_TEXT, AUDIO_LONGTEXT, true )
134 #if LIBAVCODEC_VERSION_MAJOR >= 54
135     add_string( SOUT_CFG_PREFIX "options", NULL,
136                 AV_OPTIONS_TEXT, AV_OPTIONS_LONGTEXT, true )
137 #endif
138 vlc_module_end ()
139
140 static const char *const ppsz_sout_options[] = {
141     "files", "sizes", "aspect-ratio", "port", "command", "gop", "qscale",
142     "mute-audio", "options", NULL
143 };
144
145 struct sout_stream_sys_t
146 {
147     int             i_gop;
148     int             i_qscale;
149     int             i_aspect;
150     sout_stream_id_t *pp_audio_ids[MAX_AUDIO];
151     bool            b_audio;
152
153     /* Pictures */
154     picture_t       p_pictures[MAX_PICTURES];
155     int             i_nb_pictures;
156
157     /* Command */
158     int             i_fd;
159     int             i_cmd, i_old_cmd;
160
161 #if LIBAVCODEC_VERSION_MAJOR >= 54
162     AVDictionary    *options;
163 #endif
164 };
165
166 struct sout_stream_id_t
167 {
168     void            *id;
169     bool            b_switcher_video;
170     bool            b_switcher_audio;
171     es_format_t     f_src;
172     block_t         *p_queued;
173
174     /* ffmpeg part */
175     AVCodec         *ff_enc;
176     AVCodecContext  *ff_enc_c;
177     AVFrame         *p_frame;
178     uint8_t         *p_buffer_out;
179     int             i_nb_pred;
180     int16_t         *p_samples;
181 };
182
183 /*****************************************************************************
184  * Open:
185  *****************************************************************************/
186 static int Open( vlc_object_t *p_this )
187 {
188     sout_stream_t     *p_stream = (sout_stream_t*)p_this;
189     sout_stream_sys_t *p_sys;
190     vlc_value_t       val;
191     char              *psz_files, *psz_sizes;
192     int               i_height = 0, i_width = 0;
193
194     vlc_init_avcodec();
195
196     p_sys = calloc( 1, sizeof(sout_stream_sys_t) );
197     if( !p_sys )
198         return VLC_ENOMEM;
199
200     if( !p_stream->p_next )
201     {
202         msg_Err( p_stream, "cannot create chain" );
203         free( p_sys );
204         return VLC_EGENERIC;
205     }
206
207     config_ChainParse( p_stream, SOUT_CFG_PREFIX, ppsz_sout_options,
208                    p_stream->p_cfg );
209
210     var_Get( p_stream, SOUT_CFG_PREFIX "files", &val );
211     psz_files = val.psz_string;
212     var_Get( p_stream, SOUT_CFG_PREFIX "sizes", &val );
213     psz_sizes = val.psz_string;
214
215     p_sys->i_nb_pictures = 0;
216     while ( psz_files && *psz_files )
217     {
218         char * psz_file = psz_files;
219         char * psz_size = psz_sizes;
220
221         while ( *psz_files && *psz_files != ':' )
222             psz_files++;
223         if ( *psz_files == ':' )
224            *psz_files++ = '\0';
225
226         if ( *psz_sizes )
227         {
228             while ( *psz_sizes && *psz_sizes != ':' )
229                 psz_sizes++;
230             if ( *psz_sizes == ':' )
231                 *psz_sizes++ = '\0';
232             if ( sscanf( psz_size, "%dx%d", &i_width, &i_height ) != 2 )
233             {
234                 msg_Err( p_stream, "bad size %s for file %s", psz_size,
235                          psz_file );
236                 free( p_sys );
237                 return VLC_EGENERIC;
238             }
239         }
240
241         if ( UnpackFromFile( p_stream, psz_file, i_width, i_height,
242                              &p_sys->p_pictures[p_sys->i_nb_pictures] ) < 0 )
243         {
244             free( p_sys );
245             return VLC_EGENERIC;
246         }
247         p_sys->i_nb_pictures++;
248     }
249
250     var_Get( p_stream, SOUT_CFG_PREFIX "aspect-ratio", &val );
251     if ( val.psz_string )
252     {
253         char *psz_parser = strchr( val.psz_string, ':' );
254
255         if( psz_parser )
256         {
257             *psz_parser++ = '\0';
258             p_sys->i_aspect = atoi( val.psz_string ) * VOUT_ASPECT_FACTOR
259                 / atoi( psz_parser );
260         }
261         else
262         {
263             msg_Warn( p_stream, "bad aspect ratio %s", val.psz_string );
264             p_sys->i_aspect = 4 * VOUT_ASPECT_FACTOR / 3;
265         }
266
267         free( val.psz_string );
268     }
269     else
270     {
271         p_sys->i_aspect = 4 * VOUT_ASPECT_FACTOR / 3;
272     }
273
274     var_Get( p_stream, SOUT_CFG_PREFIX "port", &val );
275     p_sys->i_fd = net_ListenUDP1( VLC_OBJECT(p_stream), NULL, val.i_int );
276     if ( p_sys->i_fd < 0 )
277     {
278         free( p_sys );
279         return VLC_EGENERIC;
280     }
281
282     var_Get( p_stream, SOUT_CFG_PREFIX "command", &val );
283     p_sys->i_cmd = val.i_int;
284     p_sys->i_old_cmd = 0;
285
286     var_Get( p_stream, SOUT_CFG_PREFIX "gop", &val );
287     p_sys->i_gop = val.i_int;
288
289     var_Get( p_stream, SOUT_CFG_PREFIX "qscale", &val );
290     p_sys->i_qscale = val.i_int;
291
292     var_Get( p_stream, SOUT_CFG_PREFIX "mute-audio", &val );
293     p_sys->b_audio = val.b_bool;
294
295     p_stream->pf_add    = Add;
296     p_stream->pf_del    = Del;
297     p_stream->pf_send   = Send;
298     p_stream->p_sys     = p_sys;
299
300 #if LIBAVCODEC_VERSION_MAJOR >= 54
301     char *psz_opts = var_InheritString( p_stream, SOUT_CFG_PREFIX "options" );
302     if (psz_opts && *psz_opts) {
303         p_sys->options = vlc_av_get_options(psz_opts);
304     } else {
305         p_sys->options = NULL;
306     }
307     free(psz_opts);
308 #endif
309
310     return VLC_SUCCESS;
311 }
312
313 /*****************************************************************************
314  * Close:
315  *****************************************************************************/
316 static void Close( vlc_object_t * p_this )
317 {
318     sout_stream_t       *p_stream = (sout_stream_t *)p_this;
319     sout_stream_sys_t   *p_sys = p_stream->p_sys;
320
321 #if LIBAVCODEC_VERSION_MAJOR >= 54
322     av_dict_free( &p_sys->options );
323 #endif
324
325     free( p_sys );
326 }
327
328 /*****************************************************************************
329  * Add: Add an input elementary stream
330  *****************************************************************************/
331 static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
332 {
333     sout_stream_sys_t   *p_sys = p_stream->p_sys;
334     sout_stream_id_t    *id;
335
336     id = calloc( 1, sizeof( sout_stream_id_t ) );
337     if( !id )
338         return NULL;
339
340     if( p_fmt->i_cat == VIDEO_ES && p_fmt->i_codec == VLC_CODEC_MPGV )
341     {
342         id->b_switcher_video = true;
343         p_fmt->i_codec = VLC_CODEC_MPGV;
344         msg_Dbg( p_stream, "creating video switcher for fcc=`%4.4s' cmd:%d",
345                  (char*)&p_fmt->i_codec, p_sys->i_cmd );
346     }
347     else if ( p_fmt->i_cat == AUDIO_ES &&
348               p_fmt->i_codec == VLC_CODEC_MPGA &&
349               p_sys->b_audio )
350     {
351         int i_ff_codec = CODEC_ID_MP2;
352         int i;
353
354         id->b_switcher_audio = true;
355         msg_Dbg( p_stream, "creating audio switcher for fcc=`%4.4s' cmd:%d",
356                  (char*)&p_fmt->i_codec, p_sys->i_cmd );
357
358         /* Allocate the encoder right now. */
359         if( i_ff_codec == 0 )
360         {
361             msg_Err( p_stream, "cannot find encoder" );
362             free( id );
363             return NULL;
364         }
365
366         id->ff_enc = avcodec_find_encoder( i_ff_codec );
367         if( !id->ff_enc )
368         {
369             msg_Err( p_stream, "cannot find encoder (avcodec)" );
370             free( id );
371             return NULL;
372         }
373
374 #if LIBAVCODEC_VERSION_MAJOR < 54
375         id->ff_enc_c = avcodec_alloc_context();
376 #else
377         id->ff_enc_c = avcodec_alloc_context3( id->ff_enc );
378 #endif
379
380         /* Set CPU capabilities */
381         id->ff_enc_c->dsp_mask = 0;
382 #if defined (__i386__) || defined (__x86_64__)
383         unsigned i_cpu = vlc_CPU();
384         if( !(i_cpu & CPU_CAPABILITY_MMX) )
385             id->ff_enc_c->dsp_mask |= AV_CPU_FLAG_MMX;
386         if( !(i_cpu & CPU_CAPABILITY_MMXEXT) )
387             id->ff_enc_c->dsp_mask |= AV_CPU_FLAG_MMX2;
388         if( !(i_cpu & CPU_CAPABILITY_3DNOW) )
389             id->ff_enc_c->dsp_mask |= AV_CPU_FLAG_3DNOW;
390         if( !(i_cpu & CPU_CAPABILITY_SSE) )
391             id->ff_enc_c->dsp_mask |= AV_CPU_FLAG_SSE;
392         if( !(i_cpu & CPU_CAPABILITY_SSE2) )
393             id->ff_enc_c->dsp_mask |= AV_CPU_FLAG_SSE2;
394 # ifdef AV_CPU_FLAG_SSE3
395         if( !(i_cpu & CPU_CAPABILITY_SSE3) )
396             id->ff_enc_c->dsp_mask |= AV_CPU_FLAG_SSE3;
397 # endif
398 # ifdef AV_CPU_FLAG_SSSE3
399         if( !(i_cpu & CPU_CAPABILITY_SSSE3) )
400             id->ff_enc_c->dsp_mask |= AV_CPU_FLAG_SSSE3;
401 # endif
402 # ifdef AV_CPU_FLAG_SSE4
403         if( !(i_cpu & CPU_CAPABILITY_SSE4_1) )
404             id->ff_enc_c->dsp_mask |= AV_CPU_FLAG_SSE4;
405 # endif
406 # ifdef AV_CPU_FLAG_SSE42
407         if( !(i_cpu & CPU_CAPABILITY_SSE4_2) )
408             id->ff_enc_c->dsp_mask |= AV_CPU_FLAG_SSE42;
409 # endif
410 #endif
411
412         id->ff_enc_c->sample_rate = p_fmt->audio.i_rate;
413         id->ff_enc_c->time_base.num = 1;
414         id->ff_enc_c->time_base.den = p_fmt->audio.i_rate;
415         id->ff_enc_c->channels    = p_fmt->audio.i_channels;
416         id->ff_enc_c->bit_rate    = p_fmt->i_bitrate;
417
418         int ret;
419 #if LIBAVCODEC_VERSION_MAJOR >= 54
420         AVDictionary *options = NULL;
421         if (p_sys->options)
422             av_dict_copy(&options, p_sys->options, 0);
423         vlc_avcodec_lock();
424         ret = avcodec_open2( id->ff_enc_c, id->ff_enc, options ? &options : NULL );
425         vlc_avcodec_unlock();
426         AVDictionaryEntry *t = NULL;
427         while ((t = av_dict_get(options, "", t, AV_DICT_IGNORE_SUFFIX))) {
428             msg_Err( p_stream, "Unknown option \"%s\"", t->key );
429         }
430         av_dict_free(&options);
431 #else
432         vlc_avcodec_lock();
433         ret = avcodec_open( id->ff_enc_c, id->ff_enc );
434         vlc_avcodec_unlock();
435 #endif
436
437         if (ret)
438         {
439             msg_Err( p_stream, "cannot open encoder" );
440             av_free( id->ff_enc_c );
441             free( id );
442             return NULL;
443         }
444
445         id->p_buffer_out = malloc( AVCODEC_MAX_AUDIO_FRAME_SIZE * 2 );
446         id->p_samples = calloc( id->ff_enc_c->frame_size * p_fmt->audio.i_channels,
447                                 sizeof(int16_t) );
448         if( !id->p_buffer_out || !id->p_samples )
449             goto error;
450
451         for( i = 0; i < MAX_AUDIO; i++ )
452         {
453             if( p_sys->pp_audio_ids[i] == NULL )
454             {
455                 p_sys->pp_audio_ids[i] = id;
456                 break;
457             }
458         }
459         if( i == MAX_AUDIO )
460         {
461             msg_Err( p_stream, "too many audio streams!" );
462             goto error;
463         }
464     }
465     else
466     {
467         msg_Dbg( p_stream, "do not know what to do when switching (fcc=`%4.4s')",
468                  (char*)&p_fmt->i_codec );
469     }
470
471     /* src format */
472     memcpy( &id->f_src, p_fmt, sizeof( es_format_t ) );
473
474     /* open output stream */
475     id->id = p_stream->p_next->pf_add( p_stream->p_next, p_fmt );
476
477     if( id->id != NULL )
478         return id;
479
480 error:
481     vlc_avcodec_lock();
482     avcodec_close( id->ff_enc_c );
483     vlc_avcodec_unlock();
484     free( id->p_samples );
485     free( id->p_buffer_out );
486     av_free( id->ff_enc_c );
487     free( id );
488     return NULL;
489 }
490
491 /*****************************************************************************
492  * Del: Del an elementary stream
493  *****************************************************************************/
494 static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
495 {
496     sout_stream_sys_t   *p_sys = p_stream->p_sys;
497
498     if ( id->b_switcher_audio )
499     {
500         int i;
501         for ( i = 0; i < MAX_AUDIO; i++ )
502         {
503             if ( p_sys->pp_audio_ids[i] == id )
504             {
505                 p_sys->pp_audio_ids[i] = NULL;
506                 break;
507             }
508         }
509     }
510
511     if ( id->ff_enc )
512     {
513         vlc_avcodec_lock();
514         avcodec_close( id->ff_enc_c );
515         vlc_avcodec_unlock();
516         av_free( id->ff_enc_c );
517         av_free( id->p_frame );
518         free( id->p_buffer_out );
519     }
520
521     if ( id->id )
522     {
523         p_stream->p_next->pf_del( p_stream->p_next, id->id );
524     }
525     free( id );
526
527     return VLC_SUCCESS;
528 }
529
530 /*****************************************************************************
531  * Send: Process an input packet
532  *****************************************************************************/
533 static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
534                  block_t *p_buffer )
535 {
536     sout_stream_sys_t *p_sys = p_stream->p_sys;
537
538     if ( !id->id )
539     {
540         block_Release( p_buffer );
541         return VLC_EGENERIC;
542     }
543
544     if ( !id->b_switcher_video && !id->b_switcher_audio )
545     {
546         return p_stream->p_next->pf_send( p_stream->p_next, id->id, p_buffer );
547     }
548
549     block_ChainAppend( &id->p_queued, p_buffer );
550
551     if ( id->b_switcher_video )
552     {
553         /* Check for commands for every video frame. */
554         NetCommand( p_stream );
555
556         while ( id->p_queued != NULL )
557         {
558             mtime_t i_dts = 0;
559
560             if ( p_sys->i_old_cmd != p_sys->i_cmd )
561             {
562                 i_dts = VideoCommand( p_stream, id );
563             }
564
565             i_dts = Process( p_stream, id, i_dts );
566
567             for ( int i = 0; i < MAX_AUDIO; i++ )
568             {
569                 if ( p_sys->pp_audio_ids[i] != NULL )
570                     Process( p_stream, p_sys->pp_audio_ids[i], i_dts );
571             }
572         }
573     }
574
575     return VLC_SUCCESS;
576 }
577
578 /*****************************************************************************
579  * Process: Process and dispatch buffers
580  *****************************************************************************/
581 static mtime_t Process( sout_stream_t *p_stream, sout_stream_id_t *id,
582                         mtime_t i_max_dts )
583 {
584     sout_stream_sys_t *p_sys = p_stream->p_sys;
585     mtime_t i_dts = 0;
586     block_t *p_blocks = NULL;
587     block_t *p_blocks_out = NULL;
588
589     /* Find out the blocks we need. */
590     while ( id->p_queued != NULL
591              && (!i_max_dts || id->p_queued->i_dts <= i_max_dts) )
592     {
593         block_t *p_next = id->p_queued->p_next;
594         id->p_queued->p_next = NULL;
595         i_dts = id->p_queued->i_dts;
596         block_ChainAppend( &p_blocks, id->p_queued );
597         id->p_queued = p_next;
598     }
599
600     if ( p_sys->i_old_cmd == 0 )
601     {
602         /* Full forward */
603         if ( p_blocks != NULL )
604             p_stream->p_next->pf_send( p_stream->p_next, id->id, p_blocks );
605         return i_dts;
606     }
607
608     if ( p_sys->i_old_cmd == -1 )
609     {
610         /* No output at all */
611         while ( p_blocks != NULL )
612         {
613             block_t * p_next = p_blocks->p_next;
614             block_Release( p_blocks );
615             p_blocks = p_next;
616         }
617         return i_dts;
618     }
619
620     while ( p_blocks != NULL )
621     {
622         block_t * p_next = p_blocks->p_next;
623         block_t * p_out;
624
625         if ( id->b_switcher_video )
626         {
627             p_out = VideoGetBuffer( p_stream, id, p_blocks );
628         }
629         else
630         {
631             p_out = AudioGetBuffer( p_stream, id, p_blocks );
632         }
633         p_blocks = p_next;
634         if ( p_out != NULL )
635         {
636             block_ChainAppend( &p_blocks_out, p_out );
637         }
638     }
639
640     if ( p_blocks_out != NULL )
641         p_stream->p_next->pf_send( p_stream->p_next, id->id, p_blocks_out );
642     return i_dts;
643 }
644
645 /*****************************************************************************
646  * UnpackFromFile: Read a YUV picture and store it in our format
647  *****************************************************************************/
648 static int UnpackFromFile( sout_stream_t *p_stream, const char *psz_file,
649                            int i_width, int i_height,
650                            picture_t *p_pic )
651 {
652     int i, j;
653     FILE *p_file = vlc_fopen( psz_file, "r" );
654
655     if ( p_file == NULL )
656     {
657         msg_Err( p_stream, "file %s not found", psz_file );
658         return -1;
659     }
660
661     if( picture_Setup( p_pic, VLC_CODEC_I420,
662                        i_width, i_height, 1, 1 ) )
663     {
664         msg_Err( p_stream, "unknown chroma" );
665         return -1;
666     }
667     for ( i = 0; i < p_pic->i_planes; i++ )
668     {
669         p_pic->p[i].p_pixels = malloc( p_pic->p[i].i_lines *
670                                            p_pic->p[i].i_pitch );
671         memset( p_pic->p[i].p_pixels, 0, p_pic->p[i].i_lines *
672                     p_pic->p[i].i_pitch );
673     }
674
675     for ( i = 0; i < i_height; i++ )
676     {
677         int i_chroma;
678         uint8_t p_buffer[i_width * 2];
679         uint8_t *p_char = p_buffer;
680         uint8_t *p_y = &p_pic->p[0].p_pixels[i * p_pic->p[0].i_pitch];
681         uint8_t *p_u = &p_pic->p[1].p_pixels[i/2 * p_pic->p[1].i_pitch];
682         uint8_t *p_v = &p_pic->p[2].p_pixels[i/2 * p_pic->p[2].i_pitch];
683
684         if ( fread( p_buffer, 2, i_width, p_file ) != (size_t)i_width )
685         {
686             msg_Err( p_stream, "premature end of file %s", psz_file );
687             fclose( p_file );
688             for ( i = 0; i < p_pic->i_planes; i++ )
689             {
690                 free( p_pic->p[i].p_pixels );
691             }
692             return -1;
693         }
694
695         i_chroma = 0;
696         for ( j = 0; j < i_width; j++ )
697         {
698             uint8_t **pp_chroma = i_chroma ? &p_v : &p_u;
699             i_chroma = !i_chroma;
700             if ( i & 1 )
701                 **pp_chroma = (**pp_chroma + *p_char + 1) / 2;
702             else
703                 **pp_chroma = *p_char;
704             (*pp_chroma)++;
705             p_char++;
706             *p_y++ = *p_char++;
707         }
708     }
709
710     fclose( p_file );
711     return 0;
712 }
713
714 /*****************************************************************************
715  * NetCommand: Get a command from the network
716  *****************************************************************************/
717 static void NetCommand( sout_stream_t *p_stream )
718 {
719     sout_stream_sys_t *p_sys = p_stream->p_sys;
720     char psz_buffer[11];
721     int i_len = recv( p_sys->i_fd, psz_buffer, sizeof( psz_buffer ) - 1, 0 );
722
723     if ( i_len > 0 )
724     {
725         psz_buffer[i_len] = '\0';
726         int i_cmd = strtol( psz_buffer, NULL, 0 );
727         if ( i_cmd < -1 || i_cmd > p_sys->i_nb_pictures )
728         {
729             msg_Err( p_stream, "got a wrong command (%d)", i_cmd );
730             return;
731         }
732
733         p_sys->i_cmd = i_cmd;
734
735         msg_Dbg( p_stream, "new command: %d old:%d", p_sys->i_cmd,
736                  p_sys->i_old_cmd );
737     }
738 }
739
740 /*****************************************************************************
741  * VideoCommand: Create/Delete a video encoder
742  *****************************************************************************/
743 static mtime_t VideoCommand( sout_stream_t *p_stream, sout_stream_id_t *id )
744 {
745     sout_stream_sys_t *p_sys = p_stream->p_sys;
746
747     if ( p_sys->i_cmd == 0 && !(id->p_queued->i_flags & BLOCK_FLAG_TYPE_I) )
748     {
749         mtime_t i_dts = id->p_queued->i_dts;
750         block_t *p_block = id->p_queued->p_next;
751
752         while ( p_block != NULL )
753         {
754             if ( p_block->i_flags & BLOCK_FLAG_TYPE_I )
755                 return i_dts;
756             i_dts = p_block->i_dts;
757             p_block = p_block->p_next;
758         }
759
760         return 0;
761     }
762
763     p_sys->i_old_cmd = p_sys->i_cmd;
764
765     if ( id->ff_enc )
766     {
767         vlc_avcodec_lock();
768         avcodec_close( id->ff_enc_c );
769         vlc_avcodec_unlock();
770         av_free( id->ff_enc_c );
771         av_free( id->p_frame );
772         free( id->p_buffer_out );
773         id->ff_enc = NULL;
774     }
775
776     if ( p_sys->i_cmd > 0 )
777     {
778         /* Create a new encoder. */
779         int i_ff_codec = CODEC_ID_MPEG2VIDEO;
780         int i_aspect_num, i_aspect_den;
781
782         if( i_ff_codec == 0 )
783         {
784             msg_Err( p_stream, "cannot find encoder" );
785             return 0;
786         }
787
788         id->ff_enc = avcodec_find_encoder( i_ff_codec );
789         if( !id->ff_enc )
790         {
791             msg_Err( p_stream, "cannot find encoder (avcodec)" );
792             return 0;
793         }
794
795 #if LIBAVCODEC_VERSION_MAJOR < 54
796         id->ff_enc_c = avcodec_alloc_context();
797 #else
798         id->ff_enc_c = avcodec_alloc_context3( id->ff_enc );
799 #endif
800
801         /* Set CPU capabilities */
802         id->ff_enc_c->dsp_mask = 0;
803 #if defined (__i386__) || defined (__x86_64__)
804         unsigned i_cpu = vlc_CPU();
805         if( !(i_cpu & CPU_CAPABILITY_MMX) )
806             id->ff_enc_c->dsp_mask |= AV_CPU_FLAG_MMX;
807         if( !(i_cpu & CPU_CAPABILITY_MMXEXT) )
808             id->ff_enc_c->dsp_mask |= AV_CPU_FLAG_MMX2;
809         if( !(i_cpu & CPU_CAPABILITY_3DNOW) )
810             id->ff_enc_c->dsp_mask |= AV_CPU_FLAG_3DNOW;
811         if( !(i_cpu & CPU_CAPABILITY_SSE) )
812             id->ff_enc_c->dsp_mask |= AV_CPU_FLAG_SSE;
813         if( !(i_cpu & CPU_CAPABILITY_SSE2) )
814             id->ff_enc_c->dsp_mask |= AV_CPU_FLAG_SSE2;
815 # ifdef AV_CPU_FLAG_SSE3
816         if( !(i_cpu & CPU_CAPABILITY_SSE3) )
817             id->ff_enc_c->dsp_mask |= AV_CPU_FLAG_SSE3;
818 # endif
819 # ifdef AV_CPU_FLAG_SSSE3
820         if( !(i_cpu & CPU_CAPABILITY_SSSE3) )
821             id->ff_enc_c->dsp_mask |= AV_CPU_FLAG_SSSE3;
822 # endif
823 # ifdef AV_CPU_FLAG_SSE4
824         if( !(i_cpu & CPU_CAPABILITY_SSE4_1) )
825             id->ff_enc_c->dsp_mask |= AV_CPU_FLAG_SSE4;
826 # endif
827 # ifdef AV_CPU_FLAG_SSE42
828         if( !(i_cpu & CPU_CAPABILITY_SSE4_2) )
829             id->ff_enc_c->dsp_mask |= AV_CPU_FLAG_SSE42;
830 # endif
831 #endif
832
833         id->ff_enc_c->width = p_sys->p_pictures[p_sys->i_cmd-1].format.i_width;
834         id->ff_enc_c->height = p_sys->p_pictures[p_sys->i_cmd-1].format.i_height;
835         av_reduce( &i_aspect_num, &i_aspect_den,
836                    p_sys->i_aspect,
837                    VOUT_ASPECT_FACTOR, 1 << 30 /* something big */ );
838         av_reduce( &id->ff_enc_c->sample_aspect_ratio.num,
839                    &id->ff_enc_c->sample_aspect_ratio.den,
840                    i_aspect_num * (int64_t)id->ff_enc_c->height,
841                    i_aspect_den * (int64_t)id->ff_enc_c->width, 1 << 30 );
842
843 #if LIBAVCODEC_BUILD >= 4754
844         id->ff_enc_c->time_base.num = 1;
845         id->ff_enc_c->time_base.den = 25; /* FIXME */
846 #else
847         id->ff_enc_c->frame_rate    = 25; /* FIXME */
848         id->ff_enc_c->frame_rate_base = 1;
849 #endif
850
851         id->ff_enc_c->gop_size = 200;
852         id->ff_enc_c->max_b_frames = 0;
853
854         id->ff_enc_c->flags |= CODEC_FLAG_QSCALE
855                             | CODEC_FLAG_INPUT_PRESERVED
856                             | CODEC_FLAG_LOW_DELAY;
857
858         id->ff_enc_c->mb_decision = FF_MB_DECISION_SIMPLE;
859         id->ff_enc_c->pix_fmt = PIX_FMT_YUV420P;
860
861         vlc_avcodec_lock();
862         int ret;
863 #if LIBAVCODEC_VERSION_MAJOR >= 54
864         AVDictionary *options = NULL;
865         if (p_sys->options)
866             av_dict_copy(&options, p_sys->options, 0);
867         ret = avcodec_open2( id->ff_enc_c, id->ff_enc, options ? &options : NULL );
868 #else
869         ret = avcodec_open( id->ff_enc_c, id->ff_enc );
870 #endif
871         vlc_avcodec_unlock();
872 #if LIBAVCODEC_VERSION_MAJOR >= 54
873         AVDictionaryEntry *t = NULL;
874         while ((t = av_dict_get(options, "", t, AV_DICT_IGNORE_SUFFIX))) {
875             msg_Err( p_stream, "Unknown option \"%s\"", t->key );
876         }
877         av_dict_free(&options);
878 #endif
879         if (ret)
880         {
881             msg_Err( p_stream, "cannot open encoder" );
882             return 0;
883         }
884
885         id->p_buffer_out = malloc( id->ff_enc_c->width * id->ff_enc_c->height * 3 );
886         id->p_frame = avcodec_alloc_frame();
887         id->p_frame->linesize[0] = p_sys->p_pictures[p_sys->i_cmd-1].p[0].i_pitch;
888         id->p_frame->linesize[1] = p_sys->p_pictures[p_sys->i_cmd-1].p[1].i_pitch;
889         id->p_frame->linesize[2] = p_sys->p_pictures[p_sys->i_cmd-1].p[2].i_pitch;
890         id->p_frame->data[0] = p_sys->p_pictures[p_sys->i_cmd-1].p[0].p_pixels;
891         id->p_frame->data[1] = p_sys->p_pictures[p_sys->i_cmd-1].p[1].p_pixels;
892         id->p_frame->data[2] = p_sys->p_pictures[p_sys->i_cmd-1].p[2].p_pixels;
893
894         id->i_nb_pred = p_sys->i_gop;
895     }
896
897     return 0;
898 }
899
900 /*****************************************************************************
901  * VideoGetBuffer: Build an alternate video buffer
902  *****************************************************************************/
903 static block_t *VideoGetBuffer( sout_stream_t *p_stream, sout_stream_id_t *id,
904                                 block_t *p_buffer )
905 {
906     sout_stream_sys_t *p_sys = p_stream->p_sys;
907     int i_out;
908     block_t *p_out;
909
910     id->p_frame->quality = p_sys->i_qscale * powf(2.0, FF_LAMBDA_SHIFT + 7.0)
911                             / 139.0;
912     id->p_frame->interlaced_frame = 0;
913     id->p_frame->top_field_first = 1;
914     id->p_frame->pts = p_buffer->i_dts;
915
916     if ( id->i_nb_pred >= p_sys->i_gop )
917     {
918         id->p_frame->pict_type = AV_PICTURE_TYPE_I;
919 #if 0
920         id->p_frame->me_threshold = 0;
921         id->p_frame->mb_threshold = 0;
922 #endif
923         id->i_nb_pred = 0;
924     }
925     else
926     {
927         id->p_frame->pict_type = AV_PICTURE_TYPE_P;
928 #if 0
929         if ( id->p_frame->mb_type != NULL )
930         {
931             id->p_frame->me_threshold = MAX_THRESHOLD;
932             id->p_frame->mb_threshold = MAX_THRESHOLD;
933         }
934 #endif
935         id->i_nb_pred++;
936     }
937
938     i_out = avcodec_encode_video( id->ff_enc_c, id->p_buffer_out,
939                                   id->ff_enc_c->width * id->ff_enc_c->height * 3,
940                                   id->p_frame );
941
942     if ( i_out <= 0 )
943         return NULL;
944
945 #if 0
946     if ( id->p_frame->mb_type == NULL
947           && id->ff_enc_c->coded_frame->pict_type != AV_PICTURE_TYPE_I )
948     {
949         int mb_width = (id->ff_enc_c->width + 15) / 16;
950         int mb_height = (id->ff_enc_c->height + 15) / 16;
951         int h_chroma_shift, v_chroma_shift;
952         int i;
953
954         avcodec_get_chroma_sub_sample( id->ff_enc_c->pix_fmt, &h_chroma_shift,
955                                        &v_chroma_shift );
956
957         id->p_frame->motion_subsample_log2
958             = id->ff_enc_c->coded_frame->motion_subsample_log2;
959         id->p_frame->mb_type = malloc( ((mb_width + 1) * (mb_height + 1) + 1)
960                                     * sizeof(uint32_t) );
961         memcpy( id->p_frame->mb_type, id->ff_enc_c->coded_frame->mb_type,
962                     (mb_width + 1) * mb_height * sizeof(id->p_frame->mb_type[0]));
963
964         for ( i = 0; i < 2; i++ )
965         {
966             int stride = ((16 * mb_width )
967                     >> id->ff_enc_c->coded_frame->motion_subsample_log2) + 1;
968             int height = ((16 * mb_height)
969                     >> id->ff_enc_c->coded_frame->motion_subsample_log2);
970             int b8_stride = mb_width * 2 + 1;
971
972             if ( id->ff_enc_c->coded_frame->motion_val[i] )
973             {
974                 id->p_frame->motion_val[i] = malloc( 2 * stride * height
975                                                 * sizeof(int16_t) );
976                 memcpy( id->p_frame->motion_val[i],
977                             id->ff_enc_c->coded_frame->motion_val[i],
978                             2 * stride * height * sizeof(int16_t) );
979             }
980             if ( id->ff_enc_c->coded_frame->ref_index[i] )
981             {
982                 id->p_frame->ref_index[i] = malloc( b8_stride * 2 * mb_height
983                                                * sizeof(int8_t) );
984                 memcpy( id->p_frame->ref_index[i],
985                             id->ff_enc_c->coded_frame->ref_index[i],
986                             b8_stride * 2 * mb_height * sizeof(int8_t));
987             }
988         }
989     }
990 #endif
991
992     p_out = block_New( p_stream, i_out );
993     memcpy( p_out->p_buffer, id->p_buffer_out, i_out );
994     p_out->i_length = p_buffer->i_length;
995     p_out->i_pts = p_buffer->i_dts;
996     p_out->i_dts = p_buffer->i_dts;
997
998     switch ( id->ff_enc_c->coded_frame->pict_type )
999     {
1000     case AV_PICTURE_TYPE_I:
1001         p_out->i_flags |= BLOCK_FLAG_TYPE_I;
1002         break;
1003     case AV_PICTURE_TYPE_P:
1004         p_out->i_flags |= BLOCK_FLAG_TYPE_P;
1005         break;
1006     case AV_PICTURE_TYPE_B:
1007         p_out->i_flags |= BLOCK_FLAG_TYPE_B;
1008         break;
1009     default:
1010         break;
1011     }
1012
1013     block_Release( p_buffer );
1014
1015     return p_out;
1016 }
1017
1018 /*****************************************************************************
1019  * AudioGetBuffer: Build an alternate audio buffer
1020  *****************************************************************************/
1021 static block_t *AudioGetBuffer( sout_stream_t *p_stream, sout_stream_id_t *id,
1022                                 block_t *p_buffer )
1023 {
1024     int i_out;
1025     block_t *p_out;
1026
1027     (void)p_stream;
1028     i_out = avcodec_encode_audio( id->ff_enc_c, id->p_buffer_out,
1029                                   2 * AVCODEC_MAX_AUDIO_FRAME_SIZE,
1030                                   id->p_samples );
1031
1032     if ( i_out <= 0 )
1033         return NULL;
1034
1035     p_out = block_New( p_stream, i_out );
1036     memcpy( p_out->p_buffer, id->p_buffer_out, i_out );
1037     p_out->i_length = p_buffer->i_length;
1038     p_out->i_pts = p_buffer->i_dts;
1039     p_out->i_dts = p_buffer->i_dts;
1040
1041     block_Release( p_buffer );
1042
1043     return p_out;
1044 }