add deinterlacing support - add new image converter support
[ffmpeg.git] / ffmpeg.c
1 /*
2  * FFmpeg main 
3  * Copyright (c) 2000,2001 Gerard Lantau
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <unistd.h>
22 #include <fcntl.h>
23 #include <sys/ioctl.h>
24 #include <errno.h>
25 #include <sys/time.h>
26 #include <string.h>
27 #include <sys/poll.h>
28 #include <termios.h>
29 #include <sys/time.h>
30 #include <sys/resource.h>
31 #include <ctype.h>
32
33 #include "avformat.h"
34
35 typedef struct {
36     const char *name;
37     int flags;
38 #define HAS_ARG    0x0001
39 #define OPT_BOOL   0x0002
40 #define OPT_EXPERT 0x0004
41 #define OPT_STRING 0x0008
42     union {
43         void (*func_arg)();
44         int *int_arg;
45         char **str_arg;
46     } u;
47     const char *help;
48     const char *argname;
49 } OptionDef;
50
51 /* select an input stream for an output stream */
52 typedef struct AVStreamMap {
53     int file_index;
54     int stream_index;
55 } AVStreamMap;
56
57 extern const OptionDef options[];
58
59 void show_help(void);
60
61 #define MAX_FILES 20
62
63 static AVFormatContext *input_files[MAX_FILES];
64 static int nb_input_files = 0;
65
66 static AVFormatContext *output_files[MAX_FILES];
67 static int nb_output_files = 0;
68
69 static AVStreamMap stream_maps[MAX_FILES];
70 static int nb_stream_maps;
71
72 static AVFormat *file_format;
73 static int frame_width  = 160;
74 static int frame_height = 128;
75 static int frame_rate = 25 * FRAME_RATE_BASE;
76 static int video_bit_rate = 200000;
77 static int video_qscale = 0;
78 static int video_disable = 0;
79 static int video_codec_id = CODEC_ID_NONE;
80 static int same_quality = 0;
81 static int do_deinterlace = 0;
82
83 static int gop_size = 12;
84 static int intra_only = 0;
85 static int audio_sample_rate = 44100;
86 static int audio_bit_rate = 64000;
87 static int audio_disable = 0;
88 static int audio_channels = 1;
89 static int audio_codec_id = CODEC_ID_NONE;
90
91 static INT64 recording_time = 0;
92 static int file_overwrite = 0;
93 static char *str_title = NULL;
94 static char *str_author = NULL;
95 static char *str_copyright = NULL;
96 static char *str_comment = NULL;
97 static int do_benchmark = 0;
98
99 typedef struct AVOutputStream {
100     int file_index;          /* file index */
101     int index;               /* stream index in the output file */
102     int source_index;        /* AVInputStream index */
103     AVStream *st;            /* stream in the output file */
104     int encoding_needed;   /* true if encoding needed for this stream */
105
106     int fifo_packet_rptr;    /* read index in the corresponding
107                                 avinputstream packet fifo */
108     /* video only */
109     AVPicture pict_tmp;         /* temporary image for resizing */
110     int video_resample;
111     ImgReSampleContext *img_resample_ctx; /* for image resampling */
112     
113     /* audio only */
114     int audio_resample;
115     ReSampleContext *resample; /* for audio resampling */
116     FifoBuffer fifo;     /* for compression: one audio fifo per codec */
117 } AVOutputStream;
118
119 typedef struct AVInputStream {
120     int file_index;
121     int index;
122     AVStream *st;
123     int discard;             /* true if stream data should be discarded */
124     int decoding_needed;     /* true if the packets must be decoded in 'raw_fifo' */
125     INT64 pts;               /* current pts */
126     int frame_number;        /* current frame */
127     INT64 sample_index;      /* current sample */
128 } AVInputStream;
129
130 typedef struct AVInputFile {
131     int eof_reached;      /* true if eof reached */
132     int ist_index;        /* index of first stream in ist_table */
133     int buffer_size;      /* current total buffer size */
134     int buffer_size_max;  /* buffer size at which we consider we can stop
135                              buffering */
136 } AVInputFile;
137
138 /* init terminal so that we can grab keys */
139 static struct termios oldtty;
140
141 static void term_exit(void)
142 {
143     tcsetattr (0, TCSANOW, &oldtty);
144 }
145
146 static void term_init(void)
147 {
148     struct termios tty;
149
150     tcgetattr (0, &tty);
151     oldtty = tty;
152
153     tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
154                           |INLCR|IGNCR|ICRNL|IXON);
155     tty.c_oflag |= OPOST;
156     tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
157     tty.c_cflag &= ~(CSIZE|PARENB);
158     tty.c_cflag |= CS8;
159     tty.c_cc[VMIN] = 1;
160     tty.c_cc[VTIME] = 0;
161     
162     tcsetattr (0, TCSANOW, &tty);
163
164     atexit(term_exit);
165 }
166
167 /* read a key without blocking */
168 static int read_key(void)
169 {
170     struct timeval tv;
171     int n;
172     unsigned char ch;
173     fd_set rfds;
174
175     FD_ZERO(&rfds);
176     FD_SET(0, &rfds);
177     tv.tv_sec = 0;
178     tv.tv_usec = 0;
179     n = select(1, &rfds, NULL, NULL, &tv);
180     if (n > 0) {
181         if (read(0, &ch, 1) == 1)
182             return ch;
183     }
184     return -1;
185 }
186
187 #define AUDIO_FIFO_SIZE 8192
188
189 /* main loop for grabbing */
190 int av_grab(AVFormatContext *s)
191 {
192     UINT8 audio_buf[AUDIO_FIFO_SIZE/2];
193     UINT8 audio_buf1[AUDIO_FIFO_SIZE/2];
194     UINT8 audio_out[AUDIO_FIFO_SIZE/2];
195     UINT8 video_buffer[128*1024];
196     char buf[256];
197     short *samples;
198     URLContext *audio_handle = NULL, *video_handle = NULL;
199     int ret;
200     AVCodecContext *enc, *first_video_enc = NULL;
201     int frame_size, frame_bytes;
202     int use_audio, use_video;
203     int frame_rate, sample_rate, channels;
204     int width, height, frame_number, i, pix_fmt = 0;
205     AVOutputStream *ost_table[s->nb_streams], *ost;
206     UINT8 *picture_in_buf = NULL, *picture_420p = NULL;
207     int audio_fifo_size = 0, picture_size = 0;
208     INT64 time_start;
209
210     /* init output stream info */
211     for(i=0;i<s->nb_streams;i++)
212         ost_table[i] = NULL;
213
214     /* output stream init */
215     for(i=0;i<s->nb_streams;i++) {
216         ost = av_mallocz(sizeof(AVOutputStream));
217         if (!ost)
218             goto fail;
219         ost->index = i;
220         ost->st = s->streams[i];
221         ost_table[i] = ost;
222     }
223
224     use_audio = 0;
225     use_video = 0;
226     frame_rate = 0;
227     sample_rate = 0;
228     frame_size = 0;
229     channels = 1;
230     width = 0;
231     height = 0;
232     frame_number = 0;
233     
234     for(i=0;i<s->nb_streams;i++) {
235         AVCodec *codec;
236
237         ost = ost_table[i];
238         enc = &ost->st->codec;
239         codec = avcodec_find_encoder(enc->codec_id);
240         if (!codec) {
241             fprintf(stderr, "Unknown codec\n");
242             return -1;
243         }
244         if (avcodec_open(enc, codec) < 0) {
245             fprintf(stderr, "Incorrect encode parameters\n");
246             return -1;
247         }
248         switch(enc->codec_type) {
249         case CODEC_TYPE_AUDIO:
250             use_audio = 1;
251             if (enc->sample_rate > sample_rate)
252                 sample_rate = enc->sample_rate;
253             if (enc->frame_size > frame_size)
254                 frame_size = enc->frame_size;
255             if (enc->channels > channels)
256                 channels = enc->channels;
257             break;
258         case CODEC_TYPE_VIDEO:
259             if (!first_video_enc)
260                 first_video_enc = enc;
261             use_video = 1;
262             if (enc->frame_rate > frame_rate)
263                 frame_rate = enc->frame_rate;
264             if (enc->width > width)
265                 width = enc->width;
266             if (enc->height > height)
267                 height = enc->height;
268             break;
269         }
270     }
271
272     /* audio */
273     samples = NULL;
274     if (use_audio) {
275         snprintf(buf, sizeof(buf), "audio:%d,%d", sample_rate, channels);
276         ret = url_open(&audio_handle, buf, URL_RDONLY);
277         if (ret < 0) {
278             fprintf(stderr, "Could not open audio device: disabling audio capture\n");
279             use_audio = 0;
280         } else {
281             URLFormat f;
282             /* read back exact grab parameters */
283             if (url_getformat(audio_handle, &f) < 0) {
284                 fprintf(stderr, "could not read back video grab parameters\n");
285                 goto fail;
286             }
287             sample_rate = f.sample_rate;
288             channels = f.channels;
289             audio_fifo_size = ((AUDIO_FIFO_SIZE / 2) / audio_handle->packet_size) * 
290                 audio_handle->packet_size;
291             fprintf(stderr, "Audio sampling: %d Hz, %s\n", 
292                     sample_rate, channels == 2 ? "stereo" : "mono");
293         }
294     }
295     
296     /* video */
297     if (use_video) {
298         snprintf(buf, sizeof(buf), "video:%d,%d,%f", 
299                  width, height, (float)frame_rate / FRAME_RATE_BASE);
300
301         ret = url_open(&video_handle, buf, URL_RDONLY);
302         if (ret < 0) {
303             fprintf(stderr,"Could not init video 4 linux capture: disabling video capture\n");
304             use_video = 0;
305         } else {
306             URLFormat f;
307             const char *pix_fmt_str;
308             /* read back exact grab parameters */
309             if (url_getformat(video_handle, &f) < 0) {
310                 fprintf(stderr, "could not read back video grab parameters\n");
311                 goto fail;
312             }
313             width = f.width;
314             height = f.height;
315             pix_fmt = f.pix_fmt;
316             switch(pix_fmt) {
317             case PIX_FMT_YUV420P:
318                 pix_fmt_str = "420P";
319                 break;
320             case PIX_FMT_YUV422:
321                 pix_fmt_str = "422";
322                 break;
323             case PIX_FMT_RGB24:
324                 pix_fmt_str = "RGB24";
325                 break;
326             case PIX_FMT_BGR24:
327                 pix_fmt_str = "BGR24";
328                 break;
329             default:
330                 pix_fmt_str = "???";
331                 break;
332             }
333             picture_size = video_handle->packet_size;
334             picture_in_buf = malloc(picture_size);
335             if (!picture_in_buf)
336                 goto fail;
337             /* allocate a temporary picture if not grabbing in 420P format */
338             if (pix_fmt != PIX_FMT_YUV420P) {
339                 picture_420p = malloc((width * height * 3) / 2);
340             }
341             fprintf(stderr, "Video sampling: %dx%d, %s format, %0.2f fps\n", 
342                     width, height, pix_fmt_str, (float)frame_rate / FRAME_RATE_BASE);
343         }
344     }
345
346     if (!use_video && !use_audio) {
347         fprintf(stderr,"Could not open grab devices : exiting\n");
348         exit(1);
349     }
350
351     /* init built in conversion functions */
352     for(i=0;i<s->nb_streams;i++) {
353         ost = ost_table[i];
354         enc = &ost->st->codec;
355         switch(enc->codec_type) {
356         case CODEC_TYPE_AUDIO:
357             ost->audio_resample = 0;
358             if ((enc->channels != channels ||
359                  enc->sample_rate != sample_rate)) {
360                 ost->audio_resample = 1;
361                 ost->resample = audio_resample_init(enc->channels, channels,
362                                                     enc->sample_rate, sample_rate);
363             }
364             if (fifo_init(&ost->fifo, (2 * audio_fifo_size * enc->sample_rate) / 
365                           sample_rate))
366                 goto fail;
367             break;
368         case CODEC_TYPE_VIDEO:
369             ost->video_resample = 0;
370             if (enc->width != width ||
371                 enc->height != height) {
372                 UINT8 *buf;
373                 ost->video_resample = 1;
374                 buf = malloc((enc->width * enc->height * 3) / 2);
375                 if (!buf)
376                     goto fail;
377                 ost->pict_tmp.data[0] = buf;
378                 ost->pict_tmp.data[1] = buf + enc->width * height;
379                 ost->pict_tmp.data[2] = ost->pict_tmp.data[1] + (enc->width * height) / 4;
380                 ost->pict_tmp.linesize[0] = enc->width;
381                 ost->pict_tmp.linesize[1] = enc->width / 2;
382                 ost->pict_tmp.linesize[2] = enc->width / 2;
383                 ost->img_resample_ctx = img_resample_init(
384                                   ost->st->codec.width, ost->st->codec.height,
385                                   width, height);
386             }
387         }
388     }
389
390     fprintf(stderr, "Press [q] to stop encoding\n");
391
392     s->format->write_header(s);
393     time_start = gettime();
394     term_init();
395     
396     for(;;) {
397         /* if 'q' pressed, exits */
398         if (read_key() == 'q')
399             break;
400
401         /* read & compress audio frames */
402         if (use_audio) {
403             int ret, nb_samples, nb_samples_out;
404             UINT8 *buftmp;
405
406             for(;;) {
407                 ret = url_read(audio_handle, audio_buf, audio_fifo_size);
408                 if (ret <= 0)
409                     break;
410                 /* fill each codec fifo by doing the right sample
411                    rate conversion. This is not optimal because we
412                    do too much work, but it is easy to do */
413                 nb_samples = ret / (channels * 2);
414                 for(i=0;i<s->nb_streams;i++) {
415                     ost = ost_table[i];
416                     enc = &ost->st->codec;
417                     if (enc->codec_type == CODEC_TYPE_AUDIO) {
418                         /* rate & stereo convertion */
419                         if (!ost->audio_resample) {
420                             buftmp = audio_buf;
421                             nb_samples_out = nb_samples;
422                         } else {
423                             buftmp = audio_buf1;
424                             nb_samples_out = audio_resample(ost->resample, 
425                                                             (short *)buftmp, (short *)audio_buf,
426                                                             nb_samples);
427                         }
428                         fifo_write(&ost->fifo, buftmp, nb_samples_out * enc->channels * 2, 
429                                    &ost->fifo.wptr);
430                     }
431                 }
432                 
433                 /* compress as many frame as possible with each audio codec */
434                 for(i=0;i<s->nb_streams;i++) {
435                     ost = ost_table[i];
436                     enc = &ost->st->codec;
437                     if (enc->codec_type == CODEC_TYPE_AUDIO) {
438                         frame_bytes = enc->frame_size * 2 * enc->channels;
439                         
440                         while (fifo_read(&ost->fifo, audio_buf, 
441                                          frame_bytes, &ost->fifo.rptr) == 0) {
442                             ret = avcodec_encode_audio(enc,
443                                                        audio_out, sizeof(audio_out), 
444                                                        (short *)audio_buf);
445                             s->format->write_packet(s, ost->index, audio_out, ret);
446                         }
447                     }
448                 }
449             }
450         }
451
452         if (use_video) {
453             AVPicture *picture1, *picture2, *picture;
454             AVPicture picture_tmp0, picture_tmp1;
455
456             ret = url_read(video_handle, picture_in_buf, picture_size);
457             if (ret < 0)
458                 break;
459             
460             picture2 = &picture_tmp0;
461             avpicture_fill(picture2, picture_in_buf, pix_fmt, width, height);
462
463             if (pix_fmt != PIX_FMT_YUV420P) {
464                 picture = &picture_tmp1;
465                 img_convert(picture, PIX_FMT_YUV420P,
466                             picture2, pix_fmt, 
467                             width, height);
468             } else {
469                 picture = picture2;
470             }
471             
472             for(i=0;i<s->nb_streams;i++) {
473                 ost = ost_table[i];
474                 enc = &ost->st->codec;
475                 if (enc->codec_type == CODEC_TYPE_VIDEO) {
476                     int n1, n2, nb;
477
478                     /* feed each codec with its requested frame rate */
479                     n1 = ((INT64)frame_number * enc->frame_rate) / frame_rate;
480                     n2 = (((INT64)frame_number + 1) * enc->frame_rate) / frame_rate;
481                     nb = n2 - n1;
482                     if (nb > 0) {
483                         /* resize the picture if needed */
484                         if (ost->video_resample) {
485                             picture1 = &ost->pict_tmp;
486                             img_resample(ost->img_resample_ctx, 
487                                          picture1, picture);
488                         } else {
489                             picture1 = picture;
490                         }
491                         ret = avcodec_encode_video(enc, video_buffer, 
492                                                    sizeof(video_buffer), 
493                                                    picture1);
494                         s->format->write_packet(s, ost->index, video_buffer, ret);
495                     }
496                 }
497             }
498             frame_number++;
499         }
500         
501         /* write report */
502         {
503             char buf[1024];
504             INT64 total_size;
505             float ti, bitrate;
506             static float last_ti;
507             INT64 ti1;
508
509             total_size = url_ftell(&s->pb);
510             ti1 = gettime() - time_start;
511             /* check elapsed time */
512             if (recording_time && ti1 >= recording_time)
513                 break;
514
515             ti = ti1 / 1000000.0;
516             if (ti < 0.1)
517                 ti = 0.1;
518             /* dispaly twice per second */
519             if ((ti - last_ti) >= 0.5) {
520                 last_ti = ti;
521                 bitrate = (int)((total_size * 8) / ti / 1000.0);
522                 
523                 buf[0] = '\0';
524                 if (use_video) {
525                     sprintf(buf + strlen(buf), "frame=%5d fps=%4.1f q=%2d ",
526                             frame_number, (float)frame_number / ti, first_video_enc->quality);
527                 }
528                 
529                 sprintf(buf + strlen(buf), "size=%8LdkB time=%0.1f bitrate=%6.1fkbits/s", 
530                         total_size / 1024, ti, bitrate);
531                 fprintf(stderr, "%s    \r", buf);
532                 fflush(stderr);
533             }
534         }
535     }
536     term_exit();
537
538     for(i=0;i<s->nb_streams;i++) {
539         ost = ost_table[i];
540         enc = &ost->st->codec;
541         avcodec_close(enc);
542     }
543     s->format->write_trailer(s);
544     
545     if (audio_handle)
546         url_close(audio_handle);
547
548     if (video_handle)
549         url_close(video_handle);
550
551     /* write report */
552     {
553         float ti, bitrate;
554         INT64 total_size;
555
556         total_size = url_ftell(&s->pb);
557
558         ti = (gettime() - time_start) / 1000000.0;
559         if (ti < 0.1)
560             ti = 0.1;
561         bitrate = (int)((total_size * 8) / ti / 1000.0);
562
563         fprintf(stderr, "\033[K\nTotal time = %0.1f s, %Ld KBytes, %0.1f kbits/s\n", 
564                 ti, total_size / 1024, bitrate);
565         if (use_video) {
566             fprintf(stderr, "Total frames = %d\n", frame_number);
567         }
568     }
569
570     ret = 0;
571  fail1:
572     if (picture_in_buf)
573         free(picture_in_buf);
574     if (picture_420p)
575         free(picture_420p);
576     for(i=0;i<s->nb_streams;i++) {
577         ost = ost_table[i];
578         if (ost) {
579             if (ost->fifo.buffer)
580                 fifo_free(&ost->fifo);
581             if (ost->pict_tmp.data[0])
582                 free(ost->pict_tmp.data[0]);
583             if (ost->video_resample)
584                 img_resample_close(ost->img_resample_ctx);
585             if (ost->audio_resample)
586                 audio_resample_close(ost->resample);
587             free(ost);
588         }
589     }
590     return ret;
591  fail:
592     ret = -ENOMEM;
593     goto fail1;
594 }
595
596 int read_ffserver_streams(AVFormatContext *s, const char *filename)
597 {
598     int i;
599     AVFormatContext *ic;
600
601     ic = av_open_input_file(filename, FFM_PACKET_SIZE);
602     if (!ic)
603         return -EIO;
604     /* copy stream format */
605     s->nb_streams = ic->nb_streams;
606     for(i=0;i<ic->nb_streams;i++) {
607         AVStream *st;
608         st = av_mallocz(sizeof(AVFormatContext));
609         memcpy(st, ic->streams[i], sizeof(AVStream));
610         s->streams[i] = st;
611     }
612
613     av_close_input_file(ic);
614     return 0;
615 }
616
617 #define MAX_AUDIO_PACKET_SIZE 16384
618
619 static void do_audio_out(AVFormatContext *s, 
620                          AVOutputStream *ost, 
621                          AVInputStream *ist,
622                          unsigned char *buf, int size)
623 {
624     UINT8 *buftmp;
625     UINT8 audio_buf[2*MAX_AUDIO_PACKET_SIZE]; /* XXX: allocate it */
626     UINT8 audio_out[MAX_AUDIO_PACKET_SIZE]; /* XXX: allocate it */
627     int size_out, frame_bytes, ret;
628     AVCodecContext *enc;
629
630     enc = &ost->st->codec;
631
632     if (ost->audio_resample) {
633         buftmp = audio_buf;
634         size_out = audio_resample(ost->resample, 
635                                   (short *)buftmp, (short *)buf,
636                                   size / (ist->st->codec.channels * 2));
637         size_out = size_out * enc->channels * 2;
638     } else {
639         buftmp = buf;
640         size_out = size;
641     }
642
643     /* now encode as many frames as possible */
644     if (enc->codec_id != CODEC_ID_PCM) {
645         /* output resampled raw samples */
646         fifo_write(&ost->fifo, buftmp, size_out, 
647                    &ost->fifo.wptr);
648
649         frame_bytes = enc->frame_size * 2 * enc->channels;
650         
651         while (fifo_read(&ost->fifo, audio_buf, frame_bytes, 
652                      &ost->fifo.rptr) == 0) {
653             ret = avcodec_encode_audio(enc,
654                                        audio_out, sizeof(audio_out), (short *)audio_buf);
655             s->format->write_packet(s, ost->index, audio_out, ret);
656         }
657     } else {
658         /* XXX: handle endianness */
659         s->format->write_packet(s, ost->index, buftmp, size_out);
660     }
661 }
662
663 /* write a picture to a raw mux */
664 static void write_picture(AVFormatContext *s, int index, AVPicture *picture, 
665                           int pix_fmt, int w, int h)
666 {
667     UINT8 *buf, *src, *dest;
668     int size, j, i;
669
670     size = avpicture_get_size(pix_fmt, w, h);
671     buf = malloc(size);
672     if (!buf)
673         return;
674
675     /* XXX: not efficient, should add test if we can take
676        directly the AVPicture */
677     switch(pix_fmt) {
678     case PIX_FMT_YUV420P:
679         dest = buf;
680         for(i=0;i<3;i++) {
681             if (i == 1) {
682                 w >>= 1;
683                 h >>= 1;
684             }
685             src = picture->data[i];
686             for(j=0;j<h;j++) {
687                 memcpy(dest, src, w);
688                 dest += w;
689                 src += picture->linesize[i];
690             }
691         }
692         break;
693     case PIX_FMT_YUV422P:
694         size = (w * h) * 2; 
695         buf = malloc(size);
696         dest = buf;
697         for(i=0;i<3;i++) {
698             if (i == 1) {
699                 w >>= 1;
700             }
701             src = picture->data[i];
702             for(j=0;j<h;j++) {
703                 memcpy(dest, src, w);
704                 dest += w;
705                 src += picture->linesize[i];
706             }
707         }
708         break;
709     case PIX_FMT_YUV444P:
710         size = (w * h) * 3; 
711         buf = malloc(size);
712         dest = buf;
713         for(i=0;i<3;i++) {
714             src = picture->data[i];
715             for(j=0;j<h;j++) {
716                 memcpy(dest, src, w);
717                 dest += w;
718                 src += picture->linesize[i];
719             }
720         }
721         break;
722     case PIX_FMT_YUV422:
723         size = (w * h) * 2; 
724         buf = malloc(size);
725         dest = buf;
726         src = picture->data[0];
727         for(j=0;j<h;j++) {
728             memcpy(dest, src, w * 2);
729             dest += w * 2;
730             src += picture->linesize[0];
731         }
732         break;
733     case PIX_FMT_RGB24:
734     case PIX_FMT_BGR24:
735         size = (w * h) * 3; 
736         buf = malloc(size);
737         dest = buf;
738         src = picture->data[0];
739         for(j=0;j<h;j++) {
740             memcpy(dest, src, w * 3);
741             dest += w * 3;
742             src += picture->linesize[0];
743         }
744         break;
745     default:
746         return;
747     }
748     s->format->write_packet(s, index, buf, size);
749     free(buf);
750 }
751
752
753 static void do_video_out(AVFormatContext *s, 
754                          AVOutputStream *ost, 
755                          AVInputStream *ist,
756                          AVPicture *picture1)
757 {
758     int n1, n2, nb, i, ret, frame_number;
759     AVPicture *picture, *picture2, *pict;
760     AVPicture picture_tmp1, picture_tmp2;
761     UINT8 video_buffer[128*1024];
762     UINT8 *buf = NULL, *buf1 = NULL;
763     AVCodecContext *enc, *dec;
764
765     enc = &ost->st->codec;
766     dec = &ist->st->codec;
767
768     frame_number = ist->frame_number;
769     /* first drop frame if needed */
770     n1 = ((INT64)frame_number * enc->frame_rate) / dec->frame_rate;
771     n2 = (((INT64)frame_number + 1) * enc->frame_rate) / dec->frame_rate;
772     nb = n2 - n1;
773     if (nb <= 0)
774         return;
775     
776     /* deinterlace : must be done before any resize */
777     if (do_deinterlace) {
778         int size;
779
780         /* create temporary picture */
781         size = avpicture_get_size(dec->pix_fmt, dec->width, dec->height);
782         buf1 = malloc(size);
783         if (!buf1)
784             return;
785         
786         picture2 = &picture_tmp2;
787         avpicture_fill(picture2, buf1, dec->pix_fmt, dec->width, dec->height);
788
789         if (avpicture_deinterlace(picture2, picture1, 
790                                   dec->pix_fmt, dec->width, dec->height) < 0) {
791             /* if error, do not deinterlace */
792             free(buf1);
793             buf1 = NULL;
794             picture2 = picture1;
795         }
796     } else {
797         picture2 = picture1;
798     }
799
800     /* convert pixel format if needed */
801     if (enc->pix_fmt != dec->pix_fmt) {
802         int size;
803
804         /* create temporary picture */
805         size = avpicture_get_size(enc->pix_fmt, dec->width, dec->height);
806         buf = malloc(size);
807         if (!buf)
808             return;
809         pict = &picture_tmp1;
810         avpicture_fill(pict, buf, enc->pix_fmt, dec->width, dec->height);
811         
812         if (img_convert(pict, enc->pix_fmt, 
813                         picture2, dec->pix_fmt, 
814                         dec->width, dec->height) < 0) {
815             fprintf(stderr, "pixel format conversion not handled\n");
816             goto the_end;
817         }
818     } else {
819         pict = picture2;
820     }
821
822     /* XXX: resampling could be done before raw format convertion in
823        some cases to go faster */
824     /* XXX: only works for YUV420P */
825     if (ost->video_resample) {
826         picture = &ost->pict_tmp;
827         img_resample(ost->img_resample_ctx, picture, pict);
828     } else {
829         picture = pict;
830     }
831
832     /* duplicates frame if needed */
833     /* XXX: pb because no interleaving */
834     for(i=0;i<nb;i++) {
835         if (enc->codec_id != CODEC_ID_RAWVIDEO) {
836             /* handles sameq here. This is not correct because it may
837                not be a global option */
838             if (same_quality) {
839                 enc->quality = dec->quality;
840             }
841             ret = avcodec_encode_video(enc, 
842                                        video_buffer, sizeof(video_buffer), 
843                                        picture);
844             s->format->write_packet(s, ost->index, video_buffer, ret);
845         } else {
846             write_picture(s, ost->index, picture, enc->pix_fmt, enc->width, enc->height);
847         }
848     }
849     the_end:
850     if (buf)
851         free(buf);
852     if (buf1)
853         free(buf1);
854 }
855
856 //#define HEX_DUMP
857
858 #ifdef HEX_DUMP
859 static void hex_dump(UINT8 *buf, int size)
860 {
861     int len, i, j, c;
862
863     for(i=0;i<size;i+=16) {
864         len = size - i;
865         if (len > 16)
866             len = 16;
867         printf("%08x ", i);
868         for(j=0;j<16;j++) {
869             if (j < len)
870                 printf(" %02x", buf[i+j]);
871             else
872                 printf("   ");
873         }
874         printf(" ");
875         for(j=0;j<len;j++) {
876             c = buf[i+j];
877             if (c < ' ' || c > '~')
878                 c = '.';
879             printf("%c", c);
880         }
881         printf("\n");
882     }
883 }
884 #endif
885
886 /*
887  * The following code is the main loop of the file converter
888  */
889 static int av_encode(AVFormatContext **output_files,
890                      int nb_output_files,
891                      AVFormatContext **input_files,
892                      int nb_input_files,
893                      AVStreamMap *stream_maps, int nb_stream_maps)
894 {
895     int ret, i, j, k, n, nb_istreams, nb_ostreams = 0;
896     AVFormatContext *is, *os;
897     AVCodecContext *codec, *icodec;
898     AVOutputStream *ost, **ost_table = NULL;
899     AVInputStream *ist, **ist_table = NULL;
900     INT64 min_pts, start_time;
901     AVInputFile file_table[nb_input_files];
902
903     memset(file_table, 0, sizeof(file_table));
904     
905     /* input stream init */
906     j = 0;
907     for(i=0;i<nb_input_files;i++) {
908         is = input_files[i];
909         file_table[i].ist_index = j;
910         j += is->nb_streams;
911     }
912     nb_istreams = j;
913
914     ist_table = av_mallocz(nb_istreams * sizeof(AVInputStream *));
915     if (!ist_table)
916         return -ENOMEM;
917     
918     for(i=0;i<nb_istreams;i++) {
919         ist = av_mallocz(sizeof(AVInputStream));
920         if (!ist)
921             goto fail;
922         ist_table[i] = ist;
923     }
924     j = 0;
925     for(i=0;i<nb_input_files;i++) {
926         is = input_files[i];
927         for(k=0;k<is->nb_streams;k++) {
928             ist = ist_table[j++];
929             ist->st = is->streams[k];
930             ist->file_index = i;
931             ist->index = k;
932             ist->discard = 1; /* the stream is discarded by default
933                                  (changed later) */
934         }
935     }
936
937     /* output stream init */
938     nb_ostreams = 0;
939     for(i=0;i<nb_output_files;i++) {
940         os = output_files[i];
941         nb_ostreams += os->nb_streams;
942     }
943     if (nb_stream_maps > 0 && nb_stream_maps != nb_ostreams) {
944         fprintf(stderr, "Number of stream maps must match number of output streams\n");
945         exit(1);
946     }
947
948     ost_table = av_mallocz(sizeof(AVOutputStream *) * nb_ostreams);
949     if (!ost_table)
950         goto fail;
951     for(i=0;i<nb_ostreams;i++) {
952         ost = av_mallocz(sizeof(AVOutputStream));
953         if (!ost)
954             goto fail;
955         ost_table[i] = ost;
956     }
957     
958     n = 0;
959     for(k=0;k<nb_output_files;k++) {
960         os = output_files[k];
961         for(i=0;i<os->nb_streams;i++) {
962             int found;
963             ost = ost_table[n++];
964             ost->file_index = k;
965             ost->index = i;
966             ost->st = os->streams[i];
967             if (nb_stream_maps > 0) {
968                 ost->source_index = file_table[stream_maps[n-1].file_index].ist_index + 
969                     stream_maps[n-1].stream_index;
970             } else {
971                 /* get corresponding input stream index : we select the first one with the right type */
972                 found = 0;
973                 for(j=0;j<nb_istreams;j++) {
974                     ist = ist_table[j];
975                     if (ist->discard && 
976                         ist->st->codec.codec_type == ost->st->codec.codec_type) {
977                         ost->source_index = j;
978                         found = 1;
979                     }
980                 }
981                 
982                 if (!found) {
983                     /* try again and reuse existing stream */
984                     for(j=0;j<nb_istreams;j++) {
985                         ist = ist_table[j];
986                         if (ist->st->codec.codec_type == ost->st->codec.codec_type) {
987                             ost->source_index = j;
988                             found = 1;
989                         }
990                     }
991                     if (!found) {
992                         fprintf(stderr, "Could not find input stream matching output stream #%d.%d\n",
993                                 ost->file_index, ost->index);
994                         exit(1);
995                     }
996                 }
997             }
998             ist = ist_table[ost->source_index];
999             ist->discard = 0;
1000         }
1001     }
1002
1003     /* dump the stream mapping */
1004     fprintf(stderr, "Stream mapping:\n");
1005     for(i=0;i<nb_ostreams;i++) {
1006         ost = ost_table[i];
1007         fprintf(stderr, "  Stream #%d.%d -> #%d.%d\n",
1008                 ist_table[ost->source_index]->file_index,
1009                 ist_table[ost->source_index]->index,
1010                 ost->file_index, 
1011                 ost->index);
1012     }
1013
1014     /* for each output stream, we compute the right encoding parameters */
1015     for(i=0;i<nb_ostreams;i++) {
1016         ost = ost_table[i];
1017         ist = ist_table[ost->source_index];
1018
1019         codec = &ost->st->codec;
1020         icodec = &ist->st->codec;
1021
1022         switch(codec->codec_type) {
1023         case CODEC_TYPE_AUDIO:
1024             /* check if same codec with same parameters. If so, no
1025                reencoding is needed */
1026             if (codec->codec_id == icodec->codec_id &&
1027                 codec->bit_rate == icodec->bit_rate &&
1028                 codec->sample_rate == icodec->sample_rate &&
1029                 codec->channels == icodec->channels) {
1030                 /* no reencoding */
1031             } else {
1032                 if (fifo_init(&ost->fifo, 2 * MAX_AUDIO_PACKET_SIZE))
1033                     goto fail;
1034
1035                 if (codec->channels == icodec->channels &&
1036                     codec->sample_rate == icodec->sample_rate) {
1037                     ost->audio_resample = 0;
1038                 } else {
1039                     ost->audio_resample = 1;
1040                     ost->resample = audio_resample_init(codec->channels, icodec->channels,
1041                                                         codec->sample_rate, 
1042                                                         icodec->sample_rate);
1043                 }
1044                 ist->decoding_needed = 1;
1045                 ost->encoding_needed = 1;
1046             }
1047             break;
1048         case CODEC_TYPE_VIDEO:
1049             /* check if same codec with same parameters. If so, no
1050                reencoding is needed */
1051             if (codec->codec_id == icodec->codec_id &&
1052                 codec->bit_rate == icodec->bit_rate &&
1053                 codec->frame_rate == icodec->frame_rate &&
1054                 codec->width == icodec->width &&
1055                 codec->height == icodec->height) {
1056                 /* no reencoding */
1057             } else {
1058                 if (codec->width == icodec->width &&
1059                     codec->height == icodec->height) {
1060                     ost->video_resample = 0;
1061                 } else {
1062                     UINT8 *buf;
1063                     ost->video_resample = 1;
1064                     buf = malloc((codec->width * codec->height * 3) / 2);
1065                     if (!buf)
1066                         goto fail;
1067                     ost->pict_tmp.data[0] = buf;
1068                     ost->pict_tmp.data[1] = ost->pict_tmp.data[0] + (codec->width * codec->height);
1069                     ost->pict_tmp.data[2] = ost->pict_tmp.data[1] + (codec->width * codec->height) / 4;
1070                     ost->pict_tmp.linesize[0] = codec->width;
1071                     ost->pict_tmp.linesize[1] = codec->width / 2;
1072                     ost->pict_tmp.linesize[2] = codec->width / 2;
1073
1074                     ost->img_resample_ctx = img_resample_init( 
1075                                       ost->st->codec.width, ost->st->codec.height,
1076                                       ist->st->codec.width, ist->st->codec.height);
1077                 }
1078                 ost->encoding_needed = 1;
1079                 ist->decoding_needed = 1;
1080             }
1081             break;
1082         }
1083     }
1084
1085     /* open each encoder */
1086     for(i=0;i<nb_ostreams;i++) {
1087         ost = ost_table[i];
1088         if (ost->encoding_needed) {
1089             AVCodec *codec;
1090             codec = avcodec_find_encoder(ost->st->codec.codec_id);
1091             if (!codec) {
1092                 fprintf(stderr, "Unsupported codec for output stream #%d.%d\n", 
1093                         ost->file_index, ost->index);
1094                 exit(1);
1095             }
1096             if (avcodec_open(&ost->st->codec, codec) < 0) {
1097                 fprintf(stderr, "Error while opening codec for stream #%d.%d - maybe incorrect parameters such as bit_rate, rate, width or height\n", 
1098                         ost->file_index, ost->index);
1099                 exit(1);
1100             }
1101         }
1102     }
1103
1104     /* open each decoder */
1105     for(i=0;i<nb_istreams;i++) {
1106         ist = ist_table[i];
1107         if (ist->decoding_needed) {
1108             AVCodec *codec;
1109             codec = avcodec_find_decoder(ist->st->codec.codec_id);
1110             if (!codec) {
1111                 fprintf(stderr, "Unsupported codec for input stream #%d.%d\n", 
1112                         ist->file_index, ist->index);
1113                 exit(1);
1114             }
1115             if (avcodec_open(&ist->st->codec, codec) < 0) {
1116                 fprintf(stderr, "Error while opening codec for input stream #%d.%d\n", 
1117                         ist->file_index, ist->index);
1118                 exit(1);
1119             }
1120         }
1121     }
1122
1123     /* init pts */
1124     for(i=0;i<nb_istreams;i++) {
1125         ist = ist_table[i];
1126         ist->pts = 0;
1127         ist->frame_number = 0;
1128     }
1129     
1130     /* compute buffer size max (should use a complete heuristic) */
1131     for(i=0;i<nb_input_files;i++) {
1132         file_table[i].buffer_size_max = 2048;
1133     }
1134
1135     /* open files and write file headers */
1136     for(i=0;i<nb_output_files;i++) {
1137         os = output_files[i];
1138         os->format->write_header(os);
1139     }
1140
1141     start_time = gettime();
1142     min_pts = 0;
1143     for(;;) {
1144         int file_index, ist_index;
1145         AVPacket pkt;
1146         UINT8 *ptr;
1147         int len;
1148         UINT8 *data_buf;
1149         int data_size, got_picture;
1150         AVPicture picture;
1151         short samples[AVCODEC_MAX_AUDIO_FRAME_SIZE / 2];
1152
1153         /* select the input file with the smallest pts */
1154     redo:
1155         file_index = -1;
1156         min_pts = (1ULL << 63) - 1;
1157         for(i=0;i<nb_istreams;i++) {
1158             ist = ist_table[i];
1159             if (!ist->discard && !file_table[ist->file_index].eof_reached && ist->pts < min_pts) {
1160                 min_pts = ist->pts;
1161                 file_index = ist->file_index;
1162             }
1163         }
1164         /* if none, if is finished */
1165         if (file_index < 0)
1166             break;
1167         /* finish if recording time exhausted */
1168         if (recording_time > 0 && min_pts >= recording_time)
1169             break;
1170         /* read a packet from it and output it in the fifo */
1171         
1172         is = input_files[file_index];
1173         if (av_read_packet(is, &pkt) < 0) {
1174             file_table[file_index].eof_reached = 1;
1175             continue;
1176         }
1177         ist_index = file_table[file_index].ist_index + pkt.stream_index;
1178         ist = ist_table[ist_index];
1179         if (ist->discard) {
1180             continue;
1181         }
1182
1183 #ifdef HEX_DUMP
1184         printf("stream #%d, size=%d:\n", pkt.stream_index, pkt.size);
1185         hex_dump(pkt.data, pkt.size);
1186 #endif
1187
1188         //        printf("read #%d.%d size=%d\n", ist->file_index, ist->index, pkt.size);
1189
1190         len = pkt.size;
1191         ptr = pkt.data;
1192         while (len > 0) {
1193
1194             /* decode the packet if needed */
1195             data_buf = NULL; /* fail safe */
1196             data_size = 0;
1197             if (ist->decoding_needed) {
1198                 switch(ist->st->codec.codec_type) {
1199                 case CODEC_TYPE_AUDIO:
1200                     if (ist->st->codec.codec_id == CODEC_ID_PCM) {
1201                         /* no need to call a codec */
1202                         data_buf = ptr;
1203                         data_size = len;
1204                         ret = len;
1205                     } else {
1206                         ret = avcodec_decode_audio(&ist->st->codec, samples, &data_size,
1207                                                    ptr, len);
1208                         if (ret < 0)
1209                             goto fail_decode;
1210                         if (data_size == 0) {
1211                             /* no audio frame */
1212                             ptr += ret;
1213                             len -= ret;
1214                             continue;
1215                         }
1216                         data_buf = (UINT8 *)samples;
1217                     }
1218                     break;
1219                 case CODEC_TYPE_VIDEO:
1220                     if (ist->st->codec.codec_id == CODEC_ID_RAWVIDEO) {
1221                         int size;
1222                         size = (ist->st->codec.width * ist->st->codec.height);
1223                         avpicture_fill(&picture, ptr, 
1224                                      ist->st->codec.pix_fmt,
1225                                      ist->st->codec.width,
1226                                      ist->st->codec.height);
1227                         ret = len;
1228                     } else {
1229                         data_size = (ist->st->codec.width * ist->st->codec.height * 3) / 2;
1230                         ret = avcodec_decode_video(&ist->st->codec, 
1231                                                    &picture, &got_picture, ptr, len);
1232                         if (ret < 0) {
1233                         fail_decode:
1234                             fprintf(stderr, "Error while decoding stream #%d.%d\n",
1235                                     ist->file_index, ist->index);
1236                             av_free_packet(&pkt);
1237                             goto redo;
1238                         }
1239                         if (!got_picture) {
1240                             /* no picture yet */
1241                             ptr += ret;
1242                             len -= ret;
1243                             continue;
1244                         }
1245                     }
1246                     break;
1247                 default:
1248                     goto fail_decode;
1249                 }
1250             } else {
1251                 data_buf = ptr;
1252                 data_size = len;
1253                 ret = len;
1254             }
1255             /* update pts */
1256             switch(ist->st->codec.codec_type) {
1257             case CODEC_TYPE_AUDIO:
1258                 ist->pts = (INT64)1000000 * ist->sample_index / ist->st->codec.sample_rate;
1259                 ist->sample_index += data_size / (2 * ist->st->codec.channels);
1260                 break;
1261             case CODEC_TYPE_VIDEO:
1262                 ist->frame_number++;
1263                 ist->pts = ((INT64)ist->frame_number * 1000000 * FRAME_RATE_BASE) / 
1264                     ist->st->codec.frame_rate;
1265                 break;
1266             }
1267             ptr += ret;
1268             len -= ret;
1269
1270             /* transcode raw format, encode packets and output them */
1271             
1272             for(i=0;i<nb_ostreams;i++) {
1273                 ost = ost_table[i];
1274                 if (ost->source_index == ist_index) {
1275                     os = output_files[ost->file_index];
1276
1277                     if (ost->encoding_needed) {
1278                         switch(ost->st->codec.codec_type) {
1279                         case CODEC_TYPE_AUDIO:
1280                             do_audio_out(os, ost, ist, data_buf, data_size);
1281                             break;
1282                         case CODEC_TYPE_VIDEO:
1283                             do_video_out(os, ost, ist, &picture);
1284                             break;
1285                         }
1286                     } else {
1287                         /* no reencoding needed : output the packet directly */
1288                         os->format->write_packet(os, ost->index, data_buf, data_size);
1289                     }
1290                 }
1291             }
1292         }
1293         av_free_packet(&pkt);
1294         
1295         /* dump report by using the first video and audio streams */
1296         {
1297             char buf[1024];
1298             AVFormatContext *oc;
1299             INT64 total_size, ti;
1300             AVCodecContext *enc;
1301             int frame_number, vid;
1302             double bitrate, ti1;
1303             static INT64 last_time;
1304
1305             if ((min_pts - last_time) >= 500000) {
1306                 last_time = min_pts;
1307                 
1308                 oc = output_files[0];
1309                 
1310                 total_size = url_ftell(&oc->pb);
1311                 
1312                 buf[0] = '\0';
1313                 ti = (1ULL << 63) - 1;
1314                 vid = 0;
1315                 for(i=0;i<nb_ostreams;i++) {
1316                     ost = ost_table[i];
1317                     enc = &ost->st->codec;
1318                     ist = ist_table[ost->source_index];
1319                     if (!vid && enc->codec_type == CODEC_TYPE_VIDEO) {
1320                         frame_number = ist->frame_number;
1321                         sprintf(buf + strlen(buf), "frame=%5d q=%2d ",
1322                                 frame_number, enc->quality);
1323                         vid = 1;
1324                     }
1325                     /* compute min pts value */
1326                     if (!ist->discard && ist->pts < ti) {
1327                         ti = ist->pts;
1328                     }
1329                 }
1330
1331                 ti1 = ti / 1000000.0;
1332                 if (ti1 < 0.1)
1333                     ti1 = 0.1;
1334                 bitrate = (double)(total_size * 8) / ti1 / 1000.0;
1335
1336                 sprintf(buf + strlen(buf), "size=%8LdkB time=%0.1f bitrate=%6.1fkbits/s", 
1337                         total_size / 1024, ti1, bitrate);
1338                 
1339                 fprintf(stderr, "%s    \r", buf);
1340                 fflush(stderr);
1341             }
1342         }
1343     }
1344
1345     /* dump report by using the first video and audio streams */
1346     {
1347         char buf[1024];
1348         AVFormatContext *oc;
1349         INT64 total_size, ti;
1350         AVCodecContext *enc;
1351         int frame_number, vid;
1352         double bitrate, ti1;
1353
1354         oc = output_files[0];
1355         
1356         total_size = url_ftell(&oc->pb);
1357         
1358         buf[0] = '\0';
1359         ti = (1ULL << 63) - 1;
1360         vid = 0;
1361         for(i=0;i<nb_ostreams;i++) {
1362             ost = ost_table[i];
1363             enc = &ost->st->codec;
1364             ist = ist_table[ost->source_index];
1365             if (!vid && enc->codec_type == CODEC_TYPE_VIDEO) {
1366                 frame_number = ist->frame_number;
1367                 sprintf(buf + strlen(buf), "frame=%5d q=%2d ",
1368                         frame_number, enc->quality);
1369                 vid = 1;
1370             }
1371             /* compute min pts value */
1372             if (!ist->discard && ist->pts < ti) {
1373                 ti = ist->pts;
1374             }
1375         }
1376         
1377         ti1 = ti / 1000000.0;
1378         if (ti1 < 0.1)
1379             ti1 = 0.1;
1380         bitrate = (double)(total_size * 8) / ti1 / 1000.0;
1381         
1382         sprintf(buf + strlen(buf), "size=%8LdkB time=%0.1f bitrate=%6.1fkbits/s", 
1383                 total_size / 1024, ti1, bitrate);
1384         
1385         fprintf(stderr, "%s    \n", buf);
1386     }
1387     /* close each encoder */
1388     for(i=0;i<nb_ostreams;i++) {
1389         ost = ost_table[i];
1390         if (ost->encoding_needed) {
1391             avcodec_close(&ost->st->codec);
1392         }
1393     }
1394     
1395     /* close each decoder */
1396     for(i=0;i<nb_istreams;i++) {
1397         ist = ist_table[i];
1398         if (ist->decoding_needed) {
1399             avcodec_close(&ist->st->codec);
1400         }
1401     }
1402     
1403
1404     /* write the trailer if needed and close file */
1405     for(i=0;i<nb_output_files;i++) {
1406         os = output_files[i];
1407         os->format->write_trailer(os);
1408     }
1409     /* finished ! */
1410     
1411     ret = 0;
1412  fail1:
1413     if (ist_table) {
1414         for(i=0;i<nb_istreams;i++) {
1415             ist = ist_table[i];
1416             if (ist) {
1417                 free(ist);
1418             }
1419         }
1420         free(ist_table);
1421     }
1422     if (ost_table) {
1423         for(i=0;i<nb_ostreams;i++) {
1424             ost = ost_table[i];
1425             if (ost) {
1426                 if (ost->pict_tmp.data[0])
1427                     free(ost->pict_tmp.data[0]);
1428                 if (ost->video_resample)
1429                     img_resample_close(ost->img_resample_ctx);
1430                 if (ost->audio_resample)
1431                     audio_resample_close(ost->resample);
1432                 free(ost);
1433             }
1434         }
1435         free(ost_table);
1436     }
1437     return ret;
1438  fail:
1439     ret = -ENOMEM;
1440     goto fail1;
1441 }
1442
1443 #if 0
1444 int file_read(const char *filename)
1445 {
1446     URLContext *h;
1447     unsigned char buffer[1024];
1448     int len, i;
1449
1450     if (url_open(&h, filename, O_RDONLY) < 0) {
1451         printf("could not open '%s'\n", filename);
1452         return -1;
1453     }
1454     for(;;) {
1455         len = url_read(h, buffer, sizeof(buffer));
1456         if (len <= 0)
1457             break;
1458         for(i=0;i<len;i++) putchar(buffer[i]);
1459     }
1460     url_close(h);
1461     return 0;
1462 }
1463 #endif
1464
1465 void show_licence(void)
1466 {
1467     printf(
1468     "ffmpeg version " FFMPEG_VERSION "\n"
1469     "Copyright (c) 2000,2001 Gerard Lantau\n"
1470     "This program is free software; you can redistribute it and/or modify\n"
1471     "it under the terms of the GNU General Public License as published by\n"
1472     "the Free Software Foundation; either version 2 of the License, or\n"
1473     "(at your option) any later version.\n"
1474     "\n"
1475     "This program is distributed in the hope that it will be useful,\n"
1476     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
1477     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
1478     "GNU General Public License for more details.\n"
1479     "\n"
1480     "You should have received a copy of the GNU General Public License\n"
1481     "along with this program; if not, write to the Free Software\n"
1482     "Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n"
1483     );
1484     exit(1);
1485 }
1486
1487 void opt_format(const char *arg)
1488 {
1489     AVFormat *f;
1490     f = first_format;
1491     while (f != NULL && strcmp(f->name, arg) != 0) f = f->next;
1492     if (f == NULL) {
1493         fprintf(stderr, "Invalid format: %s\n", arg);
1494         exit(1);
1495     }
1496     file_format = f;
1497 }
1498
1499 void opt_video_bitrate(const char *arg)
1500 {
1501     video_bit_rate = atoi(arg) * 1000;
1502 }
1503
1504 void opt_frame_rate(const char *arg)
1505 {
1506     frame_rate = (int)(strtod(arg, 0) * FRAME_RATE_BASE);
1507 }
1508
1509 void opt_frame_size(const char *arg)
1510 {
1511     parse_image_size(&frame_width, &frame_height, arg);
1512     if (frame_width <= 0 || frame_height <= 0) {
1513         fprintf(stderr, "Incorrect frame size\n");
1514         exit(1);
1515     }
1516     if ((frame_width % 2) != 0 || (frame_height % 2) != 0) {
1517         fprintf(stderr, "Frame size must be a multiple of 2\n");
1518         exit(1);
1519     }
1520 }
1521
1522 void opt_gop_size(const char *arg)
1523 {
1524     gop_size = atoi(arg);
1525 }
1526
1527 void opt_qscale(const char *arg)
1528 {
1529     video_qscale = atoi(arg);
1530     if (video_qscale < 0 ||
1531         video_qscale > 31) {
1532         fprintf(stderr, "qscale must be >= 1 and <= 31\n");
1533         exit(1);
1534     }
1535 }
1536
1537
1538 void opt_audio_bitrate(const char *arg)
1539 {
1540     audio_bit_rate = atoi(arg) * 1000;
1541 }
1542
1543 void opt_audio_rate(const char *arg)
1544 {
1545     audio_sample_rate = atoi(arg);
1546 }
1547
1548 void opt_audio_channels(const char *arg)
1549 {
1550     audio_channels = atoi(arg);
1551 }
1552
1553 void opt_video_device(const char *arg)
1554 {
1555     v4l_device = strdup(arg);
1556 }
1557
1558 void opt_audio_device(const char *arg)
1559 {
1560     audio_device = strdup(arg);
1561 }
1562
1563 void opt_audio_codec(const char *arg)
1564 {
1565     AVCodec *p;
1566
1567     p = first_avcodec;
1568     while (p) {
1569         if (!strcmp(p->name, arg) && p->type == CODEC_TYPE_AUDIO)
1570             break;
1571         p = p->next;
1572     }
1573     if (p == NULL) {
1574         fprintf(stderr, "Unknown audio codec '%s'\n", arg);
1575         exit(1);
1576     } else {
1577         audio_codec_id = p->id;
1578     }
1579 }
1580
1581 const char *motion_str[] = {
1582     "zero",
1583     "full",
1584     "log",
1585     "phods",
1586     NULL,
1587 };
1588
1589 void opt_motion_estimation(const char *arg)
1590 {
1591     const char **p;
1592     p = motion_str;
1593     for(;;) {
1594         if (!*p) {
1595             fprintf(stderr, "Unknown motion estimation method '%s'\n", arg);
1596             exit(1);
1597         }
1598         if (!strcmp(*p, arg))
1599             break;
1600         p++;
1601     }
1602     motion_estimation_method = p - motion_str;
1603 }
1604
1605 void opt_video_codec(const char *arg)
1606 {
1607     AVCodec *p;
1608
1609     p = first_avcodec;
1610     while (p) {
1611         if (!strcmp(p->name, arg) && p->type == CODEC_TYPE_VIDEO)
1612             break;
1613         p = p->next;
1614     }
1615     if (p == NULL) {
1616         fprintf(stderr, "Unknown video codec '%s'\n", arg);
1617         exit(1);
1618     } else {
1619         video_codec_id = p->id;
1620     }
1621 }
1622
1623 void opt_map(const char *arg)
1624 {
1625     AVStreamMap *m;
1626     const char *p;
1627
1628     p = arg;
1629     m = &stream_maps[nb_stream_maps++];
1630
1631     m->file_index = strtol(arg, (char **)&p, 0);
1632     if (*p)
1633         p++;
1634     m->stream_index = strtol(arg, (char **)&p, 0);
1635 }
1636
1637 void opt_recording_time(const char *arg)
1638 {
1639     recording_time = parse_date(arg, 1);
1640 }
1641
1642 /* return the number of packet read to find the codec parameters */
1643 int find_codec_parameters(AVFormatContext *ic)
1644 {
1645     int val, i, count, ret, got_picture, size;
1646     AVCodec *codec;
1647     AVCodecContext *enc;
1648     AVStream *st;
1649     AVPacket *pkt;
1650     AVPicture picture;
1651     AVPacketList *pktl, **ppktl;
1652     short samples[AVCODEC_MAX_AUDIO_FRAME_SIZE / 2];
1653     UINT8 *ptr;
1654
1655     count = 0;
1656     ppktl = &ic->packet_buffer;
1657     for(;;) {
1658         for(i=0;i<ic->nb_streams;i++) {
1659             enc = &ic->streams[i]->codec;
1660             
1661             switch(enc->codec_type) {
1662             case CODEC_TYPE_AUDIO:
1663                 val = enc->sample_rate;
1664                 break;
1665             case CODEC_TYPE_VIDEO:
1666                 val = enc->width;
1667                 break;
1668             default:
1669                 val = 1;
1670                 break;
1671             }
1672             /* if no parameters supplied, then we should read it from
1673                the stream */
1674             if (val == 0)
1675                 break;
1676         }
1677         if (i == ic->nb_streams) {
1678             ret = count;
1679             break;
1680         }
1681
1682         if (count == 0) {
1683             /* open each codec */
1684             for(i=0;i<ic->nb_streams;i++) {
1685                 st = ic->streams[i];
1686                 codec = avcodec_find_decoder(st->codec.codec_id);
1687                 if (codec == NULL) {
1688                     ret = -1;
1689                     goto the_end;
1690                 }
1691                 avcodec_open(&st->codec, codec);
1692             }
1693         }
1694         pktl = av_mallocz(sizeof(AVPacketList));
1695         if (!pktl) {
1696             ret = -1;
1697             break;
1698         }
1699
1700         /* add the packet in the buffered packet list */
1701         *ppktl = pktl;
1702         ppktl = &pktl->next;
1703
1704         pkt = &pktl->pkt;
1705         if (ic->format->read_packet(ic, pkt) < 0) {
1706             ret = -1;
1707             break;
1708         }
1709         st = ic->streams[pkt->stream_index];
1710
1711         /* decode the data and update codec parameters */
1712         ptr = pkt->data;
1713         size = pkt->size;
1714         while (size > 0) {
1715             switch(st->codec.codec_type) {
1716             case CODEC_TYPE_VIDEO:
1717                 ret = avcodec_decode_video(&st->codec, &picture, &got_picture, ptr, size);
1718                 break;
1719             case CODEC_TYPE_AUDIO:
1720                 ret = avcodec_decode_audio(&st->codec, samples, &got_picture, ptr, size);
1721                 break;
1722             default:
1723                 ret = -1;
1724                 break;
1725             }
1726             if (ret < 0) {
1727                 ret = -1;
1728                 goto the_end;
1729             }
1730             if (got_picture)
1731                 break;
1732             ptr += ret;
1733             size -= ret;
1734         }
1735
1736         count++;
1737     }
1738  the_end:
1739     if (count > 0) {
1740         /* close each codec */
1741         for(i=0;i<ic->nb_streams;i++) {
1742             st = ic->streams[i];
1743             avcodec_close(&st->codec);
1744         }
1745     }
1746     return ret;
1747 }
1748
1749
1750 void opt_input_file(const char *filename)
1751 {
1752     AVFormatContext *ic;
1753     AVFormatParameters params, *ap = &params;
1754     URLFormat url_format;
1755     AVFormat *fmt;
1756     int err, i, ret;
1757
1758     ic = av_mallocz(sizeof(AVFormatContext));
1759     strcpy(ic->filename, filename);
1760     /* first format guess to know if we must open file */
1761     fmt = file_format;
1762     if (!fmt) 
1763         fmt = guess_format(NULL, filename, NULL);
1764     
1765     if (fmt == NULL || !(fmt->flags & AVFMT_NOFILE)) {
1766         /* open file */
1767         if (url_fopen(&ic->pb, filename, URL_RDONLY) < 0) {
1768             fprintf(stderr, "Could not open '%s'\n", filename);
1769             exit(1);
1770         }
1771     
1772         /* find format and set default parameters */
1773         fmt = file_format;
1774         err = url_getformat(url_fileno(&ic->pb), &url_format);
1775         if (err >= 0) {
1776             if (!fmt)
1777                 fmt = guess_format(url_format.format_name, NULL, NULL);
1778             ap->sample_rate = url_format.sample_rate;
1779             ap->frame_rate = url_format.frame_rate;
1780             ap->channels = url_format.channels;
1781             ap->width = url_format.width;
1782             ap->height = url_format.height;
1783             ap->pix_fmt = url_format.pix_fmt;
1784         } else {
1785             if (!fmt)
1786                 fmt = guess_format(NULL, filename, NULL);
1787             memset(ap, 0, sizeof(*ap));
1788         }
1789     } else {
1790         memset(ap, 0, sizeof(*ap));
1791     }
1792
1793     if (!fmt || !fmt->read_header) {
1794         fprintf(stderr, "%s: Unknown file format\n", filename);
1795         exit(1);
1796     }
1797     ic->format = fmt;
1798
1799     /* get default parameters from command line */
1800     if (!ap->sample_rate)
1801         ap->sample_rate = audio_sample_rate;
1802     if (!ap->channels)
1803         ap->channels = audio_channels;
1804
1805     if (!ap->frame_rate)
1806         ap->frame_rate = frame_rate;
1807     if (!ap->width)
1808         ap->width = frame_width;
1809     if (!ap->height)
1810         ap->height = frame_height;
1811     
1812     err = ic->format->read_header(ic, ap);
1813     if (err < 0) {
1814         fprintf(stderr, "%s: Error while parsing header\n", filename);
1815         exit(1);
1816     }
1817     
1818     /* If not enough info for the codecs, we decode the first frames
1819        to get it. (used in mpeg case for example) */
1820     ret = find_codec_parameters(ic);
1821     if (ret < 0) {
1822         fprintf(stderr, "%s: could not find codec parameters\n", filename);
1823         exit(1);
1824     }
1825
1826     /* update the current parameters so that they match the one of the input stream */
1827     for(i=0;i<ic->nb_streams;i++) {
1828         AVCodecContext *enc = &ic->streams[i]->codec;
1829         switch(enc->codec_type) {
1830         case CODEC_TYPE_AUDIO:
1831             audio_channels = enc->channels;
1832             audio_sample_rate = enc->sample_rate;
1833             break;
1834         case CODEC_TYPE_VIDEO:
1835             frame_height = enc->height;
1836             frame_width = enc->width;
1837             frame_rate = enc->frame_rate;
1838             break;
1839         }
1840     }
1841     
1842     input_files[nb_input_files] = ic;
1843     /* dump the file content */
1844     dump_format(ic, nb_input_files, filename, 0);
1845     nb_input_files++;
1846     file_format = NULL;
1847 }
1848
1849 void opt_output_file(const char *filename)
1850 {
1851     AVStream *st;
1852     AVFormatContext *oc;
1853     int use_video, use_audio, nb_streams;
1854     int codec_id;
1855
1856     if (!strcmp(filename, "-"))
1857         filename = "pipe:";
1858
1859     oc = av_mallocz(sizeof(AVFormatContext));
1860
1861     if (!file_format) {
1862         file_format = guess_format(NULL, filename, NULL);
1863         if (!file_format)
1864             file_format = &mpeg_mux_format;
1865     }
1866     
1867     oc->format = file_format;
1868
1869     if (!strcmp(file_format->name, "ffm") && 
1870         strstart(filename, "http:", NULL)) {
1871         /* special case for files sent to ffserver: we get the stream
1872            parameters from ffserver */
1873         if (read_ffserver_streams(oc, filename) < 0) {
1874             fprintf(stderr, "Could not read stream parameters from '%s'\n", filename);
1875             exit(1);
1876         }
1877     } else {
1878         use_video = file_format->video_codec != CODEC_ID_NONE;
1879         use_audio = file_format->audio_codec != CODEC_ID_NONE;
1880         
1881         if (audio_disable) {
1882             use_audio = 0;
1883         }
1884         if (video_disable) {
1885             use_video = 0;
1886         }
1887         
1888         nb_streams = 0;
1889         if (use_video) {
1890             AVCodecContext *video_enc;
1891             
1892             st = av_mallocz(sizeof(AVStream));
1893             if (!st) {
1894                 fprintf(stderr, "Could not alloc stream\n");
1895                 exit(1);
1896             }
1897             video_enc = &st->codec;
1898
1899             codec_id = file_format->video_codec;
1900             if (video_codec_id != CODEC_ID_NONE)
1901                 codec_id = video_codec_id;
1902
1903             video_enc->codec_id = codec_id;
1904             video_enc->codec_type = CODEC_TYPE_VIDEO;
1905             
1906             video_enc->bit_rate = video_bit_rate;
1907             video_enc->frame_rate = frame_rate; 
1908             
1909             video_enc->width = frame_width;
1910             video_enc->height = frame_height;
1911             if (!intra_only)
1912                 video_enc->gop_size = gop_size;
1913             else
1914                 video_enc->gop_size = 0;
1915             if (video_qscale || same_quality) {
1916                 video_enc->flags |= CODEC_FLAG_QSCALE;
1917                 video_enc->quality = video_qscale;
1918             }
1919             /* XXX: need to find a way to set codec parameters */
1920             if (oc->format == &ppm_format ||
1921                 oc->format == &ppmpipe_format) {
1922                 video_enc->pix_fmt = PIX_FMT_RGB24;
1923             }
1924
1925             oc->streams[nb_streams] = st;
1926             nb_streams++;
1927         }
1928     
1929         if (use_audio) {
1930             AVCodecContext *audio_enc;
1931
1932             st = av_mallocz(sizeof(AVStream));
1933             if (!st) {
1934                 fprintf(stderr, "Could not alloc stream\n");
1935                 exit(1);
1936             }
1937             audio_enc = &st->codec;
1938             codec_id = file_format->audio_codec;
1939             if (audio_codec_id != CODEC_ID_NONE)
1940                 codec_id = audio_codec_id;
1941             audio_enc->codec_id = codec_id;
1942             audio_enc->codec_type = CODEC_TYPE_AUDIO;
1943             
1944             audio_enc->bit_rate = audio_bit_rate;
1945             audio_enc->sample_rate = audio_sample_rate;
1946             audio_enc->channels = audio_channels;
1947             oc->streams[nb_streams] = st;
1948             nb_streams++;
1949         }
1950
1951         oc->nb_streams = nb_streams;
1952
1953         if (!nb_streams) {
1954             fprintf(stderr, "No audio or video selected\n");
1955             exit(1);
1956         }
1957
1958         if (str_title)
1959             nstrcpy(oc->title, sizeof(oc->title), str_title);
1960         if (str_author)
1961             nstrcpy(oc->author, sizeof(oc->author), str_author);
1962         if (str_copyright)
1963             nstrcpy(oc->copyright, sizeof(oc->copyright), str_copyright);
1964         if (str_comment)
1965             nstrcpy(oc->comment, sizeof(oc->comment), str_comment);
1966     }
1967
1968     output_files[nb_output_files] = oc;
1969     /* dump the file content */
1970     dump_format(oc, nb_output_files, filename, 1);
1971     nb_output_files++;
1972
1973     strcpy(oc->filename, filename);
1974     if (!(oc->format->flags & AVFMT_NOFILE)) {
1975         /* test if it already exists to avoid loosing precious files */
1976         if (!file_overwrite && 
1977             (strchr(filename, ':') == NULL ||
1978              strstart(filename, "file:", NULL))) {
1979             if (url_exist(filename)) {
1980                 int c;
1981                 
1982                 printf("File '%s' already exists. Overwrite ? [y/N] ", filename);
1983                 fflush(stdout);
1984                 c = getchar();
1985                 if (toupper(c) != 'Y') {
1986                     fprintf(stderr, "Not overwriting - exiting\n");
1987                     exit(1);
1988                 }
1989             }
1990         }
1991         
1992         /* open the file */
1993         if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0) {
1994             fprintf(stderr, "Could not open '%s'\n", filename);
1995             exit(1);
1996         }
1997     }
1998
1999     /* reset some options */
2000     file_format = NULL;
2001     audio_disable = 0;
2002     video_disable = 0;
2003     audio_codec_id = CODEC_ID_NONE;
2004     video_codec_id = CODEC_ID_NONE;
2005 }
2006
2007 INT64 getutime(void)
2008 {
2009     struct rusage rusage;
2010
2011     getrusage(RUSAGE_SELF, &rusage);
2012     return (rusage.ru_utime.tv_sec * 1000000LL) + rusage.ru_utime.tv_usec;
2013 }
2014
2015 void show_formats(void)
2016 {
2017     AVFormat *f;
2018     URLProtocol *up;
2019     AVCodec *p;
2020     const char **pp;
2021
2022     printf("File formats:\n");
2023     printf("  Encoding:");
2024     for(f = first_format; f != NULL; f = f->next) {
2025         if (f->write_header)
2026             printf(" %s", f->name);
2027     }
2028     printf("\n");
2029     printf("  Decoding:");
2030     for(f = first_format; f != NULL; f = f->next) {
2031         if (f->read_header)
2032             printf(" %s", f->name);
2033     }
2034     printf("\n");
2035
2036     printf("Codecs:\n");
2037     printf("  Encoders:");
2038     for(p = first_avcodec; p != NULL; p = p->next) {
2039         if (p->encode)
2040             printf(" %s", p->name);
2041     }
2042     printf("\n");
2043
2044     printf("  Decoders:");
2045     for(p = first_avcodec; p != NULL; p = p->next) {
2046         if (p->decode)
2047             printf(" %s", p->name);
2048     }
2049     printf("\n");
2050
2051     printf("Supported file protocols:");
2052     for(up = first_protocol; up != NULL; up = up->next)
2053         printf(" %s:", up->name);
2054     printf("\n");
2055     
2056     printf("Frame size abbreviations: sqcif qcif cif 4cif\n");
2057     printf("Motion estimation methods:");
2058     pp = motion_str;
2059     while (*pp) {
2060         printf(" %s", *pp);
2061         if ((pp - motion_str) == ME_ZERO) 
2062             printf("(fastest)");
2063         else if ((pp - motion_str) == ME_FULL) 
2064             printf("(slowest)");
2065         else if ((pp - motion_str) == ME_LOG) 
2066             printf("(default)");
2067         pp++;
2068     }
2069     printf("\n");
2070     exit(1);
2071 }
2072
2073 void show_help(void)
2074 {
2075     const OptionDef *po;
2076     int i, expert;
2077
2078     printf("ffmpeg version " FFMPEG_VERSION ", Copyright (c) 2000,2001 Gerard Lantau\n"
2079            "usage: ffmpeg [[options] -i input_file]... {[options] outfile}...\n"
2080            "Hyper fast MPEG1/MPEG4/H263/RV and AC3/MPEG audio encoder\n"
2081            "\n"
2082            "Main options are:\n");
2083     for(i=0;i<2;i++) {
2084         if (i == 1)
2085             printf("\nAdvanced options are:\n");
2086         for(po = options; po->name != NULL; po++) {
2087             char buf[64];
2088             expert = (po->flags & OPT_EXPERT) != 0;
2089             if (expert == i) {
2090                 strcpy(buf, po->name);
2091                 if (po->flags & HAS_ARG) {
2092                     strcat(buf, " ");
2093                     strcat(buf, po->argname);
2094                 }
2095                 printf("-%-17s  %s\n", buf, po->help);
2096             }
2097         }
2098     }
2099
2100     exit(1);
2101 }
2102
2103 const OptionDef options[] = {
2104     { "L", 0, {show_licence}, "show license" },
2105     { "h", 0, {show_help}, "show help" },
2106     { "formats", 0, {show_formats}, "show available formats, codecs, protocols, ..." },
2107     { "f", HAS_ARG, {opt_format}, "force format", "fmt" },
2108     { "i", HAS_ARG, {opt_input_file}, "input file name", "filename" },
2109     { "y", OPT_BOOL, {int_arg:&file_overwrite}, "overwrite output files" },
2110     { "map", HAS_ARG | OPT_EXPERT, {opt_map}, "set input stream mapping", "file:stream" },
2111     { "t", HAS_ARG, {opt_recording_time}, "set the recording time", "duration" },
2112     { "title", HAS_ARG | OPT_STRING, {str_arg: &str_title}, "set the title", "string" },
2113     { "author", HAS_ARG | OPT_STRING, {str_arg: &str_author}, "set the author", "string" },
2114     { "copyright", HAS_ARG | OPT_STRING, {str_arg: &str_copyright}, "set the copyright", "string" },
2115     { "comment", HAS_ARG | OPT_STRING, {str_arg: &str_comment}, "set the comment", "string" },
2116     /* video options */
2117     { "b", HAS_ARG, {opt_video_bitrate}, "set video bitrate (in kbit/s)", "bitrate" },
2118     { "r", HAS_ARG, {opt_frame_rate}, "set frame rate (in Hz)", "rate" },
2119     { "s", HAS_ARG, {opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
2120     { "g", HAS_ARG | OPT_EXPERT, {opt_gop_size}, "set the group of picture size", "gop_size" },
2121     { "intra", OPT_BOOL | OPT_EXPERT, {int_arg: &intra_only}, "use only intra frames"},
2122     { "vn", OPT_BOOL, {int_arg: &video_disable}, "disable video" },
2123     { "qscale", HAS_ARG | OPT_EXPERT, {opt_qscale}, "use fixed video quantiser scale (VBR)", "q" },
2124     { "vd", HAS_ARG | OPT_EXPERT, {opt_video_device}, "set video device", "device" },
2125     { "vcodec", HAS_ARG | OPT_EXPERT, {opt_video_codec}, "force video codec", "codec" },
2126     { "me", HAS_ARG | OPT_EXPERT, {opt_motion_estimation}, "set motion estimation method", 
2127       "method" },
2128     { "sameq", OPT_BOOL, {int_arg: &same_quality}, 
2129       "use same video quality as source (implies VBR)" },
2130     /* audio options */
2131     { "ab", HAS_ARG, {opt_audio_bitrate}, "set audio bitrate (in kbit/s)", "bitrate", },
2132     { "ar", HAS_ARG, {opt_audio_rate}, "set audio sampling rate (in Hz)", "rate" },
2133     { "ac", HAS_ARG, {opt_audio_channels}, "set number of audio channels", "channels" },
2134     { "an", OPT_BOOL, {int_arg: &audio_disable}, "disable audio" },
2135     { "ad", HAS_ARG | OPT_EXPERT, {opt_audio_device}, "set audio device", "device" },
2136     { "acodec", HAS_ARG | OPT_EXPERT, {opt_audio_codec}, "force audio codec", "codec" },
2137     { "deinterlace", OPT_BOOL | OPT_EXPERT, {int_arg: &do_deinterlace}, 
2138       "deinterlace pictures" },
2139     { "benchmark", OPT_BOOL | OPT_EXPERT, {int_arg: &do_benchmark}, 
2140       "add timings for benchmarking" },
2141
2142     { NULL, },
2143 };
2144
2145 int main(int argc, char **argv)
2146 {
2147     int optindex, i;
2148     const char *opt, *arg;
2149     const OptionDef *po;
2150     
2151     register_all();
2152
2153     if (argc <= 1)
2154         show_help();
2155
2156     optindex = 1;
2157     while (optindex < argc) {
2158         opt = argv[optindex++];
2159         
2160         if (opt[0] == '-' && opt[1] != '\0') {
2161             po = options;
2162             while (po->name != NULL) {
2163                 if (!strcmp(opt + 1, po->name))
2164                     break;
2165                 po++;
2166             }
2167             if (!po->name) {
2168                 fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], opt);
2169                 exit(1);
2170             }
2171             arg = NULL;
2172             if (po->flags & HAS_ARG)
2173                 arg = argv[optindex++];
2174             if (po->flags & OPT_STRING) {
2175                 char *str;
2176                 str = strdup(arg);
2177                 *po->u.str_arg = str;
2178             } else if (po->flags & OPT_BOOL) {
2179                 *po->u.int_arg = 1;
2180             } else {
2181                 po->u.func_arg(arg);
2182             }
2183         } else {
2184             opt_output_file(opt);
2185         }
2186     }
2187
2188
2189     if (nb_input_files == 0) {
2190         if (nb_output_files != 1) {
2191             fprintf(stderr, "Only one output file supported when grabbing\n");
2192             exit(1);
2193         }
2194         av_grab(output_files[0]);
2195     } else {
2196         INT64 ti;
2197
2198         if (nb_output_files <= 0) {
2199             fprintf(stderr, "Must supply at least one output file\n");
2200             exit(1);
2201         }
2202         ti = getutime();
2203         av_encode(output_files, nb_output_files, input_files, nb_input_files, 
2204                   stream_maps, nb_stream_maps);
2205         ti = getutime() - ti;
2206         if (do_benchmark) {
2207             printf("bench: utime=%0.3fs\n", ti / 1000000.0);
2208         }
2209     }
2210
2211     /* close files */
2212     for(i=0;i<nb_output_files;i++) {
2213         if (!(output_files[i]->format->flags & AVFMT_NOFILE)) 
2214             url_fclose(&output_files[i]->pb);
2215     }
2216     for(i=0;i<nb_input_files;i++) {
2217         if (!(input_files[i]->format->flags & AVFMT_NOFILE)) 
2218             url_fclose(&input_files[i]->pb);
2219     }
2220
2221     return 0;
2222 }