added arm support - added --disable-grab
[libav.git] / ffmpeg.c
CommitLineData
85f07f22
FB
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>
5727b222
FB
29#include <sys/time.h>
30#include <sys/resource.h>
85f07f22
FB
31#include <ctype.h>
32
33#include "avformat.h"
34
35typedef 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 */
52typedef struct AVStreamMap {
53 int file_index;
54 int stream_index;
55} AVStreamMap;
56
57extern const OptionDef options[];
58
59void show_help(void);
60
61#define MAX_FILES 20
62
63static AVFormatContext *input_files[MAX_FILES];
64static int nb_input_files = 0;
65
66static AVFormatContext *output_files[MAX_FILES];
67static int nb_output_files = 0;
68
69static AVStreamMap stream_maps[MAX_FILES];
70static int nb_stream_maps;
71
72static AVFormat *file_format;
73static int frame_width = 160;
74static int frame_height = 128;
75static int frame_rate = 25 * FRAME_RATE_BASE;
76static int video_bit_rate = 200000;
77static int video_qscale = 0;
78static int video_disable = 0;
79static int video_codec_id = CODEC_ID_NONE;
80static int same_quality = 0;
cfcf0ffd 81static int do_deinterlace = 0;
85f07f22
FB
82
83static int gop_size = 12;
84static int intra_only = 0;
85static int audio_sample_rate = 44100;
86static int audio_bit_rate = 64000;
87static int audio_disable = 0;
88static int audio_channels = 1;
89static int audio_codec_id = CODEC_ID_NONE;
90
91static INT64 recording_time = 0;
92static int file_overwrite = 0;
93static char *str_title = NULL;
94static char *str_author = NULL;
95static char *str_copyright = NULL;
96static char *str_comment = NULL;
5727b222 97static int do_benchmark = 0;
85f07f22
FB
98
99typedef 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
119typedef 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
130typedef 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 */
139static struct termios oldtty;
140
141static void term_exit(void)
142{
143 tcsetattr (0, TCSANOW, &oldtty);
144}
145
146static 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 */
168static 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 */
190int 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) {
cfcf0ffd
FB
453 AVPicture *picture1, *picture2, *picture;
454 AVPicture picture_tmp0, picture_tmp1;
85f07f22
FB
455
456 ret = url_read(video_handle, picture_in_buf, picture_size);
457 if (ret < 0)
458 break;
cfcf0ffd
FB
459
460 picture2 = &picture_tmp0;
461 avpicture_fill(picture2, picture_in_buf, pix_fmt, width, height);
462
85f07f22 463 if (pix_fmt != PIX_FMT_YUV420P) {
cfcf0ffd
FB
464 picture = &picture_tmp1;
465 img_convert(picture, PIX_FMT_YUV420P,
466 picture2, pix_fmt,
467 width, height);
85f07f22 468 } else {
cfcf0ffd 469 picture = picture2;
85f07f22 470 }
85f07f22
FB
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,
cfcf0ffd 487 picture1, picture);
85f07f22 488 } else {
cfcf0ffd 489 picture1 = picture;
85f07f22
FB
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
596int 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
619static 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 */
cfcf0ffd
FB
664static void write_picture(AVFormatContext *s, int index, AVPicture *picture,
665 int pix_fmt, int w, int h)
85f07f22
FB
666{
667 UINT8 *buf, *src, *dest;
668 int size, j, i;
cfcf0ffd
FB
669
670 size = avpicture_get_size(pix_fmt, w, h);
671 buf = malloc(size);
672 if (!buf)
673 return;
674
85f07f22
FB
675 /* XXX: not efficient, should add test if we can take
676 directly the AVPicture */
cfcf0ffd
FB
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];
85f07f22 731 }
cfcf0ffd
FB
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];
85f07f22 739 for(j=0;j<h;j++) {
cfcf0ffd
FB
740 memcpy(dest, src, w * 3);
741 dest += w * 3;
742 src += picture->linesize[0];
85f07f22 743 }
cfcf0ffd
FB
744 break;
745 default:
746 return;
85f07f22
FB
747 }
748 s->format->write_packet(s, index, buf, size);
749 free(buf);
750}
751
752
753static void do_video_out(AVFormatContext *s,
754 AVOutputStream *ost,
755 AVInputStream *ist,
cfcf0ffd 756 AVPicture *picture1)
85f07f22
FB
757{
758 int n1, n2, nb, i, ret, frame_number;
cfcf0ffd
FB
759 AVPicture *picture, *picture2, *pict;
760 AVPicture picture_tmp1, picture_tmp2;
85f07f22 761 UINT8 video_buffer[128*1024];
cfcf0ffd
FB
762 UINT8 *buf = NULL, *buf1 = NULL;
763 AVCodecContext *enc, *dec;
85f07f22
FB
764
765 enc = &ost->st->codec;
cfcf0ffd 766 dec = &ist->st->codec;
85f07f22
FB
767
768 frame_number = ist->frame_number;
769 /* first drop frame if needed */
cfcf0ffd
FB
770 n1 = ((INT64)frame_number * enc->frame_rate) / dec->frame_rate;
771 n2 = (((INT64)frame_number + 1) * enc->frame_rate) / dec->frame_rate;
85f07f22
FB
772 nb = n2 - n1;
773 if (nb <= 0)
774 return;
775
cfcf0ffd
FB
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 */
85f07f22
FB
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) {
cfcf0ffd 839 enc->quality = dec->quality;
85f07f22 840 }
cfcf0ffd 841 ret = avcodec_encode_video(enc,
85f07f22
FB
842 video_buffer, sizeof(video_buffer),
843 picture);
844 s->format->write_packet(s, ost->index, video_buffer, ret);
845 } else {
cfcf0ffd 846 write_picture(s, ost->index, picture, enc->pix_fmt, enc->width, enc->height);
85f07f22
FB
847 }
848 }
cfcf0ffd
FB
849 the_end:
850 if (buf)
851 free(buf);
852 if (buf1)
853 free(buf1);
85f07f22
FB
854}
855
856//#define HEX_DUMP
857
858#ifdef HEX_DUMP
859static 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 */
889static 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);
cfcf0ffd
FB
1223 avpicture_fill(&picture, ptr,
1224 ist->st->codec.pix_fmt,
1225 ist->st->codec.width,
1226 ist->st->codec.height);
85f07f22
FB
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
1444int 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
1465void 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
1487void 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
1499void opt_video_bitrate(const char *arg)
1500{
1501 video_bit_rate = atoi(arg) * 1000;
1502}
1503
1504void opt_frame_rate(const char *arg)
1505{
1506 frame_rate = (int)(strtod(arg, 0) * FRAME_RATE_BASE);
1507}
1508
1509void 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
1522void opt_gop_size(const char *arg)
1523{
1524 gop_size = atoi(arg);
1525}
1526
1527void 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
1538void opt_audio_bitrate(const char *arg)
1539{
1540 audio_bit_rate = atoi(arg) * 1000;
1541}
1542
1543void opt_audio_rate(const char *arg)
1544{
1545 audio_sample_rate = atoi(arg);
1546}
1547
1548void opt_audio_channels(const char *arg)
1549{
1550 audio_channels = atoi(arg);
1551}
1552
1553void opt_video_device(const char *arg)
1554{
1555 v4l_device = strdup(arg);
1556}
1557
1558void opt_audio_device(const char *arg)
1559{
1560 audio_device = strdup(arg);
1561}
1562
1563void 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
1581const char *motion_str[] = {
1582 "zero",
1583 "full",
1584 "log",
1585 "phods",
1586 NULL,
1587};
1588
1589void 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
1605void 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
1623void 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
1637void 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 */
1643int 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
1750void 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
1849void 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 }
cfcf0ffd
FB
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 }
85f07f22
FB
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
5727b222
FB
2007INT64 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
85f07f22
FB
2015void 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
2073void 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
2103const 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" },
cfcf0ffd
FB
2137 { "deinterlace", OPT_BOOL | OPT_EXPERT, {int_arg: &do_deinterlace},
2138 "deinterlace pictures" },
5727b222
FB
2139 { "benchmark", OPT_BOOL | OPT_EXPERT, {int_arg: &do_benchmark},
2140 "add timings for benchmarking" },
85f07f22
FB
2141
2142 { NULL, },
2143};
2144
2145int 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 {
5727b222
FB
2196 INT64 ti;
2197
85f07f22
FB
2198 if (nb_output_files <= 0) {
2199 fprintf(stderr, "Must supply at least one output file\n");
2200 exit(1);
2201 }
5727b222 2202 ti = getutime();
85f07f22
FB
2203 av_encode(output_files, nb_output_files, input_files, nb_input_files,
2204 stream_maps, nb_stream_maps);
5727b222
FB
2205 ti = getutime() - ti;
2206 if (do_benchmark) {
2207 printf("bench: utime=%0.3fs\n", ti / 1000000.0);
2208 }
85f07f22
FB
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}