test
[libav.git] / ffmpeg.c
1 /*
2 * Basic user interface for ffmpeg system
3 * Copyright (c) 2000 Gerard Lantau
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <netinet/in.h>
22 #include <linux/videodev.h>
23 #include <linux/soundcard.h>
24 #include <unistd.h>
25 #include <fcntl.h>
26 #include <sys/ioctl.h>
27 #include <sys/mman.h>
28 #include <errno.h>
29 #include <sys/time.h>
30 #include <getopt.h>
31
32 #include "mpegenc.h"
33 #include "mpegvideo.h"
34
35 static AVFormat *file_format;
36 static int frame_width = 160;
37 static int frame_height = 128;
38 static int frame_rate = 25;
39 static int bit_rate = 200000;
40 static int video_disable = 0;
41
42 static const char *video_filename, *audio_filename;
43 static float recording_time = 10.0;
44 static int nb_frames;
45 static int gop_size = 12;
46 static int intra_only = 0;
47 static int audio_freq = 44100;
48 static int audio_bit_rate = 64000;
49 static int audio_disable = 0;
50 static int audio_channels = 1;
51
52 static long long time_start;
53
54
55 static int file_read_picture(AVEncodeContext *s,
56 UINT8 *picture[3],
57 int width, int height,
58 int picture_number)
59 {
60 FILE *f;
61 char buf[1024];
62 static int init = 0;
63 static UINT8 *pict[3];
64 if (!init) {
65 pict[0] = malloc(width * height);
66 pict[1] = malloc(width * height / 4);
67 pict[2] = malloc(width * height / 4);
68 init = 1;
69 }
70
71 picture[0] = pict[0];
72 picture[1] = pict[1];
73 picture[2] = pict[2];
74
75 sprintf(buf, "%s%d.Y", video_filename, picture_number);
76 f=fopen(buf, "r");
77 if (!f) {
78 return -1;
79 }
80
81 fread(picture[0], 1, width * height, f);
82 fclose(f);
83
84 sprintf(buf, "%s%d.U", video_filename, picture_number);
85 f=fopen(buf, "r");
86 if (!f) {
87 perror(buf);
88 exit(1);
89 }
90 fread(picture[1], 1, width * height / 4, f);
91 fclose(f);
92
93 sprintf(buf, "%s%d.V", video_filename, picture_number);
94 f=fopen(buf, "r");
95 if (!f) {
96 perror(buf);
97 exit(1);
98 }
99 fread(picture[2], 1, width * height / 4, f);
100 fclose(f);
101 return 0;
102 }
103
104 static void display_stats(AVEncodeContext *video_ctx,
105 AVEncodeContext *audio_ctx,
106 int batch_mode, int the_end)
107 {
108 if (video_ctx &&
109 ((video_ctx->frame_number % video_ctx->rate) == 0 ||
110 the_end)) {
111 float ti;
112
113 if (batch_mode) {
114 ti = (float)video_ctx->frame_number / video_ctx->rate;
115 } else {
116 ti = (gettime() - time_start) / 1000000.0;
117 if (ti < 0.1)
118 ti = 0.1;
119 }
120
121 fprintf(stderr,
122 "frame=%5d size=%8dkB time=%0.1f fps=%4.1f bitrate=%6.1fkbits/s q=%2d\r",
123 video_ctx->frame_number,
124 data_out_size / 1024,
125 ti,
126 video_ctx->frame_number / ti,
127 (data_out_size * 8 / ti / 1000),
128 ((MpegEncContext *)video_ctx->priv_data)->qscale);
129 if (the_end) {
130 fprintf(stderr,"\n");
131 }
132 fflush(stderr);
133 }
134 #if 0
135 if (the_end && batch_mode && audio_ctx) {
136 duration = (gettime() - ti) / 1000000.0;
137 factor = 0;
138 if (ti > 0) {
139 factor = (float)nb_samples / s->sample_rate / duration;
140 }
141 fprintf(stderr, "%0.1f seconds compressed in %0.1f seconds (speed factor: %0.1f)\n",
142 (float)nb_samples / s->sample_rate,
143 duration,
144 factor);
145 }
146 #endif
147 }
148
149 void raw_write_data(void *opaque,
150 unsigned char *buf, int size)
151 {
152 FILE *outfile = opaque;
153 fwrite(buf, 1, size, outfile);
154 data_out_size += size;
155 }
156
157 int raw_seek(void *opaque, long long offset, int whence)
158 {
159 FILE *outfile = opaque;
160 fseek(outfile, offset, whence);
161 return 0;
162 }
163
164 static void av_encode(AVFormatContext *ctx,
165 const char *video_filename,
166 const char *audio_filename)
167 {
168 UINT8 audio_buffer[4096];
169 UINT8 video_buffer[128*1024];
170 char buf[256];
171 short *samples;
172 int ret;
173 int audio_fd;
174 FILE *infile;
175 int sample_count;
176 int batch_mode;
177 AVEncodeContext *audio_enc, *video_enc;
178 int frame_size, frame_bytes;
179 AVEncoder *audio_encoder, *video_encoder;
180 UINT8 *picture[3];
181
182 /* audio */
183 audio_enc = ctx->audio_enc;
184 sample_count = 0;
185 infile = NULL;
186 frame_size = 0;
187 samples = NULL;
188 audio_fd = -1;
189 frame_bytes = 0;
190 batch_mode = 0;
191 if (audio_filename ||
192 video_filename)
193 batch_mode = 1;
194
195 if (audio_enc) {
196 if (batch_mode) {
197 if (!audio_filename) {
198 fprintf(stderr, "Must give audio input file\n");
199 exit(1);
200 }
201 infile = fopen(audio_filename, "r");
202 if (!infile) {
203 fprintf(stderr, "Could not open '%s'\n", audio_filename);
204 exit(1);
205 }
206 audio_fd = -1;
207 } else {
208 audio_fd = audio_open(audio_enc->rate, audio_enc->channels);
209 if (audio_fd < 0) {
210 fprintf(stderr, "Could not open audio device\n");
211 exit(1);
212 }
213 }
214
215 audio_encoder = avencoder_find(ctx->format->audio_codec);
216 if (avencoder_open(audio_enc, audio_encoder) < 0) {
217 fprintf(stderr, "Audio encoder: incorrect audio frequency or bitrate\n");
218 exit(1);
219 }
220 avencoder_string(buf, sizeof(buf), audio_enc);
221 fprintf(stderr, " %s\n", buf);
222
223 frame_size = audio_enc->frame_size;
224
225 frame_bytes = frame_size * 2 * audio_enc->channels;
226 samples = malloc(frame_bytes);
227 }
228
229 /* video */
230 video_enc = ctx->video_enc;
231 if (video_enc) {
232 if (batch_mode) {
233 if (!video_filename) {
234 fprintf(stderr, "Must give video input file\n");
235 exit(1);
236 }
237 } else {
238 ret = v4l_init(video_enc->rate, video_enc->width, video_enc->height);
239 if (ret < 0) {
240 fprintf(stderr,"Could not init video 4 linux capture\n");
241 exit(1);
242 }
243 }
244
245 video_encoder = avencoder_find(ctx->format->video_codec);
246 if (avencoder_open(video_enc, video_encoder) < 0) {
247 fprintf(stderr, "Error while initializing video codec\n");
248 exit(1);
249 }
250
251 avencoder_string(buf, sizeof(buf), video_enc);
252 fprintf(stderr, " %s\n", buf);
253 }
254
255 ctx->format->write_header(ctx);
256 time_start = gettime();
257
258 for(;;) {
259 /* read & compression audio frames */
260 if (audio_enc) {
261 if (!batch_mode) {
262 for(;;) {
263 ret = read(audio_fd, samples, frame_bytes);
264 if (ret != frame_bytes)
265 break;
266 ret = avencoder_encode(audio_enc,
267 audio_buffer, sizeof(audio_buffer), samples);
268 ctx->format->write_audio_frame(ctx, audio_buffer, ret);
269 }
270 } else {
271 if (video_enc)
272 sample_count += audio_enc->rate / video_enc->rate;
273 else
274 sample_count += frame_size;
275 while (sample_count > frame_size) {
276 if (fread(samples, 1, frame_bytes, infile) == 0)
277 goto the_end;
278
279 ret = avencoder_encode(audio_enc,
280 audio_buffer, sizeof(audio_buffer), samples);
281 ctx->format->write_audio_frame(ctx, audio_buffer, ret);
282
283 sample_count -= frame_size;
284 }
285 }
286 }
287
288 if (video_enc) {
289 /* read video image */
290 if (batch_mode) {
291 ret = file_read_picture (video_enc, picture,
292 video_enc->width, video_enc->height,
293 video_enc->frame_number);
294 } else {
295 ret = v4l_read_picture (picture,
296 video_enc->width, video_enc->height,
297 video_enc->frame_number);
298 }
299 if (ret < 0)
300 break;
301 ret = avencoder_encode(video_enc, video_buffer, sizeof(video_buffer), picture);
302 ctx->format->write_video_picture(ctx, video_buffer, ret);
303 }
304
305 display_stats(video_enc, NULL, batch_mode, 0);
306 if (video_enc && video_enc->frame_number >= nb_frames)
307 break;
308 }
309 the_end:
310 display_stats(video_enc, NULL, batch_mode, 1);
311
312 if (video_enc)
313 avencoder_close(video_enc);
314
315 if (audio_enc)
316 avencoder_close(audio_enc);
317
318 ctx->format->write_trailer(ctx);
319
320 if (!infile) {
321 close(audio_fd);
322 } else {
323 fclose(infile);
324 }
325 }
326
327 typedef struct {
328 const char *str;
329 int width, height;
330 } SizeEntry;
331
332 SizeEntry sizes[] = {
333 { "sqcif", 128, 96 },
334 { "qcif", 176, 144 },
335 { "cif", 352, 288 },
336 { "4cif", 704, 576 },
337 };
338
339 enum {
340 OPT_AR=256,
341 OPT_AB,
342 OPT_AN,
343 OPT_AC,
344 OPT_VN,
345 };
346
347 struct option long_options[] =
348 {
349 { "ar", required_argument, NULL, OPT_AR },
350 { "ab", required_argument, NULL, OPT_AB },
351 { "an", no_argument, NULL, OPT_AN },
352 { "ac", required_argument, NULL, OPT_AC },
353 { "vn", no_argument, NULL, OPT_VN },
354 };
355
356 enum {
357 OUT_FILE,
358 OUT_PIPE,
359 OUT_UDP,
360 };
361
362
363 void help(void)
364 {
365 AVFormat *f;
366
367 printf("ffmpeg version 1.0, Copyright (c) 2000 Gerard Lantau\n"
368 "usage: ffmpeg [options] outfile [video_infile] [audio_infile]\n"
369 "Hyper fast MPEG1 video/H263/RV and AC3/MPEG audio layer 2 encoder\n"
370 "\n"
371 "Main options are:\n"
372 "\n"
373 "-L print the LICENSE\n"
374 "-s size set frame size [%dx%d]\n"
375 "-f format set encoding format [%s]\n"
376 "-r fps set frame rate [%d]\n"
377 "-b bitrate set the total bitrate in kbit/s [%d]\n"
378 "-t time set recording time in seconds [%0.1f]\n"
379 "-ar freq set the audio sampling freq [%d]\n"
380 "-ab bitrate set the audio bitrate in kbit/s [%d]\n"
381 "-ac channels set the number of audio channels [%d]\n"
382 "-an disable audio recording [%s]\n"
383 "-vn disable video recording [%s]\n"
384 "\n"
385 "Frame sizes abbreviations: sqcif qcif cif 4cif\n",
386 frame_width, frame_height,
387 file_format->name,
388 frame_rate,
389 bit_rate / 1000,
390 recording_time,
391 audio_freq,
392 audio_bit_rate / 1000,
393 audio_channels,
394 audio_disable ? "yes" : "no",
395 video_disable ? "yes" : "no");
396
397 printf("Encoding video formats:");
398 for(f = first_format; f != NULL; f = f->next)
399 printf(" %s", f->name);
400 printf("\n");
401
402 printf("outfile can be a file name, - (pipe) or 'udp:host:port'\n"
403 "\n"
404 "Advanced options are:\n"
405 "-d device set video4linux device name\n"
406 "-g gop_size set the group of picture size [%d]\n"
407 "-i use only intra frames [%s]\n"
408 "-c comment set the comment string\n"
409 "\n",
410 gop_size,
411 intra_only ? "yes" : "no");
412 }
413
414 void licence(void)
415 {
416 printf(
417 "ffmpeg version 1.0\n"
418 "Copyright (c) 2000 Gerard Lantau\n"
419 "This program is free software; you can redistribute it and/or modify\n"
420 "it under the terms of the GNU General Public License as published by\n"
421 "the Free Software Foundation; either version 2 of the License, or\n"
422 "(at your option) any later version.\n"
423 "\n"
424 "This program is distributed in the hope that it will be useful,\n"
425 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
426 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
427 "GNU General Public License for more details.\n"
428 "\n"
429 "You should have received a copy of the GNU General Public License\n"
430 "along with this program; if not, write to the Free Software\n"
431 "Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n"
432 );
433 }
434
435 static unsigned char output_buffer[32768];
436
437 int main(int argc, char **argv)
438 {
439 AVEncodeContext video_enc1, *video_enc = &video_enc1;
440 AVEncodeContext audio_enc1, *audio_enc = &audio_enc1;
441 UDPContext udp_ctx1, *udp_ctx = &udp_ctx1;
442 AVFormatContext av_ctx1, *av_ctx = &av_ctx1;
443 FILE *outfile;
444 int i, c;
445 char *filename;
446 int output_type;
447 int use_video, use_audio;
448
449 register_avencoder(&ac3_encoder);
450 register_avencoder(&mp2_encoder);
451 register_avencoder(&mpeg1video_encoder);
452 register_avencoder(&h263_encoder);
453 register_avencoder(&rv10_encoder);
454 register_avencoder(&mjpeg_encoder);
455
456 register_avformat(&mp2_format);
457 register_avformat(&ac3_format);
458 register_avformat(&mpeg1video_format);
459 register_avformat(&h263_format);
460 register_avformat(&mpeg_mux_format);
461 register_avformat(&ra_format);
462 register_avformat(&rm_format);
463 register_avformat(&asf_format);
464 register_avformat(&mpjpeg_format);
465 register_avformat(&swf_format);
466
467 file_format = NULL;
468
469 for(;;) {
470 c = getopt_long_only(argc, argv, "s:f:r:b:t:hd:g:ic:L",
471 long_options, NULL);
472 if (c == -1)
473 break;
474 switch(c) {
475 case 'L':
476 licence();
477 exit(1);
478 case 'h':
479 help();
480 exit(1);
481 case 's':
482 {
483 int n = sizeof(sizes) / sizeof(SizeEntry);
484 const char *p;
485
486 for(i=0;i<n;i++) {
487 if (!strcmp(sizes[i].str, optarg)) {
488 frame_width = sizes[i].width;
489 frame_height = sizes[i].height;
490 break;
491 }
492 }
493 if (i == n) {
494 p = optarg;
495 frame_width = strtol(p, (char **)&p, 10);
496 if (*p)
497 p++;
498 frame_height = strtol(p, (char **)&p, 10);
499 }
500 }
501 break;
502 case 'f':
503 {
504 AVFormat *f;
505 f = first_format;
506 while (f != NULL && strcmp(f->name, optarg) != 0) f = f->next;
507 if (f == NULL) {
508 fprintf(stderr, "Invalid format: %s\n", optarg);
509 exit(1);
510 }
511 file_format = f;
512 }
513 break;
514 case 'r':
515 {
516 frame_rate = atoi(optarg);
517 }
518 break;
519 case 'b':
520 {
521 bit_rate = atoi(optarg) * 1000;
522 }
523 break;
524 case 't':
525 {
526 recording_time = atof(optarg);
527 break;
528 }
529 /* audio specific */
530 case OPT_AR:
531 {
532 audio_freq = atoi(optarg);
533 break;
534 }
535 case OPT_AB:
536 {
537 audio_bit_rate = atoi(optarg) * 1000;
538 break;
539 }
540 case OPT_AN:
541 audio_disable = 1;
542 break;
543 case OPT_VN:
544 video_disable = 1;
545 break;
546 case OPT_AC:
547 {
548 audio_channels = atoi(optarg);
549 if (audio_channels != 1 &&
550 audio_channels != 2) {
551 fprintf(stderr, "Incorrect number of channels: %d\n", audio_channels);
552 exit(1);
553 }
554 }
555 break;
556 /* advanced options */
557 case 'd':
558 v4l_device = optarg;
559 break;
560 case 'g':
561 gop_size = atoi(optarg);
562 break;
563 case 'i':
564 intra_only = 1;
565 break;
566 case 'c':
567 comment_string = optarg;
568 break;
569 default:
570 exit(2);
571 }
572 }
573
574 if (optind >= argc) {
575 help();
576 exit(1);
577 }
578
579 filename = argv[optind++];
580 video_filename = NULL;
581 audio_filename = NULL;
582
583 /* auto detect format */
584 if (file_format == NULL)
585 file_format = guess_format(NULL, filename, NULL);
586
587 if (file_format == NULL)
588 file_format = &mpeg_mux_format;
589
590 /* check parameters */
591 if (frame_width <= 0 || frame_height <= 0) {
592 fprintf(stderr, "Incorrect frame size\n");
593 exit(1);
594 }
595 if ((frame_width % 16) != 0 || (frame_height % 16) != 0) {
596 fprintf(stderr, "Frame size must be a multiple of 16\n");
597 exit(1);
598 }
599
600 if (bit_rate < 5000 || bit_rate >= 10000000) {
601 fprintf(stderr, "Invalid bit rate\n");
602 exit(1);
603 }
604
605 if (frame_rate < 1 || frame_rate >= 60) {
606 fprintf(stderr, "Invalid frame rate\n");
607 exit(1);
608 }
609
610 nb_frames = (int)(recording_time * frame_rate);
611 if (nb_frames < 1) {
612 fprintf(stderr, "Invalid recording time\n");
613 exit(1);
614 }
615
616 use_video = file_format->video_codec != CODEC_ID_NONE;
617 use_audio = file_format->audio_codec != CODEC_ID_NONE;
618 if (audio_disable) {
619 use_audio = 0;
620 }
621 if (video_disable) {
622 use_video = 0;
623 }
624
625 if (use_video == 0 && use_audio == 0) {
626 fprintf(stderr, "No audio or video selected\n");
627 exit(1);
628 }
629
630 fprintf(stderr, "Recording: %s, %0.1f seconds\n",
631 file_format->name,
632 recording_time);
633
634 /* open output media */
635
636 if (strstart(filename, "udp:", NULL)) {
637 output_type = OUT_UDP;
638 outfile = NULL;
639 memset(udp_ctx, 0, sizeof(*udp_ctx));
640 if (udp_tx_open(udp_ctx, filename, 0) < 0) {
641 fprintf(stderr, "Could not open UDP socket\n");
642 exit(1);
643 }
644 } else if (!strcmp(filename, "-")) {
645 output_type = OUT_PIPE;
646 outfile = stdout;
647 } else {
648 output_type = OUT_FILE;
649 outfile = fopen(filename, "w");
650 if (!outfile) {
651 perror(filename);
652 exit(1);
653 }
654 }
655
656 av_ctx->video_enc = NULL;
657 av_ctx->audio_enc = NULL;
658
659 if (output_type == OUT_UDP) {
660 init_put_byte(&av_ctx->pb, output_buffer, sizeof(output_buffer),
661 udp_ctx, udp_write_data, NULL);
662 } else {
663 init_put_byte(&av_ctx->pb, output_buffer, sizeof(output_buffer),
664 outfile, raw_write_data, raw_seek);
665 }
666
667 if (use_video) {
668 if (optind < argc) {
669 video_filename = argv[optind++];
670 }
671 /* init mpeg video encoding context */
672 memset(video_enc, 0, sizeof(*video_enc));
673 video_enc->bit_rate = bit_rate;
674 video_enc->rate = frame_rate;
675
676 video_enc->width = frame_width;
677 video_enc->height = frame_height;
678 if (!intra_only)
679 video_enc->gop_size = gop_size;
680 else
681 video_enc->gop_size = 0;
682
683 av_ctx->video_enc = video_enc;
684 av_ctx->format = file_format;
685 }
686
687 if (use_audio) {
688 if (optind < argc) {
689 audio_filename = argv[optind++];
690 }
691 audio_enc->bit_rate = audio_bit_rate;
692 audio_enc->rate = audio_freq;
693 audio_enc->channels = audio_channels;
694 av_ctx->audio_enc = audio_enc;
695 }
696 av_ctx->format = file_format;
697 av_ctx->is_streamed = 0;
698
699 av_encode(av_ctx, video_filename, audio_filename);
700
701 /* close output media */
702
703 switch(output_type) {
704 case OUT_FILE:
705 fclose(outfile);
706 break;
707 case OUT_PIPE:
708 break;
709 case OUT_UDP:
710 udp_tx_close(udp_ctx);
711 break;
712 }
713 fprintf(stderr, "\n");
714
715 return 0;
716 }
717