]> git.sesse.net Git - ffmpeg/blobdiff - ffmpeg.c
Move transform declarations out of IVIBandDesc so indeo4 can use them as well.
[ffmpeg] / ffmpeg.c
index 088b28727a1895f5f2ad88b3f7d55086da1a1e62..96f17803955e1f8e8dcd2b5a6c23e76abb99ad81 100644 (file)
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -139,7 +139,7 @@ static const char *video_rc_override_string=NULL;
 static int video_disable = 0;
 static int video_discard = 0;
 static char *video_codec_name = NULL;
-static int video_codec_tag = 0;
+static unsigned int video_codec_tag = 0;
 static char *video_language = NULL;
 static int same_quality = 0;
 static int do_deinterlace = 0;
@@ -151,7 +151,7 @@ static int loop_output = AVFMT_NOOUTPUTLOOP;
 static int qp_hist = 0;
 #if CONFIG_AVFILTER
 static char *vfilters = NULL;
-AVFilterGraph *filt_graph_all = NULL;
+AVFilterGraph *graph = NULL;
 #endif
 
 static int intra_only = 0;
@@ -162,13 +162,13 @@ static float audio_qscale = QSCALE_NONE;
 static int audio_disable = 0;
 static int audio_channels = 1;
 static char  *audio_codec_name = NULL;
-static int audio_codec_tag = 0;
+static unsigned int audio_codec_tag = 0;
 static char *audio_language = NULL;
 
 static int subtitle_disable = 0;
 static char *subtitle_codec_name = NULL;
 static char *subtitle_language = NULL;
-static int subtitle_codec_tag = 0;
+static unsigned int subtitle_codec_tag = 0;
 
 static float mux_preload= 0.5;
 static float mux_max_delay= 0.7;
