more cosmetics so that doxygen output is readable ...
[libav.git] / ffmpeg.c
CommitLineData
85f07f22
FB
1/*
2 * FFmpeg main
bf5af568 3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
85f07f22 4 *
bf5af568
FB
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
85f07f22 9 *
bf5af568 10 * This library is distributed in the hope that it will be useful,
85f07f22 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
bf5af568
FB
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
85f07f22 14 *
bf5af568
FB
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
85f07f22 18 */
daf8e955
FB
19#define HAVE_AV_CONFIG_H
20#include "avformat.h"
10d104e4 21#include "framehook.h"
daf8e955 22
bdc4796f 23#ifndef CONFIG_WIN32
85f07f22
FB
24#include <unistd.h>
25#include <fcntl.h>
26#include <sys/ioctl.h>
85f07f22 27#include <sys/time.h>
85f07f22 28#include <termios.h>
5727b222 29#include <sys/resource.h>
bdc4796f 30#endif
f3ec2d46
SG
31#ifdef CONFIG_OS2
32#include <sys/types.h>
33#include <sys/select.h>
34#include <stdlib.h>
35#endif
bf5af568
FB
36#include <time.h>
37#include <ctype.h>
85f07f22 38
8aa1e3da
MN
39#if !defined(INFINITY) && defined(HUGE_VAL)
40#define INFINITY HUGE_VAL
41#endif
85f07f22 42
0c1a9eda 43#define MAXINT64 int64_t_C(0x7fffffffffffffff)
bdc4796f 44
85f07f22
FB
45typedef struct {
46 const char *name;
47 int flags;
48#define HAS_ARG 0x0001
49#define OPT_BOOL 0x0002
50#define OPT_EXPERT 0x0004
51#define OPT_STRING 0x0008
52 union {
b29f97d1 53 void (*func_arg)(const char *);
85f07f22
FB
54 int *int_arg;
55 char **str_arg;
56 } u;
57 const char *help;
58 const char *argname;
59} OptionDef;
60
61/* select an input stream for an output stream */
62typedef struct AVStreamMap {
63 int file_index;
64 int stream_index;
65} AVStreamMap;
66
67extern const OptionDef options[];
68
69void show_help(void);
70
71#define MAX_FILES 20
72
73static AVFormatContext *input_files[MAX_FILES];
74static int nb_input_files = 0;
75
76static AVFormatContext *output_files[MAX_FILES];
77static int nb_output_files = 0;
78
79static AVStreamMap stream_maps[MAX_FILES];
80static int nb_stream_maps;
81
79fdaa4c
FB
82static AVInputFormat *file_iformat;
83static AVOutputFormat *file_oformat;
817b23ff 84static AVImageFormat *image_format;
85f07f22
FB
85static int frame_width = 160;
86static int frame_height = 128;
ab6d194a
MN
87static int frame_topBand = 0;
88static int frame_bottomBand = 0;
89static int frame_leftBand = 0;
90static int frame_rightBand = 0;
85f07f22 91static int frame_rate = 25 * FRAME_RATE_BASE;
e47ec515 92extern int emulate_frame_rate;
3aa102be
MN
93static int video_bit_rate = 200*1000;
94static int video_bit_rate_tolerance = 4000*1000;
85f07f22 95static int video_qscale = 0;
3aa102be
MN
96static int video_qmin = 2;
97static int video_qmax = 31;
17a70fde
MN
98static int video_mb_qmin = 2;
99static int video_mb_qmax = 31;
9cdd6a24
MN
100static int video_qdiff = 3;
101static float video_qblur = 0.5;
102static float video_qcomp = 0.5;
ac2830ec 103#if 0 //experimental, (can be removed)
3aa102be
MN
104static float video_rc_qsquish=1.0;
105static float video_rc_qmod_amp=0;
106static int video_rc_qmod_freq=0;
ac2830ec 107#endif
3aa102be
MN
108static char *video_rc_override_string=NULL;
109static char *video_rc_eq="tex^qComp";
110static int video_rc_buffer_size=0;
111static float video_rc_buffer_aggressivity=1.0;
112static int video_rc_max_rate=0;
113static int video_rc_min_rate=0;
114static float video_rc_initial_cplx=0;
115static float video_b_qfactor = 1.25;
116static float video_b_qoffset = 1.25;
b3a391e8 117static float video_i_qfactor = -0.8;
3aa102be 118static float video_i_qoffset = 0.0;
3bea5386 119static int me_method = ME_EPZS;
85f07f22
FB
120static int video_disable = 0;
121static int video_codec_id = CODEC_ID_NONE;
122static int same_quality = 0;
bc6caae2 123static int b_frames = 0;
e4986da9 124static int use_hq = 0;
29da453b 125static int use_4mv = 0;
21e59552
MN
126/* Fx */
127static int use_aic = 0;
128static int use_umv = 0;
129/* /Fx */
130static int use_h263p_extra = 0;
cfcf0ffd 131static int do_deinterlace = 0;
4d2858de
MN
132static int workaround_bugs = FF_BUG_AUTODETECT;
133static int error_resilience = 2;
134static int error_concealment = 3;
463678ac 135static int dct_algo = 0;
2ad1516a 136static int idct_algo = 0;
1dbb6d90
MN
137static int use_part = 0;
138static int packet_size = 0;
f560dd82 139static int strict = 0;
59b571c1 140static int debug = 0;
85f07f22
FB
141
142static int gop_size = 12;
143static int intra_only = 0;
144static int audio_sample_rate = 44100;
145static int audio_bit_rate = 64000;
146static int audio_disable = 0;
147static int audio_channels = 1;
148static int audio_codec_id = CODEC_ID_NONE;
149
0c1a9eda 150static int64_t recording_time = 0;
85f07f22
FB
151static int file_overwrite = 0;
152static char *str_title = NULL;
153static char *str_author = NULL;
154static char *str_copyright = NULL;
155static char *str_comment = NULL;
5727b222 156static int do_benchmark = 0;
a0663ba4 157static int do_hex_dump = 0;
a38469e1 158static int do_play = 0;
43f1708f 159static int do_psnr = 0;
ce7c56c2 160static int do_vstats = 0;
5abdb4b1 161static int do_pass = 0;
b0368839 162static int bitexact = 0;
5abdb4b1 163static char *pass_logfilename = NULL;
1629626f
FB
164static int audio_stream_copy = 0;
165static int video_stream_copy = 0;
5abdb4b1 166
8aa3ee32 167static char *video_grab_format = "video4linux";
79a7c268 168static char *video_device = NULL;
a5df11ab 169static int video_channel = 0;
79a7c268 170
8aa3ee32 171static char *audio_grab_format = "audio_device";
79a7c268 172static char *audio_device = NULL;
8aa3ee32 173
5abdb4b1 174#define DEFAULT_PASS_LOGFILENAME "ffmpeg2pass"
85f07f22
FB
175
176typedef struct AVOutputStream {
177 int file_index; /* file index */
178 int index; /* stream index in the output file */
179 int source_index; /* AVInputStream index */
180 AVStream *st; /* stream in the output file */
ec5517d5
FB
181 int encoding_needed; /* true if encoding needed for this stream */
182 int frame_number;
183 /* input pts and corresponding output pts
184 for A/V sync */
185 double sync_ipts;
c11ef252 186 double sync_ipts_offset;
0c1a9eda 187 int64_t sync_opts;
85f07f22 188 /* video only */
34b10a57
D
189 int video_resample; /* video_resample and video_crop are mutually exclusive */
190 AVPicture pict_tmp; /* temporary image for resampling */
85f07f22 191 ImgReSampleContext *img_resample_ctx; /* for image resampling */
34b10a57
D
192
193 int video_crop; /* video_resample and video_crop are mutually exclusive */
194 int topBand; /* cropping area sizes */
195 int leftBand;
85f07f22
FB
196
197 /* audio only */
198 int audio_resample;
199 ReSampleContext *resample; /* for audio resampling */
200 FifoBuffer fifo; /* for compression: one audio fifo per codec */
5abdb4b1 201 FILE *logfile;
85f07f22
FB
202} AVOutputStream;
203
204typedef struct AVInputStream {
205 int file_index;
206 int index;
207 AVStream *st;
208 int discard; /* true if stream data should be discarded */
209 int decoding_needed; /* true if the packets must be decoded in 'raw_fifo' */
0c1a9eda 210 int64_t sample_index; /* current sample */
ec5517d5 211 int frame_decoded; /* true if a video or audio frame has been decoded */
85f07f22
FB
212} AVInputStream;
213
214typedef struct AVInputFile {
215 int eof_reached; /* true if eof reached */
216 int ist_index; /* index of first stream in ist_table */
217 int buffer_size; /* current total buffer size */
218 int buffer_size_max; /* buffer size at which we consider we can stop
219 buffering */
79fdaa4c 220 int nb_streams; /* nb streams we are aware of */
85f07f22
FB
221} AVInputFile;
222
bdc4796f
FB
223#ifndef CONFIG_WIN32
224
85f07f22
FB
225/* init terminal so that we can grab keys */
226static struct termios oldtty;
227
228static void term_exit(void)
229{
230 tcsetattr (0, TCSANOW, &oldtty);
231}
232
233static void term_init(void)
234{
235 struct termios tty;
236
237 tcgetattr (0, &tty);
238 oldtty = tty;
239
240 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
241 |INLCR|IGNCR|ICRNL|IXON);
242 tty.c_oflag |= OPOST;
243 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
244 tty.c_cflag &= ~(CSIZE|PARENB);
245 tty.c_cflag |= CS8;
246 tty.c_cc[VMIN] = 1;
247 tty.c_cc[VTIME] = 0;
248
249 tcsetattr (0, TCSANOW, &tty);
250
251 atexit(term_exit);
9ddd71fc
FR
252#ifdef CONFIG_BEOS_NETSERVER
253 fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK);
254#endif
85f07f22
FB
255}
256
257/* read a key without blocking */
258static int read_key(void)
259{
9ddd71fc 260 int n = 1;
85f07f22 261 unsigned char ch;
9ddd71fc
FR
262#ifndef CONFIG_BEOS_NETSERVER
263 struct timeval tv;
85f07f22
FB
264 fd_set rfds;
265
266 FD_ZERO(&rfds);
267 FD_SET(0, &rfds);
268 tv.tv_sec = 0;
269 tv.tv_usec = 0;
270 n = select(1, &rfds, NULL, NULL, &tv);
9ddd71fc 271#endif
85f07f22 272 if (n > 0) {
cb09b2ed
PG
273 n = read(0, &ch, 1);
274 if (n == 1)
85f07f22 275 return ch;
cb09b2ed
PG
276
277 return n;
85f07f22
FB
278 }
279 return -1;
280}
281
a38469e1 282#else
85f07f22 283
a38469e1
FB
284/* no interactive support */
285static void term_exit(void)
85f07f22 286{
a38469e1 287}
85f07f22 288
a38469e1
FB
289static void term_init(void)
290{
291}
85f07f22 292
a38469e1
FB
293static int read_key(void)
294{
cb09b2ed 295 return 0;
85f07f22
FB
296}
297
a38469e1 298#endif
bdc4796f 299
b29f97d1 300static int read_ffserver_streams(AVFormatContext *s, const char *filename)
85f07f22 301{
79fdaa4c 302 int i, err;
85f07f22
FB
303 AVFormatContext *ic;
304
79fdaa4c
FB
305 err = av_open_input_file(&ic, filename, NULL, FFM_PACKET_SIZE, NULL);
306 if (err < 0)
307 return err;
85f07f22
FB
308 /* copy stream format */
309 s->nb_streams = ic->nb_streams;
310 for(i=0;i<ic->nb_streams;i++) {
311 AVStream *st;
1e491e29 312
85f07f22
FB
313 st = av_mallocz(sizeof(AVFormatContext));
314 memcpy(st, ic->streams[i], sizeof(AVStream));
315 s->streams[i] = st;
316 }
317
318 av_close_input_file(ic);
319 return 0;
320}
321
817b23ff 322#define MAX_AUDIO_PACKET_SIZE (128 * 1024)
85f07f22
FB
323
324static void do_audio_out(AVFormatContext *s,
325 AVOutputStream *ost,
326 AVInputStream *ist,
327 unsigned char *buf, int size)
328{
0c1a9eda
ZK
329 uint8_t *buftmp;
330 uint8_t audio_buf[2*MAX_AUDIO_PACKET_SIZE]; /* XXX: allocate it */
331 uint8_t audio_out[4*MAX_AUDIO_PACKET_SIZE]; /* XXX: allocate it - yep really WMA */
85f07f22
FB
332 int size_out, frame_bytes, ret;
333 AVCodecContext *enc;
334
335 enc = &ost->st->codec;
336
337 if (ost->audio_resample) {
338 buftmp = audio_buf;
339 size_out = audio_resample(ost->resample,
340 (short *)buftmp, (short *)buf,
341 size / (ist->st->codec.channels * 2));
342 size_out = size_out * enc->channels * 2;
343 } else {
344 buftmp = buf;
345 size_out = size;
346 }
347
348 /* now encode as many frames as possible */
a0663ba4 349 if (enc->frame_size > 1) {
85f07f22
FB
350 /* output resampled raw samples */
351 fifo_write(&ost->fifo, buftmp, size_out,
352 &ost->fifo.wptr);
353
354 frame_bytes = enc->frame_size * 2 * enc->channels;
355
356 while (fifo_read(&ost->fifo, audio_buf, frame_bytes,
357 &ost->fifo.rptr) == 0) {
a0663ba4
FB
358 ret = avcodec_encode_audio(enc, audio_out, sizeof(audio_out),
359 (short *)audio_buf);
ec5517d5 360 av_write_frame(s, ost->index, audio_out, ret);
85f07f22
FB
361 }
362 } else {
a0663ba4
FB
363 /* output a pcm frame */
364 /* XXX: change encoding codec API to avoid this ? */
365 switch(enc->codec->id) {
366 case CODEC_ID_PCM_S16LE:
367 case CODEC_ID_PCM_S16BE:
368 case CODEC_ID_PCM_U16LE:
369 case CODEC_ID_PCM_U16BE:
370 break;
371 default:
372 size_out = size_out >> 1;
373 break;
374 }
375 ret = avcodec_encode_audio(enc, audio_out, size_out,
ff29712a 376 (short *)buftmp);
ec5517d5 377 av_write_frame(s, ost->index, audio_out, ret);
85f07f22
FB
378 }
379}
380
381/* write a picture to a raw mux */
cfcf0ffd
FB
382static void write_picture(AVFormatContext *s, int index, AVPicture *picture,
383 int pix_fmt, int w, int h)
85f07f22 384{
0c1a9eda 385 uint8_t *buf, *src, *dest;
85f07f22 386 int size, j, i;
cfcf0ffd 387
85f07f22
FB
388 /* XXX: not efficient, should add test if we can take
389 directly the AVPicture */
cfcf0ffd
FB
390 switch(pix_fmt) {
391 case PIX_FMT_YUV420P:
5b0ad91b 392 size = avpicture_get_size(pix_fmt, w, h);
0f1578af 393 buf = av_malloc(size);
5b0ad91b
J
394 if (!buf)
395 return;
cfcf0ffd
FB
396 dest = buf;
397 for(i=0;i<3;i++) {
398 if (i == 1) {
399 w >>= 1;
400 h >>= 1;
401 }
402 src = picture->data[i];
403 for(j=0;j<h;j++) {
404 memcpy(dest, src, w);
405 dest += w;
406 src += picture->linesize[i];
407 }
408 }
409 break;
410 case PIX_FMT_YUV422P:
411 size = (w * h) * 2;
0f1578af 412 buf = av_malloc(size);
5b0ad91b
J
413 if (!buf)
414 return;
cfcf0ffd
FB
415 dest = buf;
416 for(i=0;i<3;i++) {
417 if (i == 1) {
418 w >>= 1;
419 }
420 src = picture->data[i];
421 for(j=0;j<h;j++) {
422 memcpy(dest, src, w);
423 dest += w;
424 src += picture->linesize[i];
425 }
426 }
427 break;
428 case PIX_FMT_YUV444P:
429 size = (w * h) * 3;
0f1578af 430 buf = av_malloc(size);
5b0ad91b
J
431 if (!buf)
432 return;
cfcf0ffd
FB
433 dest = buf;
434 for(i=0;i<3;i++) {
435 src = picture->data[i];
436 for(j=0;j<h;j++) {
437 memcpy(dest, src, w);
438 dest += w;
439 src += picture->linesize[i];
440 }
441 }
442 break;
443 case PIX_FMT_YUV422:
444 size = (w * h) * 2;
0f1578af 445 buf = av_malloc(size);
5b0ad91b
J
446 if (!buf)
447 return;
cfcf0ffd
FB
448 dest = buf;
449 src = picture->data[0];
450 for(j=0;j<h;j++) {
451 memcpy(dest, src, w * 2);
452 dest += w * 2;
453 src += picture->linesize[0];
85f07f22 454 }
cfcf0ffd
FB
455 break;
456 case PIX_FMT_RGB24:
457 case PIX_FMT_BGR24:
458 size = (w * h) * 3;
0f1578af 459 buf = av_malloc(size);
5b0ad91b
J
460 if (!buf)
461 return;
cfcf0ffd
FB
462 dest = buf;
463 src = picture->data[0];
85f07f22 464 for(j=0;j<h;j++) {
cfcf0ffd
FB
465 memcpy(dest, src, w * 3);
466 dest += w * 3;
467 src += picture->linesize[0];
85f07f22 468 }
cfcf0ffd
FB
469 break;
470 default:
471 return;
85f07f22 472 }
ec5517d5 473 av_write_frame(s, index, buf, size);
0f1578af 474 av_free(buf);
85f07f22
FB
475}
476
10d104e4
PG
477static void pre_process_video_frame(AVInputStream *ist, AVPicture *picture, void **bufp)
478{
479 AVCodecContext *dec;
480 AVPicture *picture2;
481 AVPicture picture_tmp;
0c1a9eda 482 uint8_t *buf = 0;
10d104e4
PG
483
484 dec = &ist->st->codec;
485
486 /* deinterlace : must be done before any resize */
487 if (do_deinterlace) {
488 int size;
489
490 /* create temporary picture */
491 size = avpicture_get_size(dec->pix_fmt, dec->width, dec->height);
492 buf = av_malloc(size);
493 if (!buf)
494 return;
495
496 picture2 = &picture_tmp;
497 avpicture_fill(picture2, buf, dec->pix_fmt, dec->width, dec->height);
498
499 if (avpicture_deinterlace(picture2, picture,
500 dec->pix_fmt, dec->width, dec->height) < 0) {
501 /* if error, do not deinterlace */
502 av_free(buf);
503 buf = NULL;
504 picture2 = picture;
505 }
506 } else {
507 picture2 = picture;
508 }
509
510 frame_hook_process(picture2, dec->pix_fmt, dec->width, dec->height);
511
512 if (picture != picture2)
513 *picture = *picture2;
514 *bufp = buf;
515}
516
ec5517d5
FB
517/* we begin to correct av delay at this threshold */
518#define AV_DELAY_MAX 0.100
85f07f22
FB
519
520static void do_video_out(AVFormatContext *s,
521 AVOutputStream *ost,
522 AVInputStream *ist,
34b10a57 523 AVPicture *in_picture,
ec5517d5 524 int *frame_size, AVOutputStream *audio_sync)
85f07f22 525{
ec5517d5 526 int nb_frames, i, ret;
34b10a57
D
527 AVPicture *final_picture, *formatted_picture;
528 AVPicture picture_format_temp, picture_crop_temp;
0c1a9eda
ZK
529 static uint8_t *video_buffer;
530 uint8_t *buf = NULL, *buf1 = NULL;
cfcf0ffd 531 AVCodecContext *enc, *dec;
85f07f22 532
33a1f1a3 533#define VIDEO_BUFFER_SIZE (1024*1024)
33a1f1a3 534
85f07f22 535 enc = &ost->st->codec;
cfcf0ffd 536 dec = &ist->st->codec;
85f07f22 537
ec5517d5
FB
538 /* by default, we output a single frame */
539 nb_frames = 1;
540
204c0f48
PG
541 *frame_size = 0;
542
ec5517d5
FB
543 /* NOTE: the A/V sync is always done by considering the audio is
544 the master clock. It is suffisant for transcoding or playing,
545 but not for the general case */
546 if (audio_sync) {
547 /* compute the A-V delay and duplicate/remove frames if needed */
548 double adelta, vdelta, apts, vpts, av_delay;
549
550 if (audio_sync->sync_ipts != AV_NOPTS_VALUE &&
551 ost->sync_ipts != AV_NOPTS_VALUE) {
552
553 adelta = (double)(ost->st->pts.val - audio_sync->sync_opts) *
554 s->pts_num / s->pts_den;
555 apts = audio_sync->sync_ipts + adelta;
556
557 vdelta = (double)(ost->st->pts.val - ost->sync_opts) *
558 s->pts_num / s->pts_den;
559 vpts = ost->sync_ipts + vdelta;
560
561 av_delay = apts - vpts;
562 // printf("delay=%f\n", av_delay);
563 if (av_delay < -AV_DELAY_MAX)
564 nb_frames = 2;
565 else if (av_delay > AV_DELAY_MAX)
566 nb_frames = 0;
567 }
10d104e4
PG
568 } else {
569 double vdelta;
570
571 if (ost->sync_ipts != AV_NOPTS_VALUE) {
c11ef252 572 vdelta = (double)(ost->st->pts.val) * s->pts_num / s->pts_den - (ost->sync_ipts - ost->sync_ipts_offset);
be4ce157 573 if (vdelta < 100 && vdelta > -100 && ost->sync_ipts_offset) {
c11ef252
PG
574 if (vdelta < -AV_DELAY_MAX)
575 nb_frames = 2;
576 else if (vdelta > AV_DELAY_MAX)
577 nb_frames = 0;
578 } else {
579 ost->sync_ipts_offset -= vdelta;
be4ce157
PG
580 if (!ost->sync_ipts_offset)
581 ost->sync_ipts_offset = 0.000001; /* one microsecond */
c11ef252
PG
582 }
583
be4ce157 584#if defined(PJSG)
c11ef252
PG
585 {
586 static char *action[] = { "drop frame", "copy frame", "dup frame" };
587 printf("Input PTS %12.6f, output PTS %12.6f: %s\n",
588 (double) ost->sync_ipts, (double) ost->st->pts.val * s->pts_num / s->pts_den,
589 action[nb_frames]);
590 }
591#endif
10d104e4 592 }
ec5517d5 593 }
ec5517d5 594 if (nb_frames <= 0)
85f07f22 595 return;
ce7c56c2 596
cb09b2ed 597 if (!video_buffer)
ec5517d5
FB
598 video_buffer = av_malloc(VIDEO_BUFFER_SIZE);
599 if (!video_buffer)
600 return;
c04643a2 601
cfcf0ffd
FB
602 /* convert pixel format if needed */
603 if (enc->pix_fmt != dec->pix_fmt) {
604 int size;
605
606 /* create temporary picture */
607 size = avpicture_get_size(enc->pix_fmt, dec->width, dec->height);
0f1578af 608 buf = av_malloc(size);
cfcf0ffd
FB
609 if (!buf)
610 return;
34b10a57
D
611 formatted_picture = &picture_format_temp;
612 avpicture_fill(formatted_picture, buf, enc->pix_fmt, dec->width, dec->height);
cfcf0ffd 613
34b10a57
D
614 if (img_convert(formatted_picture, enc->pix_fmt,
615 in_picture, dec->pix_fmt,
cfcf0ffd
FB
616 dec->width, dec->height) < 0) {
617 fprintf(stderr, "pixel format conversion not handled\n");
618 goto the_end;
619 }
620 } else {
34b10a57 621 formatted_picture = in_picture;
cfcf0ffd
FB
622 }
623
624 /* XXX: resampling could be done before raw format convertion in
625 some cases to go faster */
626 /* XXX: only works for YUV420P */
85f07f22 627 if (ost->video_resample) {
34b10a57
D
628 final_picture = &ost->pict_tmp;
629 img_resample(ost->img_resample_ctx, final_picture, formatted_picture);
630 } else if (ost->video_crop) {
631 picture_crop_temp.data[0] = formatted_picture->data[0] +
632 (ost->topBand * formatted_picture->linesize[0]) + ost->leftBand;
633
634 picture_crop_temp.data[1] = formatted_picture->data[1] +
635 ((ost->topBand >> 1) * formatted_picture->linesize[1]) +
636 (ost->leftBand >> 1);
637
638 picture_crop_temp.data[2] = formatted_picture->data[2] +
639 ((ost->topBand >> 1) * formatted_picture->linesize[2]) +
640 (ost->leftBand >> 1);
641
642 picture_crop_temp.linesize[0] = formatted_picture->linesize[0];
643 picture_crop_temp.linesize[1] = formatted_picture->linesize[1];
644 picture_crop_temp.linesize[2] = formatted_picture->linesize[2];
645 final_picture = &picture_crop_temp;
85f07f22 646 } else {
34b10a57 647 final_picture = formatted_picture;
85f07f22 648 }
85f07f22
FB
649 /* duplicates frame if needed */
650 /* XXX: pb because no interleaving */
ec5517d5 651 for(i=0;i<nb_frames;i++) {
85f07f22 652 if (enc->codec_id != CODEC_ID_RAWVIDEO) {
492cd3a9 653 AVFrame big_picture;
1e491e29 654
492cd3a9 655 memset(&big_picture, 0, sizeof(AVFrame));
34b10a57 656 *(AVPicture*)&big_picture= *final_picture;
1e491e29 657
85f07f22
FB
658 /* handles sameq here. This is not correct because it may
659 not be a global option */
660 if (same_quality) {
1e491e29
MN
661 big_picture.quality = ist->st->quality;
662 }else
663 big_picture.quality = ost->st->quality;
6dc96cb0 664
cfcf0ffd 665 ret = avcodec_encode_video(enc,
33a1f1a3 666 video_buffer, VIDEO_BUFFER_SIZE,
1e491e29 667 &big_picture);
44429457 668 //enc->frame_number = enc->real_pict_num;
ec5517d5 669 av_write_frame(s, ost->index, video_buffer, ret);
ce7c56c2 670 *frame_size = ret;
a5dc85ef 671 //fprintf(stderr,"\nFrame: %3d %3d size: %5d type: %d",
44429457 672 // enc->frame_number-1, enc->real_pict_num, ret,
a5dc85ef 673 // enc->pict_type);
5abdb4b1
FB
674 /* if two pass, output log */
675 if (ost->logfile && enc->stats_out) {
676 fprintf(ost->logfile, "%s", enc->stats_out);
677 }
85f07f22 678 } else {
7002684e
FB
679 if (s->oformat->flags & AVFMT_RAWPICTURE) {
680 /* raw pictures are written as AVPicture structure to
681 avoid any copies. We support temorarily the older
682 method. */
ec5517d5 683 av_write_frame(s, ost->index,
0c1a9eda 684 (uint8_t *)final_picture, sizeof(AVPicture));
7002684e 685 } else {
34b10a57 686 write_picture(s, ost->index, final_picture, enc->pix_fmt,
ec5517d5 687 enc->width, enc->height);
7002684e 688 }
85f07f22 689 }
ec5517d5 690 ost->frame_number++;
85f07f22 691 }
ec5517d5 692 the_end:
0f1578af
FB
693 av_free(buf);
694 av_free(buf1);
85f07f22
FB
695}
696
140cb663
MN
697static double psnr(double d){
698 if(d==0) return INFINITY;
b29f97d1 699 return -10.0*log(d)/log(10.0);
140cb663
MN
700}
701
ec5517d5
FB
702static void do_video_stats(AVFormatContext *os, AVOutputStream *ost,
703 int frame_size)
ce7c56c2
J
704{
705 static FILE *fvstats=NULL;
0c1a9eda 706 static int64_t total_size = 0;
ce7c56c2 707 char filename[40];
bf5af568
FB
708 time_t today2;
709 struct tm *today;
ce7c56c2
J
710 AVCodecContext *enc;
711 int frame_number;
0c1a9eda 712 int64_t ti;
ce7c56c2
J
713 double ti1, bitrate, avg_bitrate;
714
715 if (!fvstats) {
716 today2 = time(NULL);
717 today = localtime(&today2);
718 sprintf(filename, "vstats_%02d%02d%02d.log", today->tm_hour,
719 today->tm_min,
720 today->tm_sec);
721 fvstats = fopen(filename,"w");
722 if (!fvstats) {
723 perror("fopen");
724 exit(1);
725 }
726 }
727
728 ti = MAXINT64;
729 enc = &ost->st->codec;
730 total_size += frame_size;
731 if (enc->codec_type == CODEC_TYPE_VIDEO) {
ec5517d5 732 frame_number = ost->frame_number;
492cd3a9 733 fprintf(fvstats, "frame= %5d q= %2.1f ", frame_number, enc->coded_frame->quality);
140cb663 734 if (enc->flags&CODEC_FLAG_PSNR)
492cd3a9 735 fprintf(fvstats, "PSNR= %6.2f ", psnr(enc->coded_frame->error[0]/(enc->width*enc->height*255.0*255.0)));
ce7c56c2
J
736
737 fprintf(fvstats,"f_size= %6d ", frame_size);
ec5517d5
FB
738 /* compute pts value */
739 ti1 = (double)ost->st->pts.val * os->pts_num / os->pts_den;
ce7c56c2
J
740 if (ti1 < 0.01)
741 ti1 = 0.01;
742
743 bitrate = (double)(frame_size * 8) * enc->frame_rate / FRAME_RATE_BASE / 1000.0;
744 avg_bitrate = (double)(total_size * 8) / ti1 / 1000.0;
745 fprintf(fvstats, "s_size= %8.0fkB time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s ",
746 (double)total_size / 1024, ti1, bitrate, avg_bitrate);
492cd3a9 747 fprintf(fvstats,"type= %s\n", enc->coded_frame->key_frame == 1 ? "I" : "P");
ce7c56c2 748 }
ec5517d5
FB
749}
750
b29f97d1
ZK
751static void print_report(AVFormatContext **output_files,
752 AVOutputStream **ost_table, int nb_ostreams,
753 int is_last_report)
ec5517d5
FB
754{
755 char buf[1024];
756 AVOutputStream *ost;
757 AVFormatContext *oc, *os;
0c1a9eda 758 int64_t total_size;
ec5517d5
FB
759 AVCodecContext *enc;
760 int frame_number, vid, i;
761 double bitrate, ti1, pts;
0c1a9eda 762 static int64_t last_time = -1;
ec5517d5
FB
763
764 if (!is_last_report) {
0c1a9eda 765 int64_t cur_time;
ec5517d5
FB
766 /* display the report every 0.5 seconds */
767 cur_time = av_gettime();
768 if (last_time == -1) {
769 last_time = cur_time;
770 return;
771 }
772 if ((cur_time - last_time) < 500000)
773 return;
774 last_time = cur_time;
775 }
776
ce7c56c2 777
ec5517d5
FB
778 oc = output_files[0];
779
780 total_size = url_ftell(&oc->pb);
781
782 buf[0] = '\0';
783 ti1 = 1e10;
784 vid = 0;
785 for(i=0;i<nb_ostreams;i++) {
786 ost = ost_table[i];
787 os = output_files[ost->file_index];
788 enc = &ost->st->codec;
10d104e4 789 if (vid && enc->codec_type == CODEC_TYPE_VIDEO) {
1e491e29 790 sprintf(buf + strlen(buf), "q=%2.1f ",
492cd3a9 791 enc->coded_frame->quality);
10d104e4 792 }
ec5517d5
FB
793 if (!vid && enc->codec_type == CODEC_TYPE_VIDEO) {
794 frame_number = ost->frame_number;
1e491e29 795 sprintf(buf + strlen(buf), "frame=%5d q=%2.1f ",
492cd3a9 796 frame_number, enc->coded_frame ? enc->coded_frame->quality : 0);
140cb663 797 if (enc->flags&CODEC_FLAG_PSNR)
492cd3a9 798 sprintf(buf + strlen(buf), "PSNR= %6.2f ", psnr(enc->coded_frame->error[0]/(enc->width*enc->height*255.0*255.0)));
ec5517d5
FB
799 vid = 1;
800 }
801 /* compute min output value */
802 pts = (double)ost->st->pts.val * os->pts_num / os->pts_den;
5d9827bc 803 if ((pts < ti1) && (pts > 0))
ec5517d5
FB
804 ti1 = pts;
805 }
806 if (ti1 < 0.01)
807 ti1 = 0.01;
808 bitrate = (double)(total_size * 8) / ti1 / 1000.0;
809
810 sprintf(buf + strlen(buf),
811 "size=%8.0fkB time=%0.1f bitrate=%6.1fkbits/s",
812 (double)total_size / 1024, ti1, bitrate);
ce7c56c2 813
ec5517d5 814 fprintf(stderr, "%s ", buf);
ce7c56c2 815
ec5517d5
FB
816 if (is_last_report) {
817 fprintf(stderr, "\n");
818 } else {
819 fprintf(stderr, "\r");
820 fflush(stderr);
821 }
ce7c56c2
J
822}
823
85f07f22
FB
824/*
825 * The following code is the main loop of the file converter
826 */
827static int av_encode(AVFormatContext **output_files,
828 int nb_output_files,
829 AVFormatContext **input_files,
830 int nb_input_files,
831 AVStreamMap *stream_maps, int nb_stream_maps)
832{
ec5517d5 833 int ret, i, j, k, n, nb_istreams = 0, nb_ostreams = 0, pts_set;
85f07f22
FB
834 AVFormatContext *is, *os;
835 AVCodecContext *codec, *icodec;
836 AVOutputStream *ost, **ost_table = NULL;
837 AVInputStream *ist, **ist_table = NULL;
bdc4796f 838 AVInputFile *file_table;
51bd4565 839 AVFormatContext *stream_no_data;
cb09b2ed 840 int key;
bdc4796f 841
51bd4565 842 file_table= (AVInputFile*) av_mallocz(nb_input_files * sizeof(AVInputFile));
bdc4796f
FB
843 if (!file_table)
844 goto fail;
85f07f22 845
85f07f22
FB
846 /* input stream init */
847 j = 0;
848 for(i=0;i<nb_input_files;i++) {
849 is = input_files[i];
850 file_table[i].ist_index = j;
79fdaa4c 851 file_table[i].nb_streams = is->nb_streams;
85f07f22
FB
852 j += is->nb_streams;
853 }
854 nb_istreams = j;
855
856 ist_table = av_mallocz(nb_istreams * sizeof(AVInputStream *));
857 if (!ist_table)
bdc4796f 858 goto fail;
85f07f22
FB
859
860 for(i=0;i<nb_istreams;i++) {
861 ist = av_mallocz(sizeof(AVInputStream));
862 if (!ist)
863 goto fail;
864 ist_table[i] = ist;
865 }
866 j = 0;
867 for(i=0;i<nb_input_files;i++) {
868 is = input_files[i];
869 for(k=0;k<is->nb_streams;k++) {
870 ist = ist_table[j++];
871 ist->st = is->streams[k];
872 ist->file_index = i;
873 ist->index = k;
874 ist->discard = 1; /* the stream is discarded by default
875 (changed later) */
876 }
877 }
878
879 /* output stream init */
880 nb_ostreams = 0;
881 for(i=0;i<nb_output_files;i++) {
882 os = output_files[i];
883 nb_ostreams += os->nb_streams;
884 }
885 if (nb_stream_maps > 0 && nb_stream_maps != nb_ostreams) {
886 fprintf(stderr, "Number of stream maps must match number of output streams\n");
887 exit(1);
888 }
889
890 ost_table = av_mallocz(sizeof(AVOutputStream *) * nb_ostreams);
891 if (!ost_table)
892 goto fail;
893 for(i=0;i<nb_ostreams;i++) {
894 ost = av_mallocz(sizeof(AVOutputStream));
895 if (!ost)
896 goto fail;
897 ost_table[i] = ost;
898 }
899
900 n = 0;
901 for(k=0;k<nb_output_files;k++) {
902 os = output_files[k];
903 for(i=0;i<os->nb_streams;i++) {
904 int found;
905 ost = ost_table[n++];
906 ost->file_index = k;
907 ost->index = i;
908 ost->st = os->streams[i];
909 if (nb_stream_maps > 0) {
910 ost->source_index = file_table[stream_maps[n-1].file_index].ist_index +
911 stream_maps[n-1].stream_index;
912 } else {
913 /* get corresponding input stream index : we select the first one with the right type */
914 found = 0;
915 for(j=0;j<nb_istreams;j++) {
916 ist = ist_table[j];
917 if (ist->discard &&
918 ist->st->codec.codec_type == ost->st->codec.codec_type) {
919 ost->source_index = j;
920 found = 1;
921 }
922 }
923
924 if (!found) {
925 /* try again and reuse existing stream */
926 for(j=0;j<nb_istreams;j++) {
927 ist = ist_table[j];
928 if (ist->st->codec.codec_type == ost->st->codec.codec_type) {
929 ost->source_index = j;
930 found = 1;
931 }
932 }
933 if (!found) {
934 fprintf(stderr, "Could not find input stream matching output stream #%d.%d\n",
935 ost->file_index, ost->index);
936 exit(1);
937 }
938 }
939 }
940 ist = ist_table[ost->source_index];
941 ist->discard = 0;
942 }
943 }
944
85f07f22
FB
945 /* for each output stream, we compute the right encoding parameters */
946 for(i=0;i<nb_ostreams;i++) {
947 ost = ost_table[i];
948 ist = ist_table[ost->source_index];
949
950 codec = &ost->st->codec;
951 icodec = &ist->st->codec;
952
1629626f
FB
953 if (ost->st->stream_copy) {
954 /* if stream_copy is selected, no need to decode or encode */
955 codec->codec_id = icodec->codec_id;
956 codec->codec_type = icodec->codec_type;
957 codec->codec_tag = icodec->codec_tag;
958 codec->bit_rate = icodec->bit_rate;
959 switch(codec->codec_type) {
960 case CODEC_TYPE_AUDIO:
961 codec->sample_rate = icodec->sample_rate;
962 codec->channels = icodec->channels;
963 break;
964 case CODEC_TYPE_VIDEO:
965 codec->frame_rate = icodec->frame_rate;
966 codec->width = icodec->width;
967 codec->height = icodec->height;
968 break;
969 default:
970 av_abort();
971 }
972 } else {
973 switch(codec->codec_type) {
974 case CODEC_TYPE_AUDIO:
85f07f22
FB
975 if (fifo_init(&ost->fifo, 2 * MAX_AUDIO_PACKET_SIZE))
976 goto fail;
1629626f 977
85f07f22
FB
978 if (codec->channels == icodec->channels &&
979 codec->sample_rate == icodec->sample_rate) {
980 ost->audio_resample = 0;
981 } else {
e0d2714a
J
982 if (codec->channels != icodec->channels &&
983 icodec->codec_id == CODEC_ID_AC3) {
984 /* Special case for 5:1 AC3 input */
985 /* and mono or stereo output */
6dc96cb0
J
986 /* Request specific number of channels */
987 icodec->channels = codec->channels;
988 if (codec->sample_rate == icodec->sample_rate)
989 ost->audio_resample = 0;
990 else {
991 ost->audio_resample = 1;
992 ost->resample = audio_resample_init(codec->channels, icodec->channels,
993 codec->sample_rate,
994 icodec->sample_rate);
995 }
e0d2714a
J
996 /* Request specific number of channels */
997 icodec->channels = codec->channels;
998 } else {
999 ost->audio_resample = 1;
1000 ost->resample = audio_resample_init(codec->channels, icodec->channels,
85f07f22
FB
1001 codec->sample_rate,
1002 icodec->sample_rate);
e0d2714a 1003 }
85f07f22
FB
1004 }
1005 ist->decoding_needed = 1;
1006 ost->encoding_needed = 1;
1629626f
FB
1007 break;
1008 case CODEC_TYPE_VIDEO:
85f07f22 1009 if (codec->width == icodec->width &&
34b10a57
D
1010 codec->height == icodec->height &&
1011 frame_topBand == 0 &&
1012 frame_bottomBand == 0 &&
1013 frame_leftBand == 0 &&
1014 frame_rightBand == 0)
1015 {
1016 ost->video_resample = 0;
1017 ost->video_crop = 0;
1018 } else if ((codec->width == icodec->width -
1019 (frame_leftBand + frame_rightBand)) &&
1020 (codec->height == icodec->height -
1021 (frame_topBand + frame_bottomBand)))
1022 {
85f07f22 1023 ost->video_resample = 0;
34b10a57
D
1024 ost->video_crop = 1;
1025 ost->topBand = frame_topBand;
1026 ost->leftBand = frame_leftBand;
85f07f22 1027 } else {
0c1a9eda 1028 uint8_t *buf;
85f07f22 1029 ost->video_resample = 1;
34b10a57 1030 ost->video_crop = 0; // cropping is handled as part of resample
0f1578af 1031 buf = av_malloc((codec->width * codec->height * 3) / 2);
85f07f22
FB
1032 if (!buf)
1033 goto fail;
1034 ost->pict_tmp.data[0] = buf;
1035 ost->pict_tmp.data[1] = ost->pict_tmp.data[0] + (codec->width * codec->height);
1036 ost->pict_tmp.data[2] = ost->pict_tmp.data[1] + (codec->width * codec->height) / 4;
1037 ost->pict_tmp.linesize[0] = codec->width;
1038 ost->pict_tmp.linesize[1] = codec->width / 2;
1039 ost->pict_tmp.linesize[2] = codec->width / 2;
1040
ab6d194a 1041 ost->img_resample_ctx = img_resample_full_init(
85f07f22 1042 ost->st->codec.width, ost->st->codec.height,
ab6d194a
MN
1043 ist->st->codec.width, ist->st->codec.height,
1044 frame_topBand, frame_bottomBand,
1045 frame_leftBand, frame_rightBand);
85f07f22
FB
1046 }
1047 ost->encoding_needed = 1;
1048 ist->decoding_needed = 1;
1629626f
FB
1049 break;
1050 default:
1051 av_abort();
85f07f22 1052 }
1629626f
FB
1053 /* two pass mode */
1054 if (ost->encoding_needed &&
1055 (codec->flags & (CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2))) {
1056 char logfilename[1024];
1057 FILE *f;
1058 int size;
1059 char *logbuffer;
1060
1061 snprintf(logfilename, sizeof(logfilename), "%s-%d.log",
1062 pass_logfilename ?
1063 pass_logfilename : DEFAULT_PASS_LOGFILENAME, i);
1064 if (codec->flags & CODEC_FLAG_PASS1) {
1065 f = fopen(logfilename, "w");
1066 if (!f) {
1067 perror(logfilename);
1068 exit(1);
1069 }
1070 ost->logfile = f;
1071 } else {
1072 /* read the log file */
1073 f = fopen(logfilename, "r");
1074 if (!f) {
1075 perror(logfilename);
1076 exit(1);
1077 }
1078 fseek(f, 0, SEEK_END);
1079 size = ftell(f);
1080 fseek(f, 0, SEEK_SET);
1081 logbuffer = av_malloc(size + 1);
1082 if (!logbuffer) {
1083 fprintf(stderr, "Could not allocate log buffer\n");
1084 exit(1);
1085 }
1086 fread(logbuffer, 1, size, f);
1087 fclose(f);
1088 logbuffer[size] = '\0';
1089 codec->stats_in = logbuffer;
5abdb4b1 1090 }
5abdb4b1
FB
1091 }
1092 }
85f07f22
FB
1093 }
1094
1629626f
FB
1095 /* dump the file output parameters - cannot be done before in case
1096 of stream copy */
1097 for(i=0;i<nb_output_files;i++) {
1098 dump_format(output_files[i], i, output_files[i]->filename, 1);
1099 }
1100
1101 /* dump the stream mapping */
1102 fprintf(stderr, "Stream mapping:\n");
1103 for(i=0;i<nb_ostreams;i++) {
1104 ost = ost_table[i];
1105 fprintf(stderr, " Stream #%d.%d -> #%d.%d\n",
1106 ist_table[ost->source_index]->file_index,
1107 ist_table[ost->source_index]->index,
1108 ost->file_index,
1109 ost->index);
1110 }
1111
85f07f22
FB
1112 /* open each encoder */
1113 for(i=0;i<nb_ostreams;i++) {
1114 ost = ost_table[i];
1115 if (ost->encoding_needed) {
1116 AVCodec *codec;
1117 codec = avcodec_find_encoder(ost->st->codec.codec_id);
1118 if (!codec) {
1119 fprintf(stderr, "Unsupported codec for output stream #%d.%d\n",
1120 ost->file_index, ost->index);
1121 exit(1);
1122 }
1123 if (avcodec_open(&ost->st->codec, codec) < 0) {
1124 fprintf(stderr, "Error while opening codec for stream #%d.%d - maybe incorrect parameters such as bit_rate, rate, width or height\n",
1125 ost->file_index, ost->index);
1126 exit(1);
1127 }
1128 }
1129 }
1130
1131 /* open each decoder */
1132 for(i=0;i<nb_istreams;i++) {
1133 ist = ist_table[i];
1134 if (ist->decoding_needed) {
1135 AVCodec *codec;
1136 codec = avcodec_find_decoder(ist->st->codec.codec_id);
1137 if (!codec) {
10d104e4
PG
1138 fprintf(stderr, "Unsupported codec (id=%d) for input stream #%d.%d\n",
1139 ist->st->codec.codec_id, ist->file_index, ist->index);
85f07f22
FB
1140 exit(1);
1141 }
1142 if (avcodec_open(&ist->st->codec, codec) < 0) {
1143 fprintf(stderr, "Error while opening codec for input stream #%d.%d\n",
1144 ist->file_index, ist->index);
1145 exit(1);
1146 }
6dc96cb0
J
1147 //if (ist->st->codec.codec_type == CODEC_TYPE_VIDEO)
1148 // ist->st->codec.flags |= CODEC_FLAG_REPEAT_FIELD;
ec5517d5 1149 ist->frame_decoded = 1;
85f07f22
FB
1150 }
1151 }
1152
1153 /* init pts */
1154 for(i=0;i<nb_istreams;i++) {
1155 ist = ist_table[i];
85f07f22
FB
1156 }
1157
1158 /* compute buffer size max (should use a complete heuristic) */
1159 for(i=0;i<nb_input_files;i++) {
1160 file_table[i].buffer_size_max = 2048;
1161 }
1162
1163 /* open files and write file headers */
1164 for(i=0;i<nb_output_files;i++) {
1165 os = output_files[i];
79fdaa4c 1166 if (av_write_header(os) < 0) {
a38469e1
FB
1167 fprintf(stderr, "Could not write header for output file #%d (incorrect codec paramters ?)\n", i);
1168 ret = -EINVAL;
1169 goto fail;
1170 }
85f07f22
FB
1171 }
1172
a38469e1
FB
1173#ifndef CONFIG_WIN32
1174 if (!do_play) {
1175 fprintf(stderr, "Press [q] to stop encoding\n");
1176 } else {
1177 fprintf(stderr, "Press [q] to stop playing\n");
1178 }
1179#endif
1180 term_init();
1181
51bd4565 1182 stream_no_data = 0;
cb09b2ed 1183 key = -1;
51bd4565 1184
85f07f22
FB
1185 for(;;) {
1186 int file_index, ist_index;
1187 AVPacket pkt;
0c1a9eda 1188 uint8_t *ptr;
85f07f22 1189 int len;
0c1a9eda 1190 uint8_t *data_buf;
85f07f22
FB
1191 int data_size, got_picture;
1192 AVPicture picture;
1193 short samples[AVCODEC_MAX_AUDIO_FRAME_SIZE / 2];
10d104e4 1194 void *buffer_to_free;
ec5517d5
FB
1195 double pts_min;
1196
85f07f22 1197 redo:
a38469e1 1198 /* if 'q' pressed, exits */
cb09b2ed
PG
1199 if (key) {
1200 /* read_key() returns 0 on EOF */
1201 key = read_key();
1202 if (key == 'q')
1203 break;
1204 }
a38469e1 1205
ec5517d5
FB
1206 /* select the stream that we must read now by looking at the
1207 smallest output pts */
85f07f22 1208 file_index = -1;
ec5517d5
FB
1209 pts_min = 1e10;
1210 for(i=0;i<nb_ostreams;i++) {
1211 double pts;
1212 ost = ost_table[i];
1213 os = output_files[ost->file_index];
1214 ist = ist_table[ost->source_index];
1215 pts = (double)ost->st->pts.val * os->pts_num / os->pts_den;
1216 if (!file_table[ist->file_index].eof_reached &&
1217 pts < pts_min) {
1218 pts_min = pts;
85f07f22
FB
1219 file_index = ist->file_index;
1220 }
1221 }
1222 /* if none, if is finished */
51bd4565 1223 if (file_index < 0) {
85f07f22 1224 break;
ec5517d5
FB
1225 }
1226
85f07f22 1227 /* finish if recording time exhausted */
ec5517d5 1228 if (recording_time > 0 && pts_min >= (recording_time / 1000000.0))
85f07f22 1229 break;
ec5517d5 1230
85f07f22 1231 /* read a packet from it and output it in the fifo */
85f07f22
FB
1232 is = input_files[file_index];
1233 if (av_read_packet(is, &pkt) < 0) {
1234 file_table[file_index].eof_reached = 1;
1235 continue;
1236 }
51bd4565
PG
1237 if (!pkt.size) {
1238 stream_no_data = is;
1239 } else {
1240 stream_no_data = 0;
1241 }
817b23ff
FB
1242 if (do_hex_dump) {
1243 printf("stream #%d, size=%d:\n", pkt.stream_index, pkt.size);
1244 av_hex_dump(pkt.data, pkt.size);
1245 }
79fdaa4c
FB
1246 /* the following test is needed in case new streams appear
1247 dynamically in stream : we ignore them */
1248 if (pkt.stream_index >= file_table[file_index].nb_streams)
bf5af568 1249 goto discard_packet;
85f07f22
FB
1250 ist_index = file_table[file_index].ist_index + pkt.stream_index;
1251 ist = ist_table[ist_index];
bf5af568
FB
1252 if (ist->discard)
1253 goto discard_packet;
85f07f22 1254
34b10a57 1255 // printf("read #%d.%d size=%d\n", ist->file_index, ist->index, pkt.size);
85f07f22
FB
1256
1257 len = pkt.size;
1258 ptr = pkt.data;
ec5517d5 1259 pts_set = 0;
85f07f22 1260 while (len > 0) {
0c1a9eda 1261 int64_t ipts;
ec5517d5
FB
1262
1263 ipts = AV_NOPTS_VALUE;
85f07f22
FB
1264
1265 /* decode the packet if needed */
1266 data_buf = NULL; /* fail safe */
1267 data_size = 0;
1268 if (ist->decoding_needed) {
ec5517d5
FB
1269 /* NOTE1: we only take into account the PTS if a new
1270 frame has begun (MPEG semantics) */
1271 /* NOTE2: even if the fraction is not initialized,
1272 av_frac_set can be used to set the integer part */
1273 if (ist->frame_decoded &&
1274 pkt.pts != AV_NOPTS_VALUE &&
1275 !pts_set) {
1276 ipts = pkt.pts;
1277 ist->frame_decoded = 0;
1278 pts_set = 1;
1279 }
1280
85f07f22
FB
1281 switch(ist->st->codec.codec_type) {
1282 case CODEC_TYPE_AUDIO:
a0663ba4
FB
1283 /* XXX: could avoid copy if PCM 16 bits with same
1284 endianness as CPU */
1285 ret = avcodec_decode_audio(&ist->st->codec, samples, &data_size,
1286 ptr, len);
1287 if (ret < 0)
1288 goto fail_decode;
afc80f59
J
1289 /* Some bug in mpeg audio decoder gives */
1290 /* data_size < 0, it seems they are overflows */
1291 if (data_size <= 0) {
a0663ba4
FB
1292 /* no audio frame */
1293 ptr += ret;
1294 len -= ret;
1295 continue;
85f07f22 1296 }
0c1a9eda 1297 data_buf = (uint8_t *)samples;
85f07f22
FB
1298 break;
1299 case CODEC_TYPE_VIDEO:
1300 if (ist->st->codec.codec_id == CODEC_ID_RAWVIDEO) {
1301 int size;
8409b8fe 1302
85f07f22 1303 size = (ist->st->codec.width * ist->st->codec.height);
cfcf0ffd
FB
1304 avpicture_fill(&picture, ptr,
1305 ist->st->codec.pix_fmt,
1306 ist->st->codec.width,
1307 ist->st->codec.height);
85f07f22
FB
1308 ret = len;
1309 } else {
492cd3a9 1310 AVFrame big_picture;
1e491e29 1311
85f07f22
FB
1312 data_size = (ist->st->codec.width * ist->st->codec.height * 3) / 2;
1313 ret = avcodec_decode_video(&ist->st->codec,
1e491e29
MN
1314 &big_picture, &got_picture, ptr, len);
1315 picture= *(AVPicture*)&big_picture;
1316 ist->st->quality= big_picture.quality;
85f07f22
FB
1317 if (ret < 0) {
1318 fail_decode:
1319 fprintf(stderr, "Error while decoding stream #%d.%d\n",
1320 ist->file_index, ist->index);
1321 av_free_packet(&pkt);
1322 goto redo;
1323 }
1324 if (!got_picture) {
1325 /* no picture yet */
1326 ptr += ret;
1327 len -= ret;
1328 continue;
1329 }
6dc96cb0 1330
85f07f22
FB
1331 }
1332 break;
1333 default:
1334 goto fail_decode;
1335 }
1336 } else {
1337 data_buf = ptr;
1338 data_size = len;
1339 ret = len;
1340 }
85f07f22
FB
1341 ptr += ret;
1342 len -= ret;
1343
10d104e4
PG
1344 buffer_to_free = 0;
1345 if (ist->st->codec.codec_type == CODEC_TYPE_VIDEO) {
1346 pre_process_video_frame(ist, &picture, &buffer_to_free);
1347 }
1348
ec5517d5
FB
1349 ist->frame_decoded = 1;
1350
1351#if 0
1352 /* mpeg PTS deordering : if it is a P or I frame, the PTS
1353 is the one of the next displayed one */
1354 /* XXX: add mpeg4 too ? */
1355 if (ist->st->codec.codec_id == CODEC_ID_MPEG1VIDEO) {
1356 if (ist->st->codec.pict_type != B_TYPE) {
0c1a9eda 1357 int64_t tmp;
ec5517d5
FB
1358 tmp = ist->last_ip_pts;
1359 ist->last_ip_pts = ist->frac_pts.val;
1360 ist->frac_pts.val = tmp;
1361 }
1362 }
1363#endif
85f07f22 1364 /* transcode raw format, encode packets and output them */
ec5517d5 1365
85f07f22 1366 for(i=0;i<nb_ostreams;i++) {
ce7c56c2 1367 int frame_size;
ec5517d5 1368
85f07f22
FB
1369 ost = ost_table[i];
1370 if (ost->source_index == ist_index) {
1371 os = output_files[ost->file_index];
1372
ec5517d5
FB
1373 if (ipts != AV_NOPTS_VALUE) {
1374#if 0
1375 printf("%d: got pts=%f %f\n",
1376 i, pkt.pts / 90000.0,
1377 (ipts - ost->st->pts.val) / 90000.0);
1378#endif
1379 /* set the input output pts pairs */
1380 ost->sync_ipts = (double)ipts * is->pts_num /
1381 is->pts_den;
1382 /* XXX: take into account the various fifos,
1383 in particular for audio */
1384 ost->sync_opts = ost->st->pts.val;
10d104e4
PG
1385 //printf("ipts=%lld sync_ipts=%f sync_opts=%lld pts.val=%lld pkt.pts=%lld\n", ipts, ost->sync_ipts, ost->sync_opts, ost->st->pts.val, pkt.pts);
1386 } else {
1387 //printf("pts.val=%lld\n", ost->st->pts.val);
be4ce157 1388 ost->sync_ipts = AV_NOPTS_VALUE;
ec5517d5
FB
1389 }
1390
85f07f22
FB
1391 if (ost->encoding_needed) {
1392 switch(ost->st->codec.codec_type) {
1393 case CODEC_TYPE_AUDIO:
1394 do_audio_out(os, ost, ist, data_buf, data_size);
1395 break;
1396 case CODEC_TYPE_VIDEO:
ec5517d5
FB
1397 /* find an audio stream for synchro */
1398 {
1399 int i;
1400 AVOutputStream *audio_sync, *ost1;
1401 audio_sync = NULL;
1402 for(i=0;i<nb_ostreams;i++) {
1403 ost1 = ost_table[i];
1404 if (ost1->file_index == ost->file_index &&
1405 ost1->st->codec.codec_type == CODEC_TYPE_AUDIO) {
1406 audio_sync = ost1;
1407 break;
1408 }
1409 }
1410
1411 do_video_out(os, ost, ist, &picture, &frame_size, audio_sync);
204c0f48 1412 if (do_vstats && frame_size)
ec5517d5
FB
1413 do_video_stats(os, ost, frame_size);
1414 }
85f07f22 1415 break;
51bd4565 1416 default:
c04643a2 1417 av_abort();
85f07f22
FB
1418 }
1419 } else {
18531e52
MN
1420 AVFrame avframe;
1421
85f07f22 1422 /* no reencoding needed : output the packet directly */
10bb7023 1423 /* force the input stream PTS */
18531e52
MN
1424
1425 //XXX/FIXME set keyframe flag from demuxer (or optionally from decoder)
1426 memset(&avframe, 0, sizeof(AVFrame));
1427 ost->st->codec.coded_frame= &avframe;
1428
ec5517d5 1429 av_write_frame(os, ost->index, data_buf, data_size);
b2722d0a 1430 ost->st->codec.frame_number++;
9ce2f2b1 1431 ost->frame_number++;
85f07f22
FB
1432 }
1433 }
1434 }
10d104e4 1435 av_free(buffer_to_free);
ec5517d5 1436 ipts = AV_NOPTS_VALUE;
85f07f22 1437 }
bf5af568 1438 discard_packet:
85f07f22
FB
1439 av_free_packet(&pkt);
1440
ec5517d5
FB
1441 /* dump report by using the output first video and audio streams */
1442 print_report(output_files, ost_table, nb_ostreams, 0);
85f07f22 1443 }
a38469e1 1444 term_exit();
85f07f22
FB
1445
1446 /* dump report by using the first video and audio streams */
ec5517d5
FB
1447 print_report(output_files, ost_table, nb_ostreams, 1);
1448
85f07f22
FB
1449 /* close each encoder */
1450 for(i=0;i<nb_ostreams;i++) {
1451 ost = ost_table[i];
1452 if (ost->encoding_needed) {
5abdb4b1 1453 av_freep(&ost->st->codec.stats_in);
85f07f22
FB
1454 avcodec_close(&ost->st->codec);
1455 }
1456 }
1457
1458 /* close each decoder */
1459 for(i=0;i<nb_istreams;i++) {
1460 ist = ist_table[i];
1461 if (ist->decoding_needed) {
1462 avcodec_close(&ist->st->codec);
1463 }
1464 }
1465
1466
1467 /* write the trailer if needed and close file */
1468 for(i=0;i<nb_output_files;i++) {
1469 os = output_files[i];
79fdaa4c 1470 av_write_trailer(os);
85f07f22
FB
1471 }
1472 /* finished ! */
1473
1474 ret = 0;
1475 fail1:
0f1578af 1476 av_free(file_table);
bdc4796f 1477
85f07f22
FB
1478 if (ist_table) {
1479 for(i=0;i<nb_istreams;i++) {
1480 ist = ist_table[i];
0f1578af 1481 av_free(ist);
85f07f22 1482 }
0f1578af 1483 av_free(ist_table);
85f07f22
FB
1484 }
1485 if (ost_table) {
1486 for(i=0;i<nb_ostreams;i++) {
1487 ost = ost_table[i];
1488 if (ost) {
5abdb4b1
FB
1489 if (ost->logfile) {
1490 fclose(ost->logfile);
1491 ost->logfile = NULL;
1492 }
bf5af568
FB
1493 fifo_free(&ost->fifo); /* works even if fifo is not
1494 initialized but set to zero */
0f1578af 1495 av_free(ost->pict_tmp.data[0]);
85f07f22
FB
1496 if (ost->video_resample)
1497 img_resample_close(ost->img_resample_ctx);
1498 if (ost->audio_resample)
1499 audio_resample_close(ost->resample);
0f1578af 1500 av_free(ost);
85f07f22
FB
1501 }
1502 }
0f1578af 1503 av_free(ost_table);
85f07f22
FB
1504 }
1505 return ret;
1506 fail:
1507 ret = -ENOMEM;
1508 goto fail1;
1509}
1510
1511#if 0
1512int file_read(const char *filename)
1513{
1514 URLContext *h;
1515 unsigned char buffer[1024];
1516 int len, i;
1517
1518 if (url_open(&h, filename, O_RDONLY) < 0) {
1519 printf("could not open '%s'\n", filename);
1520 return -1;
1521 }
1522 for(;;) {
1523 len = url_read(h, buffer, sizeof(buffer));
1524 if (len <= 0)
1525 break;
1526 for(i=0;i<len;i++) putchar(buffer[i]);
1527 }
1528 url_close(h);
1529 return 0;
1530}
1531#endif
1532
b29f97d1 1533static void show_licence(void)
85f07f22
FB
1534{
1535 printf(
1536 "ffmpeg version " FFMPEG_VERSION "\n"
bf5af568
FB
1537 "Copyright (c) 2000, 2001, 2002 Fabrice Bellard\n"
1538 "This library is free software; you can redistribute it and/or\n"
1539 "modify it under the terms of the GNU Lesser General Public\n"
1540 "License as published by the Free Software Foundation; either\n"
1541 "version 2 of the License, or (at your option) any later version.\n"
85f07f22 1542 "\n"
bf5af568 1543 "This library is distributed in the hope that it will be useful,\n"
85f07f22 1544 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
bf5af568
FB
1545 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
1546 "Lesser General Public License for more details.\n"
85f07f22 1547 "\n"
bf5af568
FB
1548 "You should have received a copy of the GNU Lesser General Public\n"
1549 "License along with this library; if not, write to the Free Software\n"
1550 "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n"
85f07f22
FB
1551 );
1552 exit(1);
1553}
1554
b29f97d1 1555static void opt_image_format(const char *arg)
817b23ff
FB
1556{
1557 AVImageFormat *f;
1558
1559 for(f = first_image_format; f != NULL; f = f->next) {
1560 if (!strcmp(arg, f->name))
1561 break;
1562 }
1563 if (!f) {
1564 fprintf(stderr, "Unknown image format: '%s'\n", arg);
1565 exit(1);
1566 }
1567 image_format = f;
1568}
1569
b29f97d1 1570static void opt_format(const char *arg)
85f07f22 1571{
817b23ff
FB
1572 /* compatibility stuff for pgmyuv */
1573 if (!strcmp(arg, "pgmyuv")) {
1574 opt_image_format(arg);
1575 arg = "image";
1576 }
1577
79fdaa4c
FB
1578 file_iformat = av_find_input_format(arg);
1579 file_oformat = guess_format(arg, NULL, NULL);
1580 if (!file_iformat && !file_oformat) {
1581 fprintf(stderr, "Unknown input or output format: %s\n", arg);
85f07f22
FB
1582 exit(1);
1583 }
85f07f22
FB
1584}
1585
b29f97d1 1586static void opt_video_bitrate(const char *arg)
85f07f22
FB
1587{
1588 video_bit_rate = atoi(arg) * 1000;
1589}
1590
b29f97d1 1591static void opt_video_bitrate_tolerance(const char *arg)
9cdd6a24
MN
1592{
1593 video_bit_rate_tolerance = atoi(arg) * 1000;
1594}
1595
b29f97d1 1596static void opt_video_bitrate_max(const char *arg)
3aa102be
MN
1597{
1598 video_rc_max_rate = atoi(arg) * 1000;
1599}
1600
b29f97d1 1601static void opt_video_bitrate_min(const char *arg)
3aa102be
MN
1602{
1603 video_rc_min_rate = atoi(arg) * 1000;
1604}
1605
b29f97d1 1606static void opt_video_buffer_size(const char *arg)
946c8a12
MN
1607{
1608 video_rc_buffer_size = atoi(arg) * 1000;
1609}
1610
b29f97d1 1611static void opt_video_rc_eq(char *arg)
3aa102be
MN
1612{
1613 video_rc_eq = arg;
1614}
1615
b29f97d1 1616static void opt_video_rc_override_string(char *arg)
ac2830ec
MN
1617{
1618 video_rc_override_string = arg;
1619}
1620
3aa102be 1621
b29f97d1 1622static void opt_workaround_bugs(const char *arg)
fe670d09
MN
1623{
1624 workaround_bugs = atoi(arg);
1625}
1626
b29f97d1 1627static void opt_dct_algo(const char *arg)
463678ac
MN
1628{
1629 dct_algo = atoi(arg);
1630}
1631
b29f97d1 1632static void opt_idct_algo(const char *arg)
2ad1516a
MN
1633{
1634 idct_algo = atoi(arg);
1635}
1636
1637
b29f97d1 1638static void opt_error_resilience(const char *arg)
8409b8fe
MN
1639{
1640 error_resilience = atoi(arg);
1641}
1642
b29f97d1 1643static void opt_error_concealment(const char *arg)
4d2858de
MN
1644{
1645 error_concealment = atoi(arg);
1646}
1647
b29f97d1 1648static void opt_debug(const char *arg)
59b571c1
MN
1649{
1650 debug = atoi(arg);
1651}
4d2858de 1652
b29f97d1 1653static void opt_frame_rate(const char *arg)
85f07f22
FB
1654{
1655 frame_rate = (int)(strtod(arg, 0) * FRAME_RATE_BASE);
1656}
1657
ab6d194a 1658
b29f97d1 1659static void opt_frame_crop_top(const char *arg)
ab6d194a
MN
1660{
1661 frame_topBand = atoi(arg);
1662 if (frame_topBand < 0) {
1663 fprintf(stderr, "Incorrect top crop size\n");
1664 exit(1);
1665 }
1666 if ((frame_topBand % 2) != 0) {
1667 fprintf(stderr, "Top crop size must be a multiple of 2\n");
1668 exit(1);
1669 }
1670 if ((frame_topBand) >= frame_height){
1671 fprintf(stderr, "Vertical crop dimensions are outside the range of the original image.\nRemember to crop first and scale second.\n");
1672 exit(1);
1673 }
1674 frame_height -= frame_topBand;
1675}
1676
b29f97d1 1677static void opt_frame_crop_bottom(const char *arg)
ab6d194a
MN
1678{
1679 frame_bottomBand = atoi(arg);
1680 if (frame_bottomBand < 0) {
1681 fprintf(stderr, "Incorrect bottom crop size\n");
1682 exit(1);
1683 }
1684 if ((frame_bottomBand % 2) != 0) {
1685 fprintf(stderr, "Bottom crop size must be a multiple of 2\n");
1686 exit(1);
1687 }
1688 if ((frame_bottomBand) >= frame_height){
1689 fprintf(stderr, "Vertical crop dimensions are outside the range of the original image.\nRemember to crop first and scale second.\n");
1690 exit(1);
1691 }
1692 frame_height -= frame_bottomBand;
1693}
1694
b29f97d1 1695static void opt_frame_crop_left(const char *arg)
ab6d194a
MN
1696{
1697 frame_leftBand = atoi(arg);
1698 if (frame_leftBand < 0) {
1699 fprintf(stderr, "Incorrect left crop size\n");
1700 exit(1);
1701 }
1702 if ((frame_leftBand % 2) != 0) {
1703 fprintf(stderr, "Left crop size must be a multiple of 2\n");
1704 exit(1);
1705 }
1706 if ((frame_leftBand) >= frame_width){
1707 fprintf(stderr, "Horizontal crop dimensions are outside the range of the original image.\nRemember to crop first and scale second.\n");
1708 exit(1);
1709 }
1710 frame_width -= frame_leftBand;
1711}
1712
b29f97d1 1713static void opt_frame_crop_right(const char *arg)
ab6d194a
MN
1714{
1715 frame_rightBand = atoi(arg);
1716 if (frame_rightBand < 0) {
1717 fprintf(stderr, "Incorrect right crop size\n");
1718 exit(1);
1719 }
1720 if ((frame_rightBand % 2) != 0) {
1721 fprintf(stderr, "Right crop size must be a multiple of 2\n");
1722 exit(1);
1723 }
1724 if ((frame_rightBand) >= frame_width){
1725 fprintf(stderr, "Horizontal crop dimensions are outside the range of the original image.\nRemember to crop first and scale second.\n");
1726 exit(1);
1727 }
1728 frame_width -= frame_rightBand;
1729}
1730
b29f97d1 1731static void opt_frame_size(const char *arg)
85f07f22
FB
1732{
1733 parse_image_size(&frame_width, &frame_height, arg);
1734 if (frame_width <= 0 || frame_height <= 0) {
1735 fprintf(stderr, "Incorrect frame size\n");
1736 exit(1);
1737 }
1738 if ((frame_width % 2) != 0 || (frame_height % 2) != 0) {
1739 fprintf(stderr, "Frame size must be a multiple of 2\n");
1740 exit(1);
1741 }
1742}
1743
b29f97d1 1744static void opt_gop_size(const char *arg)
85f07f22
FB
1745{
1746 gop_size = atoi(arg);
1747}
1748
b29f97d1 1749static void opt_b_frames(const char *arg)
bc6caae2
J
1750{
1751 b_frames = atoi(arg);
1752 if (b_frames > FF_MAX_B_FRAMES) {
1753 fprintf(stderr, "\nCannot have more than %d B frames, increase FF_MAX_B_FRAMES.\n", FF_MAX_B_FRAMES);
1754 exit(1);
1755 } else if (b_frames < 1) {
1756 fprintf(stderr, "\nNumber of B frames must be higher than 0\n");
1757 exit(1);
1758 }
1759}
1760
b29f97d1 1761static void opt_qscale(const char *arg)
85f07f22
FB
1762{
1763 video_qscale = atoi(arg);
1764 if (video_qscale < 0 ||
1765 video_qscale > 31) {
1766 fprintf(stderr, "qscale must be >= 1 and <= 31\n");
1767 exit(1);
1768 }
1769}
1770
b29f97d1 1771static void opt_qmin(const char *arg)
9cdd6a24
MN
1772{
1773 video_qmin = atoi(arg);
1774 if (video_qmin < 0 ||
1775 video_qmin > 31) {
1776 fprintf(stderr, "qmin must be >= 1 and <= 31\n");
1777 exit(1);
1778 }
1779}
1780
b29f97d1 1781static void opt_qmax(const char *arg)
9cdd6a24
MN
1782{
1783 video_qmax = atoi(arg);
1784 if (video_qmax < 0 ||
1785 video_qmax > 31) {
1786 fprintf(stderr, "qmax must be >= 1 and <= 31\n");
1787 exit(1);
1788 }
1789}
1790
b29f97d1 1791static void opt_mb_qmin(const char *arg)
17a70fde
MN
1792{
1793 video_mb_qmin = atoi(arg);
1794 if (video_mb_qmin < 0 ||
1795 video_mb_qmin > 31) {
1796 fprintf(stderr, "qmin must be >= 1 and <= 31\n");
1797 exit(1);
1798 }
1799}
1800
b29f97d1 1801static void opt_mb_qmax(const char *arg)
17a70fde
MN
1802{
1803 video_mb_qmax = atoi(arg);
1804 if (video_mb_qmax < 0 ||
1805 video_mb_qmax > 31) {
1806 fprintf(stderr, "qmax must be >= 1 and <= 31\n");
1807 exit(1);
1808 }
1809}
1810
b29f97d1 1811static void opt_qdiff(const char *arg)
9cdd6a24
MN
1812{
1813 video_qdiff = atoi(arg);
1814 if (video_qdiff < 0 ||
1815 video_qdiff > 31) {
1816 fprintf(stderr, "qdiff must be >= 1 and <= 31\n");
1817 exit(1);
1818 }
1819}
1820
b29f97d1 1821static void opt_qblur(const char *arg)
9cdd6a24
MN
1822{
1823 video_qblur = atof(arg);
1824}
1825
b29f97d1 1826static void opt_qcomp(const char *arg)
9cdd6a24
MN
1827{
1828 video_qcomp = atof(arg);
1829}
85f07f22 1830
b29f97d1 1831static void opt_rc_initial_cplx(const char *arg)
ac2830ec
MN
1832{
1833 video_rc_initial_cplx = atof(arg);
1834}
b29f97d1 1835static void opt_b_qfactor(const char *arg)
29700fa6
MN
1836{
1837 video_b_qfactor = atof(arg);
1838}
b29f97d1 1839static void opt_i_qfactor(const char *arg)
29700fa6
MN
1840{
1841 video_i_qfactor = atof(arg);
1842}
b29f97d1 1843static void opt_b_qoffset(const char *arg)
29700fa6
MN
1844{
1845 video_b_qoffset = atof(arg);
1846}
b29f97d1 1847static void opt_i_qoffset(const char *arg)
29700fa6
MN
1848{
1849 video_i_qoffset = atof(arg);
1850}
1851
b29f97d1 1852static void opt_packet_size(const char *arg)
1dbb6d90
MN
1853{
1854 packet_size= atoi(arg);
1855}
1856
b29f97d1 1857static void opt_strict(const char *arg)
f560dd82
MN
1858{
1859 strict= atoi(arg);
1860}
1861
b29f97d1 1862static void opt_audio_bitrate(const char *arg)
85f07f22
FB
1863{
1864 audio_bit_rate = atoi(arg) * 1000;
1865}
1866
b29f97d1 1867static void opt_audio_rate(const char *arg)
85f07f22
FB
1868{
1869 audio_sample_rate = atoi(arg);
1870}
1871
b29f97d1 1872static void opt_audio_channels(const char *arg)
85f07f22
FB
1873{
1874 audio_channels = atoi(arg);
1875}
1876
b29f97d1 1877static void opt_video_device(const char *arg)
85f07f22 1878{
e9a9e0c2 1879 video_device = av_strdup(arg);
85f07f22
FB
1880}
1881
b29f97d1 1882static void opt_video_channel(const char *arg)
a5df11ab
FB
1883{
1884 video_channel = strtol(arg, NULL, 0);
1885}
1886
b29f97d1 1887static void opt_audio_device(const char *arg)
85f07f22 1888{
e9a9e0c2 1889 audio_device = av_strdup(arg);
85f07f22
FB
1890}
1891
b29f97d1 1892static void opt_dv1394(const char *arg)
8aa3ee32
MK
1893{
1894 video_grab_format = "dv1394";
1501987b 1895 audio_grab_format = NULL;
8aa3ee32
MK
1896}
1897
b29f97d1 1898static void opt_audio_codec(const char *arg)
85f07f22
FB
1899{
1900 AVCodec *p;
1901
1629626f
FB
1902 if (!strcmp(arg, "copy")) {
1903 audio_stream_copy = 1;
85f07f22 1904 } else {
1629626f
FB
1905 p = first_avcodec;
1906 while (p) {
1907 if (!strcmp(p->name, arg) && p->type == CODEC_TYPE_AUDIO)
1908 break;
1909 p = p->next;
1910 }
1911 if (p == NULL) {
1912 fprintf(stderr, "Unknown audio codec '%s'\n", arg);
1913 exit(1);
1914 } else {
1915 audio_codec_id = p->id;
1916 }
85f07f22
FB
1917 }
1918}
1919
b29f97d1 1920static void add_frame_hooker(const char *arg)
10d104e4
PG
1921{
1922 int argc = 0;
1923 char *argv[64];
1924 int i;
e9a9e0c2 1925 char *args = av_strdup(arg);
10d104e4
PG
1926
1927 argv[0] = strtok(args, " ");
1928 while (argc < 62 && (argv[++argc] = strtok(NULL, " "))) {
1929 }
1930
1931 i = frame_hook_add(argc, argv);
1932
1933 if (i != 0) {
1934 fprintf(stderr, "Failed to add video hook function: %s\n", arg);
1935 exit(1);
1936 }
1937}
1938
85f07f22
FB
1939const char *motion_str[] = {
1940 "zero",
1941 "full",
1942 "log",
1943 "phods",
7084c149
MN
1944 "epzs",
1945 "x1",
85f07f22
FB
1946 NULL,
1947};
1948
b29f97d1 1949static void opt_motion_estimation(const char *arg)
85f07f22
FB
1950{
1951 const char **p;
1952 p = motion_str;
1953 for(;;) {
1954 if (!*p) {
1955 fprintf(stderr, "Unknown motion estimation method '%s'\n", arg);
1956 exit(1);
1957 }
1958 if (!strcmp(*p, arg))
1959 break;
1960 p++;
1961 }
101bea5f 1962 me_method = (p - motion_str) + 1;
85f07f22
FB
1963}
1964
b29f97d1 1965static void opt_video_codec(const char *arg)
85f07f22
FB
1966{
1967 AVCodec *p;
1968
1629626f
FB
1969 if (!strcmp(arg, "copy")) {
1970 video_stream_copy = 1;
85f07f22 1971 } else {
1629626f
FB
1972 p = first_avcodec;
1973 while (p) {
1974 if (!strcmp(p->name, arg) && p->type == CODEC_TYPE_VIDEO)
1975 break;
1976 p = p->next;
1977 }
1978 if (p == NULL) {
1979 fprintf(stderr, "Unknown video codec '%s'\n", arg);
1980 exit(1);
1981 } else {
1982 video_codec_id = p->id;
1983 }
85f07f22
FB
1984 }
1985}
1986
b29f97d1 1987static void opt_map(const char *arg)
85f07f22
FB
1988{
1989 AVStreamMap *m;
1990 const char *p;
1991
1992 p = arg;
1993 m = &stream_maps[nb_stream_maps++];
1994
1995 m->file_index = strtol(arg, (char **)&p, 0);
1996 if (*p)
1997 p++;
a5dc85ef
J
1998
1999 m->stream_index = strtol(p, (char **)&p, 0);
85f07f22
FB
2000}
2001
b29f97d1 2002static void opt_recording_time(const char *arg)
85f07f22
FB
2003{
2004 recording_time = parse_date(arg, 1);
2005}
2006
b29f97d1 2007static void print_error(const char *filename, int err)
919f448d 2008{
79fdaa4c
FB
2009 switch(err) {
2010 case AVERROR_NUMEXPECTED:
919f448d
FB
2011 fprintf(stderr, "%s: Incorrect image filename syntax.\n"
2012 "Use '%%d' to specify the image number:\n"
2013 " for img1.jpg, img2.jpg, ..., use 'img%%d.jpg';\n"
2014 " for img001.jpg, img002.jpg, ..., use 'img%%03d.jpg'.\n",
2015 filename);
79fdaa4c
FB
2016 break;
2017 case AVERROR_INVALIDDATA:
2018 fprintf(stderr, "%s: Error while parsing header\n", filename);
2019 break;
2020 case AVERROR_NOFMT:
2021 fprintf(stderr, "%s: Unknown format\n", filename);
2022 break;
2023 default:
2024 fprintf(stderr, "%s: Error while opening file\n", filename);
2025 break;
919f448d
FB
2026 }
2027}
85f07f22 2028
b29f97d1 2029static void opt_input_file(const char *filename)
85f07f22
FB
2030{
2031 AVFormatContext *ic;
2032 AVFormatParameters params, *ap = &params;
6dc96cb0 2033 int err, i, ret, rfps;
85f07f22 2034
b242baa4
FB
2035 if (!strcmp(filename, "-"))
2036 filename = "pipe:";
2037
85f07f22 2038 /* get default parameters from command line */
79fdaa4c
FB
2039 memset(ap, 0, sizeof(*ap));
2040 ap->sample_rate = audio_sample_rate;
2041 ap->channels = audio_channels;
2042 ap->frame_rate = frame_rate;
2043 ap->width = frame_width;
2044 ap->height = frame_height;
817b23ff 2045 ap->image_format = image_format;
79fdaa4c
FB
2046
2047 /* open the input file with generic libav function */
2048 err = av_open_input_file(&ic, filename, file_iformat, 0, ap);
85f07f22 2049 if (err < 0) {
79fdaa4c 2050 print_error(filename, err);
85f07f22
FB
2051 exit(1);
2052 }
2053
79fdaa4c
FB
2054 /* If not enough info to get the stream parameters, we decode the
2055 first frames to get it. (used in mpeg case for example) */
2056 ret = av_find_stream_info(ic);
85f07f22
FB
2057 if (ret < 0) {
2058 fprintf(stderr, "%s: could not find codec parameters\n", filename);
2059 exit(1);
2060 }
2061
2062 /* update the current parameters so that they match the one of the input stream */
2063 for(i=0;i<ic->nb_streams;i++) {
2064 AVCodecContext *enc = &ic->streams[i]->codec;
2065 switch(enc->codec_type) {
2066 case CODEC_TYPE_AUDIO:
e0d2714a 2067 //fprintf(stderr, "\nInput Audio channels: %d", enc->channels);
85f07f22
FB
2068 audio_channels = enc->channels;
2069 audio_sample_rate = enc->sample_rate;
2070 break;
2071 case CODEC_TYPE_VIDEO:
2072 frame_height = enc->height;
2073 frame_width = enc->width;
79fdaa4c 2074 rfps = ic->streams[i]->r_frame_rate;
fe670d09 2075 enc->workaround_bugs = workaround_bugs;
8409b8fe 2076 enc->error_resilience = error_resilience;
4d2858de 2077 enc->error_concealment = error_concealment;
2ad1516a 2078 enc->idct_algo= idct_algo;
59b571c1 2079 enc->debug= debug;
d7425f59
MN
2080/* if(enc->codec->capabilities & CODEC_CAP_TRUNCATED)
2081 enc->flags|= CODEC_FLAG_TRUNCATED; */
2082 if(/*enc->codec_id==CODEC_ID_MPEG4 || */enc->codec_id==CODEC_ID_MPEG1VIDEO)
2083 enc->flags|= CODEC_FLAG_TRUNCATED;
b0368839
MN
2084
2085 if(bitexact)
2086 enc->flags|= CODEC_FLAG_BITEXACT;
d7425f59 2087
79fdaa4c 2088 if (enc->frame_rate != rfps) {
6dc96cb0
J
2089 fprintf(stderr,"\nSeems that stream %d comes from film source: %2.2f->%2.2f\n",
2090 i, (float)enc->frame_rate / FRAME_RATE_BASE,
2091 (float)rfps / FRAME_RATE_BASE);
79fdaa4c 2092 }
bf5af568
FB
2093 /* update the current frame rate to match the stream frame rate */
2094 frame_rate = rfps;
85f07f22 2095 break;
51bd4565 2096 default:
c04643a2 2097 av_abort();
85f07f22
FB
2098 }
2099 }
2100
2101 input_files[nb_input_files] = ic;
2102 /* dump the file content */
2103 dump_format(ic, nb_input_files, filename, 0);
2104 nb_input_files++;
79fdaa4c
FB
2105 file_iformat = NULL;
2106 file_oformat = NULL;
817b23ff 2107 image_format = NULL;
85f07f22
FB
2108}
2109
b29f97d1 2110static void check_audio_video_inputs(int *has_video_ptr, int *has_audio_ptr)
919f448d
FB
2111{
2112 int has_video, has_audio, i, j;
2113 AVFormatContext *ic;
2114
2115 has_video = 0;
2116 has_audio = 0;
2117 for(j=0;j<nb_input_files;j++) {
2118 ic = input_files[j];
2119 for(i=0;i<ic->nb_streams;i++) {
2120 AVCodecContext *enc = &ic->streams[i]->codec;
2121 switch(enc->codec_type) {
2122 case CODEC_TYPE_AUDIO:
2123 has_audio = 1;
2124 break;
2125 case CODEC_TYPE_VIDEO:
2126 has_video = 1;
2127 break;
51bd4565 2128 default:
c04643a2 2129 av_abort();
919f448d
FB
2130 }
2131 }
2132 }
2133 *has_video_ptr = has_video;
2134 *has_audio_ptr = has_audio;
2135}
2136
b29f97d1 2137static void opt_output_file(const char *filename)
85f07f22
FB
2138{
2139 AVStream *st;
2140 AVFormatContext *oc;
919f448d 2141 int use_video, use_audio, nb_streams, input_has_video, input_has_audio;
85f07f22 2142 int codec_id;
817b23ff 2143 AVFormatParameters params, *ap = &params;
85f07f22
FB
2144
2145 if (!strcmp(filename, "-"))
2146 filename = "pipe:";
2147
2148 oc = av_mallocz(sizeof(AVFormatContext));
2149
79fdaa4c
FB
2150 if (!file_oformat) {
2151 file_oformat = guess_format(NULL, filename, NULL);
2152 if (!file_oformat) {
2153 fprintf(stderr, "Unable for find a suitable output format for '%s'\n",
2154 filename);
2155 exit(1);
2156 }
85f07f22
FB
2157 }
2158
79fdaa4c 2159 oc->oformat = file_oformat;
85f07f22 2160
79fdaa4c 2161 if (!strcmp(file_oformat->name, "ffm") &&
85f07f22
FB
2162 strstart(filename, "http:", NULL)) {
2163 /* special case for files sent to ffserver: we get the stream
2164 parameters from ffserver */
2165 if (read_ffserver_streams(oc, filename) < 0) {
2166 fprintf(stderr, "Could not read stream parameters from '%s'\n", filename);
2167 exit(1);
2168 }
2169 } else {
79fdaa4c
FB
2170 use_video = file_oformat->video_codec != CODEC_ID_NONE;
2171 use_audio = file_oformat->audio_codec != CODEC_ID_NONE;
919f448d 2172
e30a2846
FB
2173 /* disable if no corresponding type found and at least one
2174 input file */
2175 if (nb_input_files > 0) {
2176 check_audio_video_inputs(&input_has_video, &input_has_audio);
2177 if (!input_has_video)
2178 use_video = 0;
2179 if (!input_has_audio)
2180 use_audio = 0;
2181 }
919f448d
FB
2182
2183 /* manual disable */
85f07f22
FB
2184 if (audio_disable) {
2185 use_audio = 0;
2186 }
2187 if (video_disable) {
2188 use_video = 0;
2189 }
2190
2191 nb_streams = 0;
2192 if (use_video) {
2193 AVCodecContext *video_enc;
2194
2195 st = av_mallocz(sizeof(AVStream));
2196 if (!st) {
2197 fprintf(stderr, "Could not alloc stream\n");
2198 exit(1);
2199 }
1e491e29 2200 avcodec_get_context_defaults(&st->codec);
85f07f22 2201
1629626f
FB
2202 video_enc = &st->codec;
2203 if (video_stream_copy) {
2204 st->stream_copy = 1;
2205 video_enc->codec_type = CODEC_TYPE_VIDEO;
2206 } else {
ac2830ec
MN
2207 char *p;
2208 int i;
2209
1629626f
FB
2210 codec_id = file_oformat->video_codec;
2211 if (video_codec_id != CODEC_ID_NONE)
2212 codec_id = video_codec_id;
2213
2214 video_enc->codec_id = codec_id;
2215
2216 video_enc->bit_rate = video_bit_rate;
2217 video_enc->bit_rate_tolerance = video_bit_rate_tolerance;
2218 video_enc->frame_rate = frame_rate;
2219
2220 video_enc->width = frame_width;
2221 video_enc->height = frame_height;
2222
2223 if (!intra_only)
2224 video_enc->gop_size = gop_size;
2225 else
2226 video_enc->gop_size = 0;
2227 if (video_qscale || same_quality) {
2228 video_enc->flags |= CODEC_FLAG_QSCALE;
1e491e29 2229 st->quality = video_qscale;
1629626f 2230 }
b0368839
MN
2231
2232 if(bitexact)
2233 video_enc->flags |= CODEC_FLAG_BITEXACT;
2234
1629626f
FB
2235 if (use_hq) {
2236 video_enc->flags |= CODEC_FLAG_HQ;
2237 }
21e59552
MN
2238 /* Fx */
2239 if (use_umv) {
2240 video_enc->flags |= CODEC_FLAG_H263P_UMV;
2241 }
2242 if (use_aic) {
2243 video_enc->flags |= CODEC_FLAG_H263P_AIC;
2244 }
2245 /* /Fx */
1629626f
FB
2246 if (use_4mv) {
2247 video_enc->flags |= CODEC_FLAG_HQ;
2248 video_enc->flags |= CODEC_FLAG_4MV;
2249 }
bc6caae2 2250
1629626f
FB
2251 if(use_part)
2252 video_enc->flags |= CODEC_FLAG_PART;
1dbb6d90
MN
2253
2254
1629626f 2255 if (b_frames) {
1629626f
FB
2256 video_enc->max_b_frames = b_frames;
2257 video_enc->b_frame_strategy = 0;
2258 video_enc->b_quant_factor = 2.0;
bc6caae2 2259 }
bc6caae2 2260
1629626f
FB
2261 video_enc->qmin = video_qmin;
2262 video_enc->qmax = video_qmax;
17a70fde
MN
2263 video_enc->mb_qmin = video_mb_qmin;
2264 video_enc->mb_qmax = video_mb_qmax;
1629626f
FB
2265 video_enc->max_qdiff = video_qdiff;
2266 video_enc->qblur = video_qblur;
2267 video_enc->qcompress = video_qcomp;
2268 video_enc->rc_eq = video_rc_eq;
59b571c1 2269 video_enc->debug= debug;
ac2830ec
MN
2270
2271 p= video_rc_override_string;
2272 for(i=0; p; i++){
2273 int start, end, q;
2274 int e=sscanf(p, "%d,%d,%d", &start, &end, &q);
2275 if(e!=3){
2276 fprintf(stderr, "error parsing rc_override\n");
2277 exit(1);
2278 }
2279 video_enc->rc_override=
47e2a6e6
FB
2280 av_realloc(video_enc->rc_override,
2281 sizeof(RcOverride)*(i+1));
ac2830ec
MN
2282 video_enc->rc_override[i].start_frame= start;
2283 video_enc->rc_override[i].end_frame = end;
2284 if(q>0){
2285 video_enc->rc_override[i].qscale= q;
2286 video_enc->rc_override[i].quality_factor= 1.0;
2287 }
2288 else{
2289 video_enc->rc_override[i].qscale= 0;
2290 video_enc->rc_override[i].quality_factor= -q/100.0;
2291 }
2292 p= strchr(p, '/');
2293 if(p) p++;
2294 }
2295 video_enc->rc_override_count=i;
2296
1629626f
FB
2297 video_enc->rc_max_rate = video_rc_max_rate;
2298 video_enc->rc_min_rate = video_rc_min_rate;
2299 video_enc->rc_buffer_size = video_rc_buffer_size;
2300 video_enc->rc_buffer_aggressivity= video_rc_buffer_aggressivity;
ac2830ec 2301 video_enc->rc_initial_cplx= video_rc_initial_cplx;
1629626f
FB
2302 video_enc->i_quant_factor = video_i_qfactor;
2303 video_enc->b_quant_factor = video_b_qfactor;
2304 video_enc->i_quant_offset = video_i_qoffset;
2305 video_enc->b_quant_offset = video_b_qoffset;
2306 video_enc->dct_algo = dct_algo;
2307 video_enc->idct_algo = idct_algo;
f560dd82 2308 video_enc->strict_std_compliance = strict;
1629626f
FB
2309 if(packet_size){
2310 video_enc->rtp_mode= 1;
2311 video_enc->rtp_payload_size= packet_size;
2312 }
9cdd6a24 2313
1629626f 2314 if (do_psnr)
140cb663 2315 video_enc->flags|= CODEC_FLAG_PSNR;
e4986da9 2316
1629626f 2317 video_enc->me_method = me_method;
5abdb4b1 2318
1629626f
FB
2319 /* two pass mode */
2320 if (do_pass) {
2321 if (do_pass == 1) {
2322 video_enc->flags |= CODEC_FLAG_PASS1;
2323 } else {
2324 video_enc->flags |= CODEC_FLAG_PASS2;
2325 }
5abdb4b1 2326 }
cfcf0ffd 2327 }
85f07f22
FB
2328 oc->streams[nb_streams] = st;
2329 nb_streams++;
2330 }
2331
2332 if (use_audio) {
2333 AVCodecContext *audio_enc;
2334
2335 st = av_mallocz(sizeof(AVStream));
2336 if (!st) {
2337 fprintf(stderr, "Could not alloc stream\n");
2338 exit(1);
2339 }
1e491e29 2340 avcodec_get_context_defaults(&st->codec);
1629626f 2341
85f07f22 2342 audio_enc = &st->codec;
85f07f22 2343 audio_enc->codec_type = CODEC_TYPE_AUDIO;
1629626f
FB
2344 if (audio_stream_copy) {
2345 st->stream_copy = 1;
2346 } else {
2347 codec_id = file_oformat->audio_codec;
2348 if (audio_codec_id != CODEC_ID_NONE)
2349 codec_id = audio_codec_id;
2350 audio_enc->codec_id = codec_id;
2351
2352 audio_enc->bit_rate = audio_bit_rate;
2353 audio_enc->sample_rate = audio_sample_rate;
2354 /* For audio codecs other than AC3 we limit */
2355 /* the number of coded channels to stereo */
2356 if (audio_channels > 2 && codec_id != CODEC_ID_AC3) {
2357 audio_enc->channels = 2;
2358 } else
2359 audio_enc->channels = audio_channels;
2360 }
85f07f22
FB
2361 oc->streams[nb_streams] = st;
2362 nb_streams++;
2363 }
2364
2365 oc->nb_streams = nb_streams;
2366
2367 if (!nb_streams) {
919f448d 2368 fprintf(stderr, "No audio or video streams available\n");
85f07f22
FB
2369 exit(1);
2370 }
2371
2372 if (str_title)
79fdaa4c 2373 pstrcpy(oc->title, sizeof(oc->title), str_title);
85f07f22 2374 if (str_author)
79fdaa4c 2375 pstrcpy(oc->author, sizeof(oc->author), str_author);
85f07f22 2376 if (str_copyright)
79fdaa4c 2377 pstrcpy(oc->copyright, sizeof(oc->copyright), str_copyright);
85f07f22 2378 if (str_comment)
79fdaa4c 2379 pstrcpy(oc->comment, sizeof(oc->comment), str_comment);
85f07f22
FB
2380 }
2381
1629626f 2382 output_files[nb_output_files++] = oc;
85f07f22
FB
2383
2384 strcpy(oc->filename, filename);
919f448d
FB
2385
2386 /* check filename in case of an image number is expected */
79fdaa4c
FB
2387 if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
2388 if (filename_number_test(oc->filename) < 0) {
2389 print_error(oc->filename, AVERROR_NUMEXPECTED);
919f448d 2390 exit(1);
79fdaa4c 2391 }
919f448d
FB
2392 }
2393
79fdaa4c 2394 if (!(oc->oformat->flags & AVFMT_NOFILE)) {
85f07f22
FB
2395 /* test if it already exists to avoid loosing precious files */
2396 if (!file_overwrite &&
2397 (strchr(filename, ':') == NULL ||
2398 strstart(filename, "file:", NULL))) {
2399 if (url_exist(filename)) {
2400 int c;
2401
2402 printf("File '%s' already exists. Overwrite ? [y/N] ", filename);
2403 fflush(stdout);
2404 c = getchar();
2405 if (toupper(c) != 'Y') {
2406 fprintf(stderr, "Not overwriting - exiting\n");
2407 exit(1);
2408 }
2409 }
2410 }
2411
2412 /* open the file */
2413 if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0) {
2414 fprintf(stderr, "Could not open '%s'\n", filename);
2415 exit(1);
2416 }
2417 }
2418
817b23ff
FB
2419 memset(ap, 0, sizeof(*ap));
2420 ap->image_format = image_format;
2421 if (av_set_parameters(oc, ap) < 0) {
2422 fprintf(stderr, "%s: Invalid encoding parameters\n",
2423 oc->filename);
2424 exit(1);
2425 }
2426
85f07f22 2427 /* reset some options */
79fdaa4c
FB
2428 file_oformat = NULL;
2429 file_iformat = NULL;
817b23ff 2430 image_format = NULL;
85f07f22
FB
2431 audio_disable = 0;
2432 video_disable = 0;
2433 audio_codec_id = CODEC_ID_NONE;
2434 video_codec_id = CODEC_ID_NONE;
1629626f
FB
2435 audio_stream_copy = 0;
2436 video_stream_copy = 0;
85f07f22
FB
2437}
2438
a38469e1 2439/* prepare dummy protocols for grab */
b29f97d1 2440static void prepare_grab(void)
a38469e1
FB
2441{
2442 int has_video, has_audio, i, j;
2443 AVFormatContext *oc;
2444 AVFormatContext *ic;
79a7c268 2445 AVFormatParameters vp1, *vp = &vp1;
a38469e1 2446 AVFormatParameters ap1, *ap = &ap1;
79a7c268 2447
a38469e1
FB
2448 /* see if audio/video inputs are needed */
2449 has_video = 0;
2450 has_audio = 0;
2451 memset(ap, 0, sizeof(*ap));
79a7c268 2452 memset(vp, 0, sizeof(*vp));
a38469e1
FB
2453 for(j=0;j<nb_output_files;j++) {
2454 oc = output_files[j];
2455 for(i=0;i<oc->nb_streams;i++) {
2456 AVCodecContext *enc = &oc->streams[i]->codec;
2457 switch(enc->codec_type) {
2458 case CODEC_TYPE_AUDIO:
2459 if (enc->sample_rate > ap->sample_rate)
2460 ap->sample_rate = enc->sample_rate;
2461 if (enc->channels > ap->channels)
2462 ap->channels = enc->channels;
2463 has_audio = 1;
2464 break;
2465 case CODEC_TYPE_VIDEO:
79a7c268
FB
2466 if (enc->width > vp->width)
2467 vp->width = enc->width;
2468 if (enc->height > vp->height)
2469 vp->height = enc->height;
2470 if (enc->frame_rate > vp->frame_rate)
2471 vp->frame_rate = enc->frame_rate;
a38469e1
FB
2472 has_video = 1;
2473 break;
51bd4565 2474 default:
c04643a2 2475 av_abort();
a38469e1
FB
2476 }
2477 }
2478 }
2479
2480 if (has_video == 0 && has_audio == 0) {
2481 fprintf(stderr, "Output file must have at least one audio or video stream\n");
2482 exit(1);
2483 }
2484
2485 if (has_video) {
79fdaa4c 2486 AVInputFormat *fmt1;
8aa3ee32 2487 fmt1 = av_find_input_format(video_grab_format);
a5df11ab
FB
2488 vp->device = video_device;
2489 vp->channel = video_channel;
79a7c268 2490 if (av_open_input_file(&ic, "", fmt1, 0, vp) < 0) {
bf5af568 2491 fprintf(stderr, "Could not find video grab device\n");
a38469e1
FB
2492 exit(1);
2493 }
79fdaa4c 2494 /* by now video grab has one stream */
79a7c268 2495 ic->streams[0]->r_frame_rate = vp->frame_rate;
a38469e1 2496 input_files[nb_input_files] = ic;
79a7c268 2497 dump_format(ic, nb_input_files, "", 0);
a38469e1
FB
2498 nb_input_files++;
2499 }
1501987b 2500 if (has_audio && audio_grab_format) {
79fdaa4c 2501 AVInputFormat *fmt1;
8aa3ee32 2502 fmt1 = av_find_input_format(audio_grab_format);
79a7c268 2503 ap->device = audio_device;
79fdaa4c 2504 if (av_open_input_file(&ic, "", fmt1, 0, ap) < 0) {
bf5af568 2505 fprintf(stderr, "Could not find audio grab device\n");
a38469e1
FB
2506 exit(1);
2507 }
2508 input_files[nb_input_files] = ic;
79a7c268 2509 dump_format(ic, nb_input_files, "", 0);
a38469e1
FB
2510 nb_input_files++;
2511 }
2512}
2513
a38469e1 2514/* open the necessary output devices for playing */
b29f97d1 2515static void prepare_play(void)
a38469e1 2516{
79a7c268 2517 int has_video, has_audio;
a38469e1 2518
79a7c268
FB
2519 check_audio_video_inputs(&has_video, &has_audio);
2520
2521 /* manual disable */
2522 if (audio_disable) {
2523 has_audio = 0;
2524 }
2525 if (video_disable) {
2526 has_video = 0;
2527 }
2528
2529 if (has_audio) {
2530 file_oformat = guess_format("audio_device", NULL, NULL);
2531 if (!file_oformat) {
2532 fprintf(stderr, "Could not find audio device\n");
2533 exit(1);
2534 }
3f07e605 2535 opt_output_file(audio_device?audio_device:"/dev/dsp");
79a7c268
FB
2536 }
2537
2538 if (has_video) {
2539 file_oformat = guess_format("framebuffer_device", NULL, NULL);
2540 if (!file_oformat) {
2541 fprintf(stderr, "Could not find framebuffer device\n");
2542 exit(1);
2543 }
2544 opt_output_file("");
2545 }
a38469e1
FB
2546}
2547
5abdb4b1 2548/* same option as mencoder */
b29f97d1 2549static void opt_pass(const char *pass_str)
5abdb4b1
FB
2550{
2551 int pass;
2552 pass = atoi(pass_str);
2553 if (pass != 1 && pass != 2) {
2554 fprintf(stderr, "pass number can be only 1 or 2\n");
2555 exit(1);
2556 }
2557 do_pass = pass;
2558}
a38469e1 2559
f3ec2d46 2560#if defined(CONFIG_WIN32) || defined(CONFIG_OS2)
0c1a9eda 2561static int64_t getutime(void)
5727b222 2562{
f3ec2d46 2563 return av_gettime();
5727b222 2564}
bdc4796f 2565#else
0c1a9eda 2566static int64_t getutime(void)
bdc4796f 2567{
f3ec2d46
SG
2568 struct rusage rusage;
2569
2570 getrusage(RUSAGE_SELF, &rusage);
2571 return (rusage.ru_utime.tv_sec * 1000000LL) + rusage.ru_utime.tv_usec;
bdc4796f
FB
2572}
2573#endif
5727b222 2574
79fdaa4c
FB
2575extern int ffm_nopts;
2576
b29f97d1 2577static void opt_bitexact(void)
79fdaa4c 2578{
b0368839 2579 bitexact=1;
79fdaa4c
FB
2580 /* disable generate of real time pts in ffm (need to be supressed anyway) */
2581 ffm_nopts = 1;
2582}
2583
b29f97d1 2584static void show_formats(void)
85f07f22 2585{
79fdaa4c
FB
2586 AVInputFormat *ifmt;
2587 AVOutputFormat *ofmt;
817b23ff 2588 AVImageFormat *image_fmt;
85f07f22
FB
2589 URLProtocol *up;
2590 AVCodec *p;
2591 const char **pp;
2592
817b23ff 2593 printf("Output audio/video file formats:");
79fdaa4c
FB
2594 for(ofmt = first_oformat; ofmt != NULL; ofmt = ofmt->next) {
2595 printf(" %s", ofmt->name);
85f07f22
FB
2596 }
2597 printf("\n");
817b23ff
FB
2598
2599 printf("Input audio/video file formats:");
79fdaa4c
FB
2600 for(ifmt = first_iformat; ifmt != NULL; ifmt = ifmt->next) {
2601 printf(" %s", ifmt->name);
85f07f22
FB
2602 }
2603 printf("\n");
2604
817b23ff
FB
2605 printf("Output image formats:");
2606 for(image_fmt = first_image_format; image_fmt != NULL;
2607 image_fmt = image_fmt->next) {
2608 if (image_fmt->img_write)
2609 printf(" %s", image_fmt->name);
2610 }
2611 printf("\n");
2612
2613 printf("Input image formats:");
2614 for(image_fmt = first_image_format; image_fmt != NULL;
2615 image_fmt = image_fmt->next) {
2616 if (image_fmt->img_read)
2617 printf(" %s", image_fmt->name);
2618 }
2619 printf("\n");
2620
85f07f22
FB
2621 printf("Codecs:\n");
2622 printf(" Encoders:");
2623 for(p = first_avcodec; p != NULL; p = p->next) {
2624 if (p->encode)
2625 printf(" %s", p->name);
2626 }
2627 printf("\n");
2628
2629 printf(" Decoders:");
2630 for(p = first_avcodec; p != NULL; p = p->next) {
2631 if (p->decode)
2632 printf(" %s", p->name);
2633 }
2634 printf("\n");
2635
2636 printf("Supported file protocols:");
2637 for(up = first_protocol; up != NULL; up = up->next)
2638 printf(" %s:", up->name);
2639 printf("\n");
2640
2641 printf("Frame size abbreviations: sqcif qcif cif 4cif\n");
2642 printf("Motion estimation methods:");
2643 pp = motion_str;
2644 while (*pp) {
2645 printf(" %s", *pp);
101bea5f 2646 if ((pp - motion_str + 1) == ME_ZERO)
85f07f22 2647 printf("(fastest)");
101bea5f 2648 else if ((pp - motion_str + 1) == ME_FULL)
85f07f22 2649 printf("(slowest)");
101bea5f 2650 else if ((pp - motion_str + 1) == ME_EPZS)
85f07f22
FB
2651 printf("(default)");
2652 pp++;
2653 }
2654 printf("\n");
2655 exit(1);
2656}
2657
2658void show_help(void)
2659{
a38469e1 2660 const char *prog;
85f07f22
FB
2661 const OptionDef *po;
2662 int i, expert;
a38469e1
FB
2663
2664 prog = do_play ? "ffplay" : "ffmpeg";
85f07f22 2665
bf5af568 2666 printf("%s version " FFMPEG_VERSION ", Copyright (c) 2000, 2001, 2002 Fabrice Bellard\n",
a38469e1
FB
2667 prog);
2668
2669 if (!do_play) {
2670 printf("usage: ffmpeg [[options] -i input_file]... {[options] outfile}...\n"
2671 "Hyper fast MPEG1/MPEG4/H263/RV and AC3/MPEG audio encoder\n");
2672 } else {
2673 printf("usage: ffplay [options] input_file...\n"
2674 "Simple audio player\n");
2675 }
2676
2677 printf("\n"
85f07f22
FB
2678 "Main options are:\n");
2679 for(i=0;i<2;i++) {
2680 if (i == 1)
2681 printf("\nAdvanced options are:\n");
2682 for(po = options; po->name != NULL; po++) {
2683 char buf[64];
2684 expert = (po->flags & OPT_EXPERT) != 0;
2685 if (expert == i) {
2686 strcpy(buf, po->name);
2687 if (po->flags & HAS_ARG) {
2688 strcat(buf, " ");
2689 strcat(buf, po->argname);
2690 }
2691 printf("-%-17s %s\n", buf, po->help);
2692 }
2693 }
2694 }
2695
2696 exit(1);
2697}
2698
2699const OptionDef options[] = {
bdc4796f
FB
2700 { "L", 0, {(void*)show_licence}, "show license" },
2701 { "h", 0, {(void*)show_help}, "show help" },
2702 { "formats", 0, {(void*)show_formats}, "show available formats, codecs, protocols, ..." },
2703 { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
817b23ff 2704 { "img", HAS_ARG, {(void*)opt_image_format}, "force image format", "img_fmt" },
bdc4796f
FB
2705 { "i", HAS_ARG, {(void*)opt_input_file}, "input file name", "filename" },
2706 { "y", OPT_BOOL, {(void*)&file_overwrite}, "overwrite output files" },
2707 { "map", HAS_ARG | OPT_EXPERT, {(void*)opt_map}, "set input stream mapping", "file:stream" },
2708 { "t", HAS_ARG, {(void*)opt_recording_time}, "set the recording time", "duration" },
2709 { "title", HAS_ARG | OPT_STRING, {(void*)&str_title}, "set the title", "string" },
2710 { "author", HAS_ARG | OPT_STRING, {(void*)&str_author}, "set the author", "string" },
2711 { "copyright", HAS_ARG | OPT_STRING, {(void*)&str_copyright}, "set the copyright", "string" },
2712 { "comment", HAS_ARG | OPT_STRING, {(void*)&str_comment}, "set the comment", "string" },
5abdb4b1
FB
2713 { "pass", HAS_ARG, {(void*)&opt_pass}, "select the pass number (1 or 2)", "n" },
2714 { "passlogfile", HAS_ARG | OPT_STRING, {(void*)&pass_logfilename}, "select two pass log file name", "file" },
85f07f22 2715 /* video options */
bdc4796f
FB
2716 { "b", HAS_ARG, {(void*)opt_video_bitrate}, "set video bitrate (in kbit/s)", "bitrate" },
2717 { "r", HAS_ARG, {(void*)opt_frame_rate}, "set frame rate (in Hz)", "rate" },
e47ec515 2718 { "em_rate", OPT_BOOL|OPT_EXPERT, {(void*)&emulate_frame_rate}, "makes img reading happen at nominal frame rate" },
bdc4796f 2719 { "s", HAS_ARG, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
ab6d194a
MN
2720 { "croptop", HAS_ARG, {(void*)opt_frame_crop_top}, "set top crop band size (in pixels)", "size" },
2721 { "cropbottom", HAS_ARG, {(void*)opt_frame_crop_bottom}, "set bottom crop band size (in pixels)", "size" },
2722 { "cropleft", HAS_ARG, {(void*)opt_frame_crop_left}, "set left crop band size (in pixels)", "size" },
2723 { "cropright", HAS_ARG, {(void*)opt_frame_crop_right}, "set right crop band size (in pixels)", "size" },
bdc4796f
FB
2724 { "g", HAS_ARG | OPT_EXPERT, {(void*)opt_gop_size}, "set the group of picture size", "gop_size" },
2725 { "intra", OPT_BOOL | OPT_EXPERT, {(void*)&intra_only}, "use only intra frames"},
2726 { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" },
2727 { "qscale", HAS_ARG | OPT_EXPERT, {(void*)opt_qscale}, "use fixed video quantiser scale (VBR)", "q" },
9cdd6a24
MN
2728 { "qmin", HAS_ARG | OPT_EXPERT, {(void*)opt_qmin}, "min video quantiser scale (VBR)", "q" },
2729 { "qmax", HAS_ARG | OPT_EXPERT, {(void*)opt_qmax}, "max video quantiser scale (VBR)", "q" },
17a70fde
MN
2730 { "mbqmin", HAS_ARG | OPT_EXPERT, {(void*)opt_mb_qmin}, "min macroblock quantiser scale (VBR)", "q" },
2731 { "mbqmax", HAS_ARG | OPT_EXPERT, {(void*)opt_mb_qmax}, "max macroblock quantiser scale (VBR)", "q" },
9cdd6a24
MN
2732 { "qdiff", HAS_ARG | OPT_EXPERT, {(void*)opt_qdiff}, "max difference between the quantiser scale (VBR)", "q" },
2733 { "qblur", HAS_ARG | OPT_EXPERT, {(void*)opt_qblur}, "video quantiser scale blur (VBR)", "blur" },
2734 { "qcomp", HAS_ARG | OPT_EXPERT, {(void*)opt_qcomp}, "video quantiser scale compression (VBR)", "compression" },
ac2830ec 2735 { "rc_init_cplx", HAS_ARG | OPT_EXPERT, {(void*)opt_rc_initial_cplx}, "initial complexity for 1-pass encoding", "complexity" },
29700fa6
MN
2736 { "b_qfactor", HAS_ARG | OPT_EXPERT, {(void*)opt_b_qfactor}, "qp factor between p and b frames", "factor" },
2737 { "i_qfactor", HAS_ARG | OPT_EXPERT, {(void*)opt_i_qfactor}, "qp factor between p and i frames", "factor" },
2738 { "b_qoffset", HAS_ARG | OPT_EXPERT, {(void*)opt_b_qoffset}, "qp offset between p and b frames", "offset" },
2739 { "i_qoffset", HAS_ARG | OPT_EXPERT, {(void*)opt_i_qoffset}, "qp offset between p and i frames", "offset" },
59b571c1 2740// { "b_strategy", HAS_ARG | OPT_EXPERT, {(void*)opt_b_strategy}, "dynamic b frame selection strategy", "strategy" },
3aa102be 2741 { "rc_eq", HAS_ARG | OPT_EXPERT, {(void*)opt_video_rc_eq}, "", "equation" },
ac2830ec 2742 { "rc_override", HAS_ARG | OPT_EXPERT, {(void*)opt_video_rc_override_string}, "Rate control override", "qualities for specific intervals" },
9cdd6a24 2743 { "bt", HAS_ARG, {(void*)opt_video_bitrate_tolerance}, "set video bitrate tolerance (in kbit/s)", "tolerance" },
3aa102be
MN
2744 { "maxrate", HAS_ARG, {(void*)opt_video_bitrate_max}, "set max video bitrate tolerance (in kbit/s)", "bitrate" },
2745 { "minrate", HAS_ARG, {(void*)opt_video_bitrate_min}, "set min video bitrate tolerance (in kbit/s)", "bitrate" },
946c8a12 2746 { "bufsize", HAS_ARG, {(void*)opt_video_buffer_size}, "set ratecontrol buffere size (in kbit)", "size" },
bf5af568 2747 { "vd", HAS_ARG | OPT_EXPERT, {(void*)opt_video_device}, "set video grab device", "device" },
a5df11ab 2748 { "vc", HAS_ARG | OPT_EXPERT, {(void*)opt_video_channel}, "set video grab channel (DV1394 only)", "channel" },
79a7c268 2749 { "dv1394", OPT_EXPERT, {(void*)opt_dv1394}, "set DV1394 grab", "" },
1629626f 2750 { "vcodec", HAS_ARG | OPT_EXPERT, {(void*)opt_video_codec}, "force video codec ('copy' to copy stream)", "codec" },
bdc4796f 2751 { "me", HAS_ARG | OPT_EXPERT, {(void*)opt_motion_estimation}, "set motion estimation method",
85f07f22 2752 "method" },
463678ac 2753 { "dct_algo", HAS_ARG | OPT_EXPERT, {(void*)opt_dct_algo}, "set dct algo", "algo" },
2ad1516a 2754 { "idct_algo", HAS_ARG | OPT_EXPERT, {(void*)opt_idct_algo}, "set idct algo", "algo" },
8409b8fe 2755 { "er", HAS_ARG | OPT_EXPERT, {(void*)opt_error_resilience}, "set error resilience", "" },
59b571c1 2756 { "ec", HAS_ARG | OPT_EXPERT, {(void*)opt_error_concealment}, "set error concealment", "" },
bc6caae2 2757 { "bf", HAS_ARG | OPT_EXPERT, {(void*)opt_b_frames}, "use 'frames' B frames (only MPEG-4)", "frames" },
e4986da9 2758 { "hq", OPT_BOOL | OPT_EXPERT, {(void*)&use_hq}, "activate high quality settings" },
29da453b 2759 { "4mv", OPT_BOOL | OPT_EXPERT, {(void*)&use_4mv}, "use four motion vector by macroblock (only MPEG-4)" },
1dbb6d90 2760 { "part", OPT_BOOL | OPT_EXPERT, {(void*)&use_part}, "use data partitioning (only MPEG-4)" },
fe670d09 2761 { "bug", HAS_ARG | OPT_EXPERT, {(void*)opt_workaround_bugs}, "workaround not auto detected encoder bugs", "param" },
1dbb6d90 2762 { "ps", HAS_ARG | OPT_EXPERT, {(void*)opt_packet_size}, "packet size", "size in bits" },
f560dd82 2763 { "strict", HAS_ARG | OPT_EXPERT, {(void*)opt_strict}, "strictness", "how strictly to follow the standarts" },
bdc4796f 2764 { "sameq", OPT_BOOL, {(void*)&same_quality},
85f07f22 2765 "use same video quality as source (implies VBR)" },
1d366fce 2766 { "debug", HAS_ARG | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" },
85f07f22 2767 /* audio options */
bdc4796f
FB
2768 { "ab", HAS_ARG, {(void*)opt_audio_bitrate}, "set audio bitrate (in kbit/s)", "bitrate", },
2769 { "ar", HAS_ARG, {(void*)opt_audio_rate}, "set audio sampling rate (in Hz)", "rate" },
2770 { "ac", HAS_ARG, {(void*)opt_audio_channels}, "set number of audio channels", "channels" },
2771 { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" },
bdc4796f 2772 { "ad", HAS_ARG | OPT_EXPERT, {(void*)opt_audio_device}, "set audio device", "device" },
1629626f 2773 { "acodec", HAS_ARG | OPT_EXPERT, {(void*)opt_audio_codec}, "force audio codec ('copy' to copy stream)", "codec" },
bdc4796f 2774 { "deinterlace", OPT_BOOL | OPT_EXPERT, {(void*)&do_deinterlace},
cfcf0ffd 2775 "deinterlace pictures" },
bdc4796f 2776 { "benchmark", OPT_BOOL | OPT_EXPERT, {(void*)&do_benchmark},
5727b222 2777 "add timings for benchmarking" },
a0663ba4
FB
2778 { "hex", OPT_BOOL | OPT_EXPERT, {(void*)&do_hex_dump},
2779 "dump each input packet" },
ce7c56c2
J
2780 { "psnr", OPT_BOOL | OPT_EXPERT, {(void*)&do_psnr}, "calculate PSNR of compressed frames" },
2781 { "vstats", OPT_BOOL | OPT_EXPERT, {(void*)&do_vstats}, "dump video coding statistics to file" },
79fdaa4c 2782 { "bitexact", OPT_EXPERT, {(void*)opt_bitexact}, "only use bit exact algorithms (for codec testing)" },
10d104e4 2783 { "vhook", HAS_ARG | OPT_EXPERT, {(void*)add_frame_hooker}, "insert video processing module", "module name and parameters" },
21e59552
MN
2784 /* Fx */
2785 { "aic", OPT_BOOL | OPT_EXPERT, {(void*)&use_aic}, "enable Advanced intra coding (h263+)" },
2786 { "umv", OPT_BOOL | OPT_EXPERT, {(void*)&use_umv}, "enable Unlimited Motion Vector (h263+)" },
2787 /* /Fx */
85f07f22
FB
2788 { NULL, },
2789};
2790
2791int main(int argc, char **argv)
2792{
2793 int optindex, i;
2794 const char *opt, *arg;
2795 const OptionDef *po;
0c1a9eda 2796 int64_t ti;
63b15e55 2797
2c4ae653 2798 av_register_all();
85f07f22 2799
a38469e1
FB
2800 /* detect if invoked as player */
2801 i = strlen(argv[0]);
2802 if (i >= 6 && !strcmp(argv[0] + i - 6, "ffplay"))
2803 do_play = 1;
2804
85f07f22
FB
2805 if (argc <= 1)
2806 show_help();
a38469e1
FB
2807
2808 /* parse options */
85f07f22
FB
2809 optindex = 1;
2810 while (optindex < argc) {
2811 opt = argv[optindex++];
2812
2813 if (opt[0] == '-' && opt[1] != '\0') {
2814 po = options;
2815 while (po->name != NULL) {
2816 if (!strcmp(opt + 1, po->name))
2817 break;
2818 po++;
2819 }
2820 if (!po->name) {
2821 fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], opt);
2822 exit(1);
2823 }
2824 arg = NULL;
10d104e4 2825 if (po->flags & HAS_ARG) {
85f07f22 2826 arg = argv[optindex++];
10d104e4
PG
2827 if (!arg) {
2828 fprintf(stderr, "%s: missing argument for option '%s'\n", argv[0], opt);
2829 exit(1);
2830 }
2831 }
85f07f22
FB
2832 if (po->flags & OPT_STRING) {
2833 char *str;
e9a9e0c2 2834 str = av_strdup(arg);
85f07f22
FB
2835 *po->u.str_arg = str;
2836 } else if (po->flags & OPT_BOOL) {
2837 *po->u.int_arg = 1;
2838 } else {
b29f97d1 2839 po->u.func_arg(arg);
85f07f22
FB
2840 }
2841 } else {
a38469e1
FB
2842 if (!do_play) {
2843 opt_output_file(opt);
2844 } else {
2845 opt_input_file(opt);
2846 }
85f07f22
FB
2847 }
2848 }
2849
2850
a38469e1
FB
2851 if (!do_play) {
2852 /* file converter / grab */
85f07f22
FB
2853 if (nb_output_files <= 0) {
2854 fprintf(stderr, "Must supply at least one output file\n");
2855 exit(1);
2856 }
a38469e1
FB
2857
2858 if (nb_input_files == 0) {
2859 prepare_grab();
5727b222 2860 }
a38469e1
FB
2861 } else {
2862 /* player */
2863 if (nb_input_files <= 0) {
2864 fprintf(stderr, "Must supply at least one input file\n");
2865 exit(1);
2866 }
2867 prepare_play();
2868 }
2869
2870 ti = getutime();
2871 av_encode(output_files, nb_output_files, input_files, nb_input_files,
2872 stream_maps, nb_stream_maps);
2873 ti = getutime() - ti;
2874 if (do_benchmark) {
2875 printf("bench: utime=%0.3fs\n", ti / 1000000.0);
85f07f22
FB
2876 }
2877
2878 /* close files */
2879 for(i=0;i<nb_output_files;i++) {
4fca59f2
ZK
2880 /* maybe av_close_output_file ??? */
2881 AVFormatContext *s = output_files[i];
2882 int j;
2883 if (!(s->oformat->flags & AVFMT_NOFILE))
2884 url_fclose(&s->pb);
2885 for(j=0;j<s->nb_streams;j++)
2886 av_free(s->streams[j]);
2887 av_free(s);
85f07f22 2888 }
79fdaa4c
FB
2889 for(i=0;i<nb_input_files;i++)
2890 av_close_input_file(input_files[i]);
85f07f22 2891
855ea723 2892 av_free_static();
db40a39a
MN
2893
2894
35e5fb06
RD
2895#ifdef POWERPC_TBL_PERFORMANCE_REPORT
2896 extern void powerpc_display_perf_report(void);
2897 powerpc_display_perf_report();
2898#endif /* POWERPC_TBL_PERFORMANCE_REPORT */
db40a39a 2899
85f07f22
FB
2900 return 0;
2901}