]> git.sesse.net Git - ffmpeg/blobdiff - ffmpeg.c
av_log(NULL,... -> av_log(avctx,.. where appropriate.
[ffmpeg] / ffmpeg.c
index 445498615c460551da1ba7bc23cfc833eb3e9b8c..cdc78ea5d2dff41bb386726b19a789299adfd70d 100644 (file)
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -2,21 +2,24 @@
  * FFmpeg main
  * Copyright (c) 2000-2003 Fabrice Bellard
  *
- * This library is free software; you can redistribute it and/or
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * version 2.1 of the License, or (at your option) any later version.
  *
- * This library is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #define HAVE_AV_CONFIG_H
+#include <signal.h>
 #include <limits.h>
 #include "avformat.h"
 #include "swscale.h"
 #include "opt.h"
 #include "fifo.h"
 
-#ifndef __MINGW32__
+#ifdef __MINGW32__
+#include <conio.h>
+#else
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
 #include <sys/time.h>
 #include <termios.h>
 #include <sys/resource.h>
-#include <signal.h>
 #endif
 #ifdef CONFIG_OS2
 #include <sys/types.h>
@@ -89,7 +93,6 @@ static int nb_meta_data_maps;
 
 static AVInputFormat *file_iformat;
 static AVOutputFormat *file_oformat;
-static AVImageFormat *image_format;
 static int frame_width  = 0;
 static int frame_height = 0;
 static float frame_aspect_ratio = 0;
@@ -291,10 +294,13 @@ typedef struct AVInputFile {
 
 /* init terminal so that we can grab keys */
 static struct termios oldtty;
+#endif
 
 static void term_exit(void)
 {
+#ifndef __MINGW32__
     tcsetattr (0, TCSANOW, &oldtty);
+#endif
 }
 
 static volatile sig_atomic_t received_sigterm = 0;
@@ -308,6 +314,7 @@ sigterm_handler(int sig)
 
 static void term_init(void)
 {
+#ifndef __MINGW32__
     struct termios tty;
 
     tcgetattr (0, &tty);
@@ -323,9 +330,10 @@ static void term_init(void)
     tty.c_cc[VTIME] = 0;
 
     tcsetattr (0, TCSANOW, &tty);
+    signal(SIGQUIT, sigterm_handler); /* Quit (POSIX).  */
+#endif
 
     signal(SIGINT , sigterm_handler); /* Interrupt (ANSI).  */
-    signal(SIGQUIT, sigterm_handler); /* Quit (POSIX).  */
     signal(SIGTERM, sigterm_handler); /* Termination (ANSI).  */
     /*
     register a function to be called at normal program termination
@@ -339,6 +347,10 @@ static void term_init(void)
 /* read a key without blocking */
 static int read_key(void)
 {
+#ifdef __MINGW32__
+    if(kbhit())
+        return(getch());
+#else
     int n = 1;
     unsigned char ch;
 #ifndef CONFIG_BEOS_NETSERVER
@@ -358,6 +370,7 @@ static int read_key(void)
 
         return n;
     }
+#endif
     return -1;
 }
 
@@ -366,26 +379,6 @@ static int decode_interrupt_cb(void)
     return q_pressed || (q_pressed = read_key() == 'q');
 }
 
-#else
-
-static volatile int received_sigterm = 0;
-
-/* no interactive support */
-static void term_exit(void)
-{
-}
-
-static void term_init(void)
-{
-}
-
-static int read_key(void)
-{
-    return 0;
-}
-
-#endif
-
 static int read_ffserver_streams(AVFormatContext *s, const char *filename)
 {
     int i, err;
@@ -499,7 +492,7 @@ static void do_audio_out(AVFormatContext *s,
                 assert(ost->audio_resample);
                 if(verbose > 2)
                     fprintf(stderr, "compensating audio timestamp drift:%f compensation:%d in:%d\n", delta, comp, enc->sample_rate);
-//                fprintf(stderr, "drift:%f len:%d opts:%lld ipts:%lld fifo:%d\n", delta, -1, ost->sync_opts, (int64_t)(get_sync_ipts(ost) * enc->sample_rate), av_fifo_size(&ost->fifo)/(ost->st->codec->channels * 2));
+//                fprintf(stderr, "drift:%f len:%d opts:%"PRId64" ipts:%"PRId64" fifo:%d\n", delta, -1, ost->sync_opts, (int64_t)(get_sync_ipts(ost) * enc->sample_rate), av_fifo_size(&ost->fifo)/(ost->st->codec->channels * 2));
                 av_resample_compensate(*(struct AVResampleContext**)ost->resample, comp, enc->sample_rate);
             }
         }
@@ -719,7 +712,7 @@ static void do_video_out(AVFormatContext *s,
             nb_frames = 0;
         else if (vdelta > 1.1)
             nb_frames = lrintf(vdelta);
-//fprintf(stderr, "vdelta:%f, ost->sync_opts:%lld, ost->sync_ipts:%f nb_frames:%d\n", vdelta, ost->sync_opts, ost->sync_ipts, nb_frames);
+//fprintf(stderr, "vdelta:%f, ost->sync_opts:%"PRId64", ost->sync_ipts:%f nb_frames:%d\n", vdelta, ost->sync_opts, ost->sync_ipts, nb_frames);
         if (nb_frames == 0){
             ++nb_frames_drop;
             if (verbose>2)
@@ -819,7 +812,7 @@ static void do_video_out(AVFormatContext *s,
 //            big_picture.pts = AV_NOPTS_VALUE;
             big_picture.pts= ost->sync_opts;
 //            big_picture.pts= av_rescale(ost->sync_opts, AV_TIME_BASE*(int64_t)enc->time_base.num, enc->time_base.den);
-//av_log(NULL, AV_LOG_DEBUG, "%lld -> encoder\n", ost->sync_opts);
+//av_log(NULL, AV_LOG_DEBUG, "%"PRId64" -> encoder\n", ost->sync_opts);
             ret = avcodec_encode_video(enc,
                                        bit_buffer, bit_buffer_size,
                                        &big_picture);
@@ -833,7 +826,7 @@ static void do_video_out(AVFormatContext *s,
                 pkt.size= ret;
                 if(enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE)
                     pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);
-/*av_log(NULL, AV_LOG_DEBUG, "encoder -> %lld/%lld\n",
+/*av_log(NULL, AV_LOG_DEBUG, "encoder -> %"PRId64"/%"PRId64"\n",
    pkt.pts != AV_NOPTS_VALUE ? av_rescale(pkt.pts, enc->time_base.den, AV_TIME_BASE*(int64_t)enc->time_base.num) : -1,
    pkt.dts != AV_NOPTS_VALUE ? av_rescale(pkt.dts, enc->time_base.den, AV_TIME_BASE*(int64_t)enc->time_base.num) : -1);*/
 
@@ -888,7 +881,7 @@ static void do_video_stats(AVFormatContext *os, AVOutputStream *ost,
         }
     }
 
-    ti = MAXINT64;
+    ti = INT64_MAX;
     enc = ost->st->codec;
     if (enc->codec_type == CODEC_TYPE_VIDEO) {
         frame_number = ost->frame_number;
@@ -1423,6 +1416,10 @@ static int av_encode(AVFormatContext **output_files,
     nb_ostreams = 0;
     for(i=0;i<nb_output_files;i++) {
         os = output_files[i];
+        if (!os->nb_streams) {
+            fprintf(stderr, "Output file does not contain any stream\n");
+            exit(1);
+        }
         nb_ostreams += os->nb_streams;
     }
     if (nb_stream_maps > 0 && nb_stream_maps != nb_ostreams) {
@@ -1533,7 +1530,10 @@ static int av_encode(AVFormatContext **output_files,
             codec->bit_rate = icodec->bit_rate;
             codec->extradata= icodec->extradata;
             codec->extradata_size= icodec->extradata_size;
-            codec->time_base = icodec->time_base;
+            if(av_q2d(icodec->time_base) > av_q2d(ist->st->time_base) && av_q2d(ist->st->time_base) < 1.0/1000)
+                codec->time_base = icodec->time_base;
+            else
+                codec->time_base = ist->st->time_base;
             switch(codec->codec_type) {
             case CODEC_TYPE_AUDIO:
                 codec->sample_rate = icodec->sample_rate;
@@ -1824,12 +1824,10 @@ static int av_encode(AVFormatContext **output_files,
         }
     }
 
-#ifndef __MINGW32__
     if ( !using_stdin && verbose >= 0) {
         fprintf(stderr, "Press [q] to stop encoding\n");
         url_set_interrupt_cb(decode_interrupt_cb);
     }
-#endif
     term_init();
 
     stream_no_data = 0;
@@ -1919,10 +1917,10 @@ static int av_encode(AVFormatContext **output_files,
         if (ist->discard)
             goto discard_packet;
 
-//        fprintf(stderr, "next:%lld dts:%lld off:%lld %d\n", ist->next_pts, pkt.dts, input_files_ts_offset[ist->file_index], ist->st->codec->codec_type);
+//        fprintf(stderr, "next:%"PRId64" dts:%"PRId64" off:%"PRId64" %d\n", ist->next_pts, pkt.dts, input_files_ts_offset[ist->file_index], ist->st->codec->codec_type);
         if (pkt.dts != AV_NOPTS_VALUE && ist->next_pts != AV_NOPTS_VALUE) {
             int64_t delta= av_rescale_q(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q) - ist->next_pts;
-            if(ABS(delta) > 1LL*dts_delta_threshold*AV_TIME_BASE && !copy_ts){
+            if(FFABS(delta) > 1LL*dts_delta_threshold*AV_TIME_BASE && !copy_ts){
                 input_files_ts_offset[ist->file_index]-= delta;
                 if (verbose > 2)
                     fprintf(stderr, "timestamp discontinuity %"PRId64", new offset= %"PRId64"\n", delta, input_files_ts_offset[ist->file_index]);
@@ -2050,21 +2048,6 @@ int file_read(const char *filename)
 }
 #endif
 
-static void opt_image_format(const char *arg)
-{
-    AVImageFormat *f;
-
-    for(f = first_image_format; f != NULL; f = f->next) {
-        if (!strcmp(arg, f->name))
-            break;
-    }
-    if (!f) {
-        fprintf(stderr, "Unknown image format: '%s'\n", arg);
-        exit(1);
-    }
-    image_format = f;
-}
-
 static void opt_format(const char *arg)
 {
     /* compatibility stuff for pgmyuv */
@@ -2584,7 +2567,6 @@ static void opt_input_file(const char *filename)
     ap->time_base.num = frame_rate_base;
     ap->width = frame_width + frame_padleft + frame_padright;
     ap->height = frame_height + frame_padtop + frame_padbottom;
-    ap->image_format = image_format;
     ap->pix_fmt = frame_pix_fmt;
     ap->device  = grab_device;
     ap->channel = video_channel;
@@ -2676,7 +2658,7 @@ static void opt_input_file(const char *filename)
             if (enc->time_base.den != rfps || enc->time_base.num != rfps_base) {
 
                 if (verbose >= 0)
-                    fprintf(stderr,"\nSeems that stream %d comes from film source: %2.2f (%d/%d) -> %2.2f (%d/%d)\n",
+                    fprintf(stderr,"\nSeems stream %d codec frame rate differs from container frame rate: %2.2f (%d/%d) -> %2.2f (%d/%d)\n",
                             i, (float)enc->time_base.den / enc->time_base.num, enc->time_base.den, enc->time_base.num,
 
                     (float)rfps / rfps_base, rfps, rfps_base);
@@ -2711,7 +2693,6 @@ static void opt_input_file(const char *filename)
     nb_input_files++;
     file_iformat = NULL;
     file_oformat = NULL;
-    image_format = NULL;
 
     grab_device = NULL;
     video_channel = 0;
@@ -2940,6 +2921,7 @@ static void new_audio_stream(AVFormatContext *oc)
 
     audio_enc = st->codec;
     audio_enc->codec_type = CODEC_TYPE_AUDIO;
+    audio_enc->strict_std_compliance = strict;
 
     if(audio_codec_tag)
         audio_enc->codec_tag= audio_codec_tag;
@@ -2970,7 +2952,6 @@ static void new_audio_stream(AVFormatContext *oc)
             audio_enc->flags |= CODEC_FLAG_QSCALE;
             audio_enc->global_quality = st->quality = FF_QP2LAMBDA * audio_qscale;
         }
-        audio_enc->strict_std_compliance = strict;
         audio_enc->thread_count = thread_count;
         /* For audio codecs other than AC3 or DTS we limit */
         /* the number of coded channels to stereo   */
@@ -3120,11 +3101,6 @@ static void opt_output_file(const char *filename)
             new_audio_stream(oc);
         }
 
-        if (!oc->nb_streams) {
-            fprintf(stderr, "No audio or video streams available\n");
-            exit(1);
-        }
-
         oc->timestamp = rec_timestamp;
 
         if (str_title)
@@ -3181,7 +3157,6 @@ static void opt_output_file(const char *filename)
     }
 
     memset(ap, 0, sizeof(*ap));
-    ap->image_format = image_format;
     if (av_set_parameters(oc, ap) < 0) {
         fprintf(stderr, "%s: Invalid encoding parameters\n",
                 oc->filename);
@@ -3202,7 +3177,6 @@ static void opt_output_file(const char *filename)
     /* reset some options */
     file_oformat = NULL;
     file_iformat = NULL;
-    image_format = NULL;
 }
 
 /* prepare dummy protocols for grab */
@@ -3260,6 +3234,10 @@ static void prepare_grab(void)
 
     if (has_video) {
         AVInputFormat *fmt1;
+#warning FIXME: find a better interface
+        if(!strncmp(video_device,"x11:",4)) {
+            video_grab_format="x11grab";
+        }
         fmt1 = av_find_input_format(video_grab_format);
         vp->device  = video_device;
         vp->channel = video_channel;
@@ -3337,7 +3315,6 @@ static void show_formats(void)
 {
     AVInputFormat *ifmt;
     AVOutputFormat *ofmt;
-    AVImageFormat *image_fmt;
     URLProtocol *up;
     AVCodec *p, *p2;
     const char **pp, *last_name;
@@ -3381,18 +3358,6 @@ static void show_formats(void)
     }
     printf("\n");
 
-    printf("Image formats (filename extensions, if any, follow):\n");
-    for(image_fmt = first_image_format; image_fmt != NULL;
-        image_fmt = image_fmt->next) {
-        printf(
-            " %s%s %-6s %s\n",
-            image_fmt->img_read  ? "D":" ",
-            image_fmt->img_write ? "E":" ",
-            image_fmt->name,
-            image_fmt->extensions ? image_fmt->extensions:" ");
-    }
-    printf("\n");
-
     printf("Codecs:\n");
     last_name= "000";
     for(;;){
@@ -3725,7 +3690,6 @@ const OptionDef options[] = {
     { "version", 0, {(void*)show_version}, "show version" },
     { "formats", 0, {(void*)show_formats}, "show available formats, codecs, protocols, ..." },
     { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
-    { "img", HAS_ARG, {(void*)opt_image_format}, "force image format", "img_fmt" },
     { "i", HAS_ARG, {(void*)opt_input_file}, "input file name", "filename" },
     { "y", OPT_BOOL, {(void*)&file_overwrite}, "overwrite output files" },
     { "map", HAS_ARG | OPT_EXPERT, {(void*)opt_map}, "set input stream mapping", "file:stream[:syncfile:syncstream]" },
@@ -3779,8 +3743,8 @@ const OptionDef options[] = {
     { "intra", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&intra_only}, "use only intra frames"},
     { "vn", OPT_BOOL | OPT_VIDEO, {(void*)&video_disable}, "disable video" },
     { "vdt", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&video_discard}, "discard threshold", "n" },
-    { "qscale", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qscale}, "use fixed video quantiser scale (VBR)", "q" },
-    { "qdiff", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qdiff}, "max difference between the quantiser scale (VBR)", "q" },
+    { "qscale", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qscale}, "use fixed video quantizer scale (VBR)", "q" },
+    { "qdiff", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qdiff}, "max difference between the quantizer scale (VBR)", "q" },
     { "rc_eq", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_video_rc_eq}, "set rate control equation", "equation" },
     { "rc_override", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_video_rc_override_string}, "rate control override for specific intervals", "override" },
     { "vcodec", HAS_ARG | OPT_VIDEO, {(void*)opt_video_codec}, "force video codec ('copy' to copy stream)", "codec" },
@@ -3846,7 +3810,7 @@ const OptionDef options[] = {
 
 static void show_banner(void)
 {
-    fprintf(stderr, "FFmpeg version " FFMPEG_VERSION ", Copyright (c) 2000-2004 Fabrice Bellard\n");
+    fprintf(stderr, "FFmpeg version " FFMPEG_VERSION ", Copyright (c) 2000-2006 Fabrice Bellard, et al.\n");
     fprintf(stderr, "  configuration: " FFMPEG_CONFIGURATION "\n");
     fprintf(stderr, "  libavutil version: " AV_STRINGIFY(LIBAVUTIL_VERSION) "\n");
     fprintf(stderr, "  libavcodec version: " AV_STRINGIFY(LIBAVCODEC_VERSION) "\n");
@@ -3864,34 +3828,34 @@ static void show_license(void)
     show_banner();
 #ifdef CONFIG_GPL
     printf(
-    "This program is free software; you can redistribute it and/or modify\n"
+    "FFmpeg is free software; you can redistribute it and/or modify\n"
     "it under the terms of the GNU General Public License as published by\n"
     "the Free Software Foundation; either version 2 of the License, or\n"
     "(at your option) any later version.\n"
     "\n"
-    "This program is distributed in the hope that it will be useful,\n"
+    "FFmpeg is distributed in the hope that it will be useful,\n"
     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
     "GNU General Public License for more details.\n"
     "\n"
     "You should have received a copy of the GNU General Public License\n"
-    "along with this program; if not, write to the Free Software\n"
+    "along with FFmpeg; if not, write to the Free Software\n"
     "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n"
     );
 #else
     printf(
-    "This library is free software; you can redistribute it and/or\n"
+    "FFmpeg is free software; you can redistribute it and/or\n"
     "modify it under the terms of the GNU Lesser General Public\n"
     "License as published by the Free Software Foundation; either\n"
-    "version 2 of the License, or (at your option) any later version.\n"
+    "version 2.1 of the License, or (at your option) any later version.\n"
     "\n"
-    "This library is distributed in the hope that it will be useful,\n"
+    "FFmpeg is distributed in the hope that it will be useful,\n"
     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n"
     "Lesser General Public License for more details.\n"
     "\n"
     "You should have received a copy of the GNU Lesser General Public\n"
-    "License along with this library; if not, write to the Free Software\n"
+    "License along with FFmpeg; if not, write to the Free Software\n"
     "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n"
     );
 #endif
@@ -3982,8 +3946,10 @@ int main(int argc, char **argv)
         int j;
         if (!(s->oformat->flags & AVFMT_NOFILE))
             url_fclose(&s->pb);
-        for(j=0;j<s->nb_streams;j++)
+        for(j=0;j<s->nb_streams;j++) {
+            av_free(s->streams[j]->codec);
             av_free(s->streams[j]);
+        }
         av_free(s);
     }
     for(i=0;i<nb_input_files;i++)
@@ -4001,14 +3967,13 @@ int main(int argc, char **argv)
     powerpc_display_perf_report();
 #endif /* POWERPC_PERFORMANCE_REPORT */
 
-#ifndef __MINGW32__
     if (received_sigterm) {
         fprintf(stderr,
             "Received signal %d: terminating.\n",
             (int) received_sigterm);
         exit (255);
     }
-#endif
+
     exit(0); /* not all OS-es handle main() return value */
     return 0;
 }