@@ -398,75 +398,71 @@ static AVFilter output_filter =
 
 static int configure_filters(AVInputStream *ist, AVOutputStream *ost)
 {
-    AVFilterContext *curr_filter;
+    AVFilterContext *last_filter, *filter;
     /** filter graph containing all filters including input & output */
     AVCodecContext *codec = ost->st->codec;
     AVCodecContext *icodec = ist->st->codec;
     char args[255];
 
-    filt_graph_all = av_mallocz(sizeof(AVFilterGraph));
+    graph = av_mallocz(sizeof(AVFilterGraph));
 
-    if(!(ist->input_video_filter = avfilter_open(avfilter_get_by_name("buffer"), "src")))
+    if (!(ist->input_video_filter = avfilter_open(avfilter_get_by_name("buffer"), "src")))
         return -1;
-    if(!(ist->out_video_filter = avfilter_open(&output_filter, "out")))
+    if (!(ist->out_video_filter = avfilter_open(&output_filter, "out")))
         return -1;
 
     snprintf(args, 255, "%d:%d:%d", ist->st->codec->width,
              ist->st->codec->height, ist->st->codec->pix_fmt);
-    if(avfilter_init_filter(ist->input_video_filter, args, NULL))
+    if (avfilter_init_filter(ist->input_video_filter, args, NULL))
         return -1;
-    if(avfilter_init_filter(ist->out_video_filter, NULL, &codec->pix_fmt))
+    if (avfilter_init_filter(ist->out_video_filter, NULL, &codec->pix_fmt))
         return -1;
 
     /* add input and output filters to the overall graph */
-    avfilter_graph_add_filter(filt_graph_all, ist->input_video_filter);
-    avfilter_graph_add_filter(filt_graph_all, ist->out_video_filter);
+    avfilter_graph_add_filter(graph, ist->input_video_filter);
+    avfilter_graph_add_filter(graph, ist->out_video_filter);
 
-    curr_filter = ist->input_video_filter;
+    last_filter = ist->input_video_filter;
 
-    if(ost->video_crop) {
-        char crop_args[255];
-        AVFilterContext *filt_crop;
-        snprintf(crop_args, 255, "%d:%d:%d:%d", ost->leftBand, ost->topBand,
+    if (ost->video_crop) {
+        snprintf(args, 255, "%d:%d:%d:%d", ost->leftBand, ost->topBand,
                  codec->width,
                  codec->height);
-        filt_crop = avfilter_open(avfilter_get_by_name("crop"), NULL);
-        if (!filt_crop)
+        filter = avfilter_open(avfilter_get_by_name("crop"), NULL);
+        if (!filter)
             return -1;
-        if (avfilter_init_filter(filt_crop, crop_args, NULL))
+        if (avfilter_init_filter(filter, args, NULL))
             return -1;
-        if (avfilter_link(curr_filter, 0, filt_crop, 0))
+        if (avfilter_link(last_filter, 0, filter, 0))
             return -1;
-        curr_filter = filt_crop;
-        avfilter_graph_add_filter(filt_graph_all, curr_filter);
+        last_filter = filter;
+        avfilter_graph_add_filter(graph, last_filter);
     }
 
     if((codec->width !=
         icodec->width - (frame_leftBand + frame_rightBand)) ||
        (codec->height != icodec->height - (frame_topBand  + frame_bottomBand))) {
-        char scale_args[255];
-        AVFilterContext *filt_scale;
-        snprintf(scale_args, 255, "%d:%d:flags=0x%X",
+        snprintf(args, 255, "%d:%d:flags=0x%X",
                  codec->width,
                  codec->height,
                  (int)av_get_int(sws_opts, "sws_flags", NULL));
-        filt_scale = avfilter_open(avfilter_get_by_name("scale"), NULL);
-        if (!filt_scale)
+        filter = avfilter_open(avfilter_get_by_name("scale"), NULL);
+        if (!filter)
             return -1;
-        if (avfilter_init_filter(filt_scale, scale_args, NULL))
+        if (avfilter_init_filter(filter, args, NULL))
             return -1;
-        if (avfilter_link(curr_filter, 0, filt_scale, 0))
+        if (avfilter_link(last_filter, 0, filter, 0))
             return -1;
-        curr_filter = filt_scale;
-        avfilter_graph_add_filter(filt_graph_all, curr_filter);
+        last_filter = filter;
+        avfilter_graph_add_filter(graph, last_filter);
     }
 
-    if(vfilters) {
+    if (vfilters) {
         AVFilterInOut *outputs = av_malloc(sizeof(AVFilterInOut));
         AVFilterInOut *inputs  = av_malloc(sizeof(AVFilterInOut));
 
         outputs->name    = av_strdup("in");
-        outputs->filter  = curr_filter;
+        outputs->filter  = last_filter;
         outputs->pad_idx = 0;
         outputs->next    = NULL;
 
@@ -475,26 +471,23 @@ static int configure_filters(AVInputStream *ist, AVOutputStream *ost)
         inputs->pad_idx = 0;
         inputs->next    = NULL;
 
-        if (avfilter_graph_parse(filt_graph_all, vfilters, inputs, outputs, NULL) < 0)
+        if (avfilter_graph_parse(graph, vfilters, inputs, outputs, NULL) < 0)
             return -1;
         av_freep(&vfilters);
     } else {
-        if(avfilter_link(curr_filter, 0, ist->out_video_filter, 0) < 0)
+        if (avfilter_link(last_filter, 0, ist->out_video_filter, 0) < 0)
             return -1;
     }
 
-    {
-        char scale_sws_opts[128];
-        snprintf(scale_sws_opts, sizeof(scale_sws_opts), "flags=0x%X", (int)av_get_int(sws_opts, "sws_flags", NULL));
-        filt_graph_all->scale_sws_opts = av_strdup(scale_sws_opts);
-    }
+    snprintf(args, sizeof(args), "flags=0x%X", (int)av_get_int(sws_opts, "sws_flags", NULL));
+    graph->scale_sws_opts = av_strdup(args);
 
     /* configure all the filter links */
-    if(avfilter_graph_check_validity(filt_graph_all, NULL))
+    if (avfilter_graph_check_validity(graph, NULL))
         return -1;
-    if(avfilter_graph_config_formats(filt_graph_all, NULL))
+    if (avfilter_graph_config_formats(graph, NULL))
         return -1;
-    if(avfilter_graph_config_links(filt_graph_all, NULL))
+    if (avfilter_graph_config_links(graph, NULL))
         return -1;
 
     codec->width = ist->out_video_filter->inputs[0]->w;
@@ -547,10 +540,6 @@ static void term_init(void)
 #ifdef SIGXCPU
     signal(SIGXCPU, sigterm_handler);
 #endif
-
-#if CONFIG_BEOS_NETSERVER
-    fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK);
-#endif
 }
 
 /* read a key without blocking */
@@ -559,7 +548,6 @@ static int read_key(void)
 #if HAVE_TERMIOS_H
     int n = 1;
     unsigned char ch;
-#if !CONFIG_BEOS_NETSERVER
     struct timeval tv;
     fd_set rfds;
 
@@ -568,7 +556,6 @@ static int read_key(void)
     tv.tv_sec = 0;
     tv.tv_usec = 0;
     n = select(1, &rfds, NULL, NULL, &tv);
-#endif
     if (n > 0) {
         n = read(0, &ch, 1);
         if (n == 1)
@@ -826,6 +813,7 @@ need_realloc:
     audio_buf_size= (allocated_for_size + isize*dec->channels - 1) / (isize*dec->channels);
     audio_buf_size= (audio_buf_size*enc->sample_rate + dec->sample_rate) / dec->sample_rate;
     audio_buf_size= audio_buf_size*2 + 10000; //safety factors for the deprecated resampling API
+    audio_buf_size= FFMAX(audio_buf_size, enc->frame_size);
     audio_buf_size*= osize*enc->channels;
 
     audio_out_size= FFMAX(audio_buf_size, enc->frame_size * osize * enc->channels);
@@ -1528,7 +1516,7 @@ static int output_packet(AVInputStream *ist, int ist_index,
     AVSubtitle subtitle, *subtitle_to_free;
     int got_subtitle;
 #if CONFIG_AVFILTER
-    int loop;
+    int frame_available;
 #endif
 
     AVPacket avpkt;
@@ -1689,14 +1677,14 @@ static int output_packet(AVInputStream *ist, int ist_index,
                 usleep(pts - now);
         }
 #if CONFIG_AVFILTER
-        loop = ist->st->codec->codec_type != AVMEDIA_TYPE_VIDEO ||
+        frame_available = ist->st->codec->codec_type != AVMEDIA_TYPE_VIDEO ||
             !ist->out_video_filter || avfilter_poll_frame(ist->out_video_filter->inputs[0]);
 #endif
         /* if output time reached then transcode raw format,
            encode packets and output them */
         if (start_time == 0 || ist->pts >= start_time)
 #if CONFIG_AVFILTER
-        while(loop) {
+        while (frame_available) {
             if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ist->out_video_filter)
                 get_filtered_video_pic(ist->out_video_filter, &ist->picref, &picture, &ist->pts);
 #endif
@@ -1789,7 +1777,7 @@ static int output_packet(AVInputStream *ist, int ist_index,
                     }
                 }
 #if CONFIG_AVFILTER
-                loop =  (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) &&
+                frame_available = (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) &&
                         ist->out_video_filter && avfilter_poll_frame(ist->out_video_filter->inputs[0]);
 #endif
             }
@@ -1845,17 +1833,17 @@ static int output_packet(AVInputStream *ist, int ist_index,
                                 int osize = av_get_bits_per_sample_format(enc->sample_fmt) >> 3;
                                 int fs_tmp = enc->frame_size;
 
-                                av_fifo_generic_read(ost->fifo, samples, fifo_bytes, NULL);
+                                av_fifo_generic_read(ost->fifo, audio_buf, fifo_bytes, NULL);
                                 if (enc->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) {
                                     enc->frame_size = fifo_bytes / (osize * enc->channels);
                                 } else { /* pad */
                                     int frame_bytes = enc->frame_size*osize*enc->channels;
-                                    if (samples_size < frame_bytes)
+                                    if (allocated_audio_buf_size < frame_bytes)
                                         av_exit(1);
-                                    memset((uint8_t*)samples+fifo_bytes, 0, frame_bytes - fifo_bytes);
+                                    memset(audio_buf+fifo_bytes, 0, frame_bytes - fifo_bytes);
                                 }
 
-                                ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, samples);
+                                ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, (short *)audio_buf);
                                 pkt.duration = av_rescale((int64_t)enc->frame_size*ost->st->time_base.den,
                                                           ost->st->time_base.num, enc->sample_rate);
                                 enc->frame_size = fs_tmp;
@@ -2163,6 +2151,11 @@ static int av_transcode(AVFormatContext **output_files,
         codec->chroma_sample_location = icodec->chroma_sample_location;
 
         if (ost->st->stream_copy) {
+            uint64_t extra_size = (uint64_t)icodec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE;
+
+            if (extra_size > INT_MAX)
+                goto fail;
+
             /* if stream_copy is selected, no need to decode or encode */
             codec->codec_id = icodec->codec_id;
             codec->codec_type = icodec->codec_type;
@@ -2175,7 +2168,10 @@ static int av_transcode(AVFormatContext **output_files,
             }
 
             codec->bit_rate = icodec->bit_rate;
-            codec->extradata= icodec->extradata;
+            codec->extradata= av_mallocz(extra_size);
+            if (!codec->extradata)
+                goto fail;
+            memcpy(codec->extradata, icodec->extradata, icodec->extradata_size);
             codec->extradata_size= icodec->extradata_size;
             if(av_q2d(icodec->time_base)*icodec->ticks_per_frame > av_q2d(ist->st->time_base) && av_q2d(ist->st->time_base) < 1.0/1000){
                 codec->time_base = icodec->time_base;
@@ -2298,7 +2294,7 @@ static int av_transcode(AVFormatContext **output_files,
                          pass_logfilename_prefix ? pass_logfilename_prefix : DEFAULT_PASS_LOGFILENAME_PREFIX,
                          i);
                 if (codec->flags & CODEC_FLAG_PASS1) {
-                    f = fopen(logfilename, "w");
+                    f = fopen(logfilename, "wb");
                     if (!f) {
                         fprintf(stderr, "Cannot write log file '%s' for pass-1 encoding: %s\n", logfilename, strerror(errno));
                         av_exit(1);
@@ -2665,9 +2661,9 @@ static int av_transcode(AVFormatContext **output_files,
         }
     }
 #if CONFIG_AVFILTER
-    if (filt_graph_all) {
-        avfilter_graph_destroy(filt_graph_all);
-        av_freep(&filt_graph_all);
+    if (graph) {
+        avfilter_graph_destroy(graph);
+        av_freep(&graph);
     }
 #endif
 
@@ -2689,6 +2685,8 @@ static int av_transcode(AVFormatContext **output_files,
         for(i=0;i<nb_ostreams;i++) {
             ost = ost_table[i];
             if (ost) {
+                if (ost->st->stream_copy)
+                    av_freep(&ost->st->codec->extradata);
                 if (ost->logfile) {
                     fclose(ost->logfile);
                     ost->logfile = NULL;
@@ -2826,7 +2824,7 @@ static void opt_frame_size(const char *arg)
 }
 
 static void opt_pad(const char *arg) {
-    fprintf(stderr, "Please use vfilters=pad\n");
+    fprintf(stderr, "Please use vf=pad\n");
     av_exit(1);
 }
 
@@ -3075,7 +3073,7 @@ static int opt_input_ts_offset(const char *opt, const char *arg)
     return 0;
 }
 
-static enum CodecID find_codec_or_die(const char *name, int type, int encoder)
+static enum CodecID find_codec_or_die(const char *name, int type, int encoder, int strict)
 {
     const char *codec_string = encoder ? "encoder" : "decoder";
     AVCodec *codec;
@@ -3093,6 +3091,19 @@ static enum CodecID find_codec_or_die(const char *name, int type, int encoder)
         fprintf(stderr, "Invalid %s type '%s'\n", codec_string, name);
         av_exit(1);
     }
+    if(codec->capabilities & CODEC_CAP_EXPERIMENTAL &&
+       strict > FF_COMPLIANCE_EXPERIMENTAL) {
+        fprintf(stderr, "%s '%s' is experimental and might produce bad "
+                "results.\nAdd '-strict experimental' if you want to use it.\n",
+                codec_string, codec->name);
+        codec = encoder ?
+            avcodec_find_encoder(codec->id) :
+            avcodec_find_decoder(codec->id);
+        if (!(codec->capabilities & CODEC_CAP_EXPERIMENTAL))
+            fprintf(stderr, "Or use the non experimental %s '%s'.\n",
+                    codec_string, codec->name);
+        av_exit(1);
+    }
     return codec->id;
 }
 
@@ -3140,9 +3151,15 @@ static void opt_input_file(const char *filename)
 
     set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM);
 
-    ic->video_codec_id   = find_codec_or_die(video_codec_name   , AVMEDIA_TYPE_VIDEO   , 0);
-    ic->audio_codec_id   = find_codec_or_die(audio_codec_name   , AVMEDIA_TYPE_AUDIO   , 0);
-    ic->subtitle_codec_id= find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 0);
+    ic->video_codec_id   =
+        find_codec_or_die(video_codec_name   , AVMEDIA_TYPE_VIDEO   , 0,
+                          avcodec_opts[AVMEDIA_TYPE_VIDEO   ]->strict_std_compliance);
+    ic->audio_codec_id   =
+        find_codec_or_die(audio_codec_name   , AVMEDIA_TYPE_AUDIO   , 0,
+                          avcodec_opts[AVMEDIA_TYPE_AUDIO   ]->strict_std_compliance);
+    ic->subtitle_codec_id=
+        find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 0,
+                          avcodec_opts[AVMEDIA_TYPE_SUBTITLE]->strict_std_compliance);
     ic->flags |= AVFMT_FLAG_NONBLOCK;
 
     if(pgmyuv_compatibility_hack)
@@ -3371,7 +3388,8 @@ static void new_video_stream(AVFormatContext *oc)
         AVRational fps= frame_rate.num ? frame_rate : (AVRational){25,1};
 
         if (video_codec_name) {
-            codec_id = find_codec_or_die(video_codec_name, AVMEDIA_TYPE_VIDEO, 1);
+            codec_id = find_codec_or_die(video_codec_name, AVMEDIA_TYPE_VIDEO, 1,
+                                         video_enc->strict_std_compliance);
             codec = avcodec_find_encoder_by_name(video_codec_name);
             output_codecs[nb_ocodecs] = codec;
         } else {
@@ -3502,7 +3520,8 @@ static void new_audio_stream(AVFormatContext *oc)
         set_context_opts(audio_enc, avcodec_opts[AVMEDIA_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM);
 
         if (audio_codec_name) {
-            codec_id = find_codec_or_die(audio_codec_name, AVMEDIA_TYPE_AUDIO, 1);
+            codec_id = find_codec_or_die(audio_codec_name, AVMEDIA_TYPE_AUDIO, 1,
+                                         audio_enc->strict_std_compliance);
             codec = avcodec_find_encoder_by_name(audio_codec_name);
             output_codecs[nb_ocodecs] = codec;
         } else {
@@ -3562,7 +3581,8 @@ static void new_subtitle_stream(AVFormatContext *oc)
         st->stream_copy = 1;
     } else {
         set_context_opts(avcodec_opts[AVMEDIA_TYPE_SUBTITLE], subtitle_enc, AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_ENCODING_PARAM);
-        subtitle_enc->codec_id = find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 1);
+        subtitle_enc->codec_id = find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 1,
+                                                   subtitle_enc->strict_std_compliance);
         output_codecs[nb_ocodecs] = avcodec_find_encoder_by_name(subtitle_codec_name);
     }
     nb_ocodecs++;
@@ -4204,7 +4224,7 @@ static const OptionDef options[] = {
     { "vstats", OPT_EXPERT | OPT_VIDEO, {(void*)&opt_vstats}, "dump video coding statistics to file" },
     { "vstats_file", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_vstats_file}, "dump video coding statistics to file", "file" },
 #if CONFIG_AVFILTER
-    { "vfilters", OPT_STRING | HAS_ARG, {(void*)&vfilters}, "video filters", "filter list" },
+    { "vf", OPT_STRING | HAS_ARG, {(void*)&vfilters}, "video filters", "filter list" },
 #endif
     { "intra_matrix", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_intra_matrix}, "specify intra matrix coeffs", "matrix" },
     { "inter_matrix", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_inter_matrix}, "specify inter matrix coeffs", "matrix" },