]> git.sesse.net Git - ffmpeg/blobdiff - ffmpeg.c
add doxygen comments
[ffmpeg] / ffmpeg.c
index 16911c6624814363c2992800aa983a59b0f6f1fb..105e1134287013943bcc86de4fa19db0cb4d5961 100644 (file)
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -24,7 +24,6 @@
 #include "avformat.h"
 #include "swscale.h"
 #include "framehook.h"
-#include "dsputil.h"
 #include "opt.h"
 #include "fifo.h"
 
@@ -56,6 +55,8 @@
 #define INFINITY HUGE_VAL
 #endif
 
+#undef exit
+
 /* select an input stream for an output stream */
 typedef struct AVStreamMap {
     int file_index;
@@ -165,7 +166,6 @@ static int do_benchmark = 0;
 static int do_hex_dump = 0;
 static int do_pkt_dump = 0;
 static int do_psnr = 0;
-static int do_vstats = 0;
 static int do_pass = 0;
 static char *pass_logfilename = NULL;
 static int audio_stream_copy = 0;
@@ -176,6 +176,8 @@ static int audio_sync_method= 0;
 static int copy_ts= 0;
 static int opt_shortest = 0; //
 static int video_global_header = 0;
+static char *vstats_filename;
+static FILE *fvstats;
 
 static int rate_emu = 0;
 
@@ -195,7 +197,7 @@ static int64_t extra_size = 0;
 static int nb_frames_dup = 0;
 static int nb_frames_drop = 0;
 static int input_sync;
-static int limit_filesize = 0; //
+static uint64_t limit_filesize = 0; //
 
 static int pgmyuv_compatibility_hack=0;
 static int dts_delta_threshold = 10;
@@ -206,6 +208,7 @@ const char **opt_names=NULL;
 int opt_name_count=0;
 AVCodecContext *avctx_opts[CODEC_TYPE_NB];
 AVFormatContext *avformat_opts;
+static int64_t timer_start = 0;
 
 static AVBitStreamFilterContext *video_bitstream_filters=NULL;
 static AVBitStreamFilterContext *audio_bitstream_filters=NULL;
@@ -270,8 +273,6 @@ typedef struct AVInputFile {
     int eof_reached;      /* true if eof reached */
     int ist_index;        /* index of first stream in ist_table */
     int buffer_size;      /* current total buffer size */
-    int buffer_size_max;  /* buffer size at which we consider we can stop
-                             buffering */
     int nb_streams;       /* nb streams we are aware of */
 } AVInputFile;
 
@@ -601,7 +602,8 @@ static void pre_process_video_frame(AVInputStream *ist, AVPicture *picture, void
         picture2 = picture;
     }
 
-    frame_hook_process(picture2, dec->pix_fmt, dec->width, dec->height);
+    frame_hook_process(picture2, dec->pix_fmt, dec->width, dec->height,
+                       1000000 * ist->pts / AV_TIME_BASE);
 
     if (picture != picture2)
         *picture = *picture2;
@@ -675,7 +677,6 @@ static void do_video_out(AVFormatContext *s,
     int nb_frames, i, ret;
     AVFrame *final_picture, *formatted_picture, *resampling_dst, *padding_src;
     AVFrame picture_crop_temp, picture_pad_temp;
-    uint8_t *buf = NULL, *buf1 = NULL;
     AVCodecContext *enc, *dec;
 
     avcodec_get_frame_defaults(&picture_crop_temp);
@@ -717,7 +718,7 @@ static void do_video_out(AVFormatContext *s,
     if (ost->video_crop) {
         if (av_picture_crop((AVPicture *)&picture_crop_temp, (AVPicture *)in_picture, dec->pix_fmt, ost->topBand, ost->leftBand) < 0) {
             av_log(NULL, AV_LOG_ERROR, "error cropping picture\n");
-            goto the_end;
+            return;
         }
         formatted_picture = &picture_crop_temp;
     } else {
@@ -732,7 +733,7 @@ static void do_video_out(AVFormatContext *s,
         if (ost->video_resample) {
             if (av_picture_crop((AVPicture *)&picture_pad_temp, (AVPicture *)final_picture, enc->pix_fmt, ost->padtop, ost->padleft) < 0) {
                 av_log(NULL, AV_LOG_ERROR, "error padding picture\n");
-                goto the_end;
+                return;
             }
             resampling_dst = &picture_pad_temp;
         }
@@ -831,9 +832,6 @@ static void do_video_out(AVFormatContext *s,
         ost->sync_opts++;
         ost->frame_number++;
     }
- the_end:
-    av_free(buf);
-    av_free(buf1);
 }
 
 static double psnr(double d){
@@ -844,22 +842,14 @@ static double psnr(double d){
 static void do_video_stats(AVFormatContext *os, AVOutputStream *ost,
                            int frame_size)
 {
-    static FILE *fvstats=NULL;
-    char filename[40];
-    time_t today2;
-    struct tm *today;
     AVCodecContext *enc;
     int frame_number;
     int64_t ti;
     double ti1, bitrate, avg_bitrate;
 
+    /* this is executed just the first time do_video_stats is called */
     if (!fvstats) {
-        today2 = time(NULL);
-        today = localtime(&today2);
-        snprintf(filename, sizeof(filename), "vstats_%02d%02d%02d.log", today->tm_hour,
-                                               today->tm_min,
-                                               today->tm_sec);
-        fvstats = fopen(filename,"w");
+        fvstats = fopen(vstats_filename, "w");
         if (!fvstats) {
             perror("fopen");
             exit(1);
@@ -918,7 +908,9 @@ static void print_report(AVFormatContext **output_files,
 
     oc = output_files[0];
 
-    total_size = url_ftell(&oc->pb);
+    total_size = url_fsize(&oc->pb);
+    if(total_size<0) // FIXME improve url_fsize() so it works with non seekable output too
+        total_size= url_ftell(&oc->pb);
 
     buf[0] = '\0';
     ti1 = 1e10;
@@ -932,9 +924,12 @@ static void print_report(AVFormatContext **output_files,
                     enc->coded_frame->quality/(float)FF_QP2LAMBDA);
         }
         if (!vid && enc->codec_type == CODEC_TYPE_VIDEO) {
+            float t = (av_gettime()-timer_start) / 1000000.0;
+
             frame_number = ost->frame_number;
-            snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "frame=%5d q=%3.1f ",
-                    frame_number, enc->coded_frame ? enc->coded_frame->quality/(float)FF_QP2LAMBDA : -1);
+            snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "frame=%5d fps=%3d q=%3.1f ",
+                     frame_number, (t>1)?(int)(frame_number/t+0.5) : 0,
+                     enc->coded_frame ? enc->coded_frame->quality/(float)FF_QP2LAMBDA : -1);
             if(is_last_report)
                 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "L");
             if(qp_hist && enc->coded_frame){
@@ -1050,7 +1045,7 @@ static int output_packet(AVInputStream *ist, int ist_index,
             switch(ist->st->codec->codec_type) {
             case CODEC_TYPE_AUDIO:{
                 if(pkt)
-                    samples= av_fast_realloc(samples, &samples_size, FFMAX(pkt->size, AVCODEC_MAX_AUDIO_FRAME_SIZE));
+                    samples= av_fast_realloc(samples, &samples_size, FFMAX(pkt->size*sizeof(*samples), AVCODEC_MAX_AUDIO_FRAME_SIZE));
                 data_size= samples_size;
                     /* XXX: could avoid copy if PCM 16 bits with same
                        endianness as CPU */
@@ -1106,165 +1101,165 @@ static int output_packet(AVInputStream *ist, int ist_index,
                 goto fail_decode;
             }
         } else {
-                switch(ist->st->codec->codec_type) {
-                case CODEC_TYPE_AUDIO:
-                    ist->next_pts += ((int64_t)AV_TIME_BASE * ist->st->codec->frame_size) /
-                        (ist->st->codec->sample_rate * ist->st->codec->channels);
-                    break;
-                case CODEC_TYPE_VIDEO:
-                    if (ist->st->codec->time_base.num != 0) {
-                        ist->next_pts += ((int64_t)AV_TIME_BASE *
-                                          ist->st->codec->time_base.num) /
-                            ist->st->codec->time_base.den;
-                    }
-                    break;
+            switch(ist->st->codec->codec_type) {
+            case CODEC_TYPE_AUDIO:
+                ist->next_pts += ((int64_t)AV_TIME_BASE * ist->st->codec->frame_size) /
+                    (ist->st->codec->sample_rate * ist->st->codec->channels);
+                break;
+            case CODEC_TYPE_VIDEO:
+                if (ist->st->codec->time_base.num != 0) {
+                    ist->next_pts += ((int64_t)AV_TIME_BASE *
+                                      ist->st->codec->time_base.num) /
+                        ist->st->codec->time_base.den;
                 }
-                data_buf = ptr;
-                data_size = len;
-                ret = len;
-                len = 0;
-            }
-
-            buffer_to_free = NULL;
-            if (ist->st->codec->codec_type == CODEC_TYPE_VIDEO) {
-                pre_process_video_frame(ist, (AVPicture *)&picture,
-                                        &buffer_to_free);
+                break;
             }
-
-            // preprocess audio (volume)
-            if (ist->st->codec->codec_type == CODEC_TYPE_AUDIO) {
-                if (audio_volume != 256) {
-                    short *volp;
-                    volp = samples;
-                    for(i=0;i<(data_size / sizeof(short));i++) {
-                        int v = ((*volp) * audio_volume + 128) >> 8;
-                        if (v < -32768) v = -32768;
-                        if (v >  32767) v = 32767;
-                        *volp++ = v;
-                    }
+            data_buf = ptr;
+            data_size = len;
+            ret = len;
+            len = 0;
+        }
+
+        buffer_to_free = NULL;
+        if (ist->st->codec->codec_type == CODEC_TYPE_VIDEO) {
+            pre_process_video_frame(ist, (AVPicture *)&picture,
+                                    &buffer_to_free);
+        }
+
+        // preprocess audio (volume)
+        if (ist->st->codec->codec_type == CODEC_TYPE_AUDIO) {
+            if (audio_volume != 256) {
+                short *volp;
+                volp = samples;
+                for(i=0;i<(data_size / sizeof(short));i++) {
+                    int v = ((*volp) * audio_volume + 128) >> 8;
+                    if (v < -32768) v = -32768;
+                    if (v >  32767) v = 32767;
+                    *volp++ = v;
                 }
             }
+        }
 
-            /* frame rate emulation */
-            if (ist->st->codec->rate_emu) {
-                int64_t pts = av_rescale((int64_t) ist->frame * ist->st->codec->time_base.num, 1000000, ist->st->codec->time_base.den);
-                int64_t now = av_gettime() - ist->start;
-                if (pts > now)
-                    usleep(pts - now);
+        /* frame rate emulation */
+        if (ist->st->codec->rate_emu) {
+            int64_t pts = av_rescale((int64_t) ist->frame * ist->st->codec->time_base.num, 1000000, ist->st->codec->time_base.den);
+            int64_t now = av_gettime() - ist->start;
+            if (pts > now)
+                usleep(pts - now);
 
-                ist->frame++;
-            }
+            ist->frame++;
+        }
 
 #if 0
-            /* mpeg PTS deordering : if it is a P or I frame, the PTS
-               is the one of the next displayed one */
-            /* XXX: add mpeg4 too ? */
-            if (ist->st->codec->codec_id == CODEC_ID_MPEG1VIDEO) {
-                if (ist->st->codec->pict_type != B_TYPE) {
-                    int64_t tmp;
-                    tmp = ist->last_ip_pts;
-                    ist->last_ip_pts  = ist->frac_pts.val;
-                    ist->frac_pts.val = tmp;
-                }
+        /* mpeg PTS deordering : if it is a P or I frame, the PTS
+           is the one of the next displayed one */
+        /* XXX: add mpeg4 too ? */
+        if (ist->st->codec->codec_id == CODEC_ID_MPEG1VIDEO) {
+            if (ist->st->codec->pict_type != B_TYPE) {
+                int64_t tmp;
+                tmp = ist->last_ip_pts;
+                ist->last_ip_pts  = ist->frac_pts.val;
+                ist->frac_pts.val = tmp;
             }
+        }
 #endif
-            /* if output time reached then transcode raw format,
-               encode packets and output them */
-            if (start_time == 0 || ist->pts >= start_time)
-                for(i=0;i<nb_ostreams;i++) {
-                    int frame_size;
+        /* if output time reached then transcode raw format,
+           encode packets and output them */
+        if (start_time == 0 || ist->pts >= start_time)
+            for(i=0;i<nb_ostreams;i++) {
+                int frame_size;
 
-                    ost = ost_table[i];
-                    if (ost->source_index == ist_index) {
-                        os = output_files[ost->file_index];
+                ost = ost_table[i];
+                if (ost->source_index == ist_index) {
+                    os = output_files[ost->file_index];
 
 #if 0
-                        printf("%d: got pts=%0.3f %0.3f\n", i,
-                               (double)pkt->pts / AV_TIME_BASE,
-                               ((double)ist->pts / AV_TIME_BASE) -
-                               ((double)ost->st->pts.val * ost->st->time_base.num / ost->st->time_base.den));
+                    printf("%d: got pts=%0.3f %0.3f\n", i,
+                           (double)pkt->pts / AV_TIME_BASE,
+                           ((double)ist->pts / AV_TIME_BASE) -
+                           ((double)ost->st->pts.val * ost->st->time_base.num / ost->st->time_base.den));
 #endif
-                        /* set the input output pts pairs */
-                        //ost->sync_ipts = (double)(ist->pts + input_files_ts_offset[ist->file_index] - start_time)/ AV_TIME_BASE;
-
-                        if (ost->encoding_needed) {
-                            switch(ost->st->codec->codec_type) {
-                            case CODEC_TYPE_AUDIO:
-                                do_audio_out(os, ost, ist, data_buf, data_size);
-                                break;
-                            case CODEC_TYPE_VIDEO:
-                                    do_video_out(os, ost, ist, &picture, &frame_size);
-                                    video_size += frame_size;
-                                    if (do_vstats && frame_size)
-                                        do_video_stats(os, ost, frame_size);
-                                break;
-                            case CODEC_TYPE_SUBTITLE:
-                                do_subtitle_out(os, ost, ist, &subtitle,
-                                                pkt->pts);
-                                break;
-                            default:
-                                av_abort();
-                            }
-                        } else {
-                            AVFrame avframe; //FIXME/XXX remove this
-                            AVPacket opkt;
-                            av_init_packet(&opkt);
-
-                            /* no reencoding needed : output the packet directly */
-                            /* force the input stream PTS */
-
-                            avcodec_get_frame_defaults(&avframe);
-                            ost->st->codec->coded_frame= &avframe;
-                            avframe.key_frame = pkt->flags & PKT_FLAG_KEY;
-
-                            if(ost->st->codec->codec_type == CODEC_TYPE_AUDIO)
-                                audio_size += data_size;
-                            else if (ost->st->codec->codec_type == CODEC_TYPE_VIDEO) {
-                                video_size += data_size;
-                                ost->sync_opts++;
-                            }
+                    /* set the input output pts pairs */
+                    //ost->sync_ipts = (double)(ist->pts + input_files_ts_offset[ist->file_index] - start_time)/ AV_TIME_BASE;
 
-                            opkt.stream_index= ost->index;
-                            if(pkt->pts != AV_NOPTS_VALUE)
-                                opkt.pts= av_rescale_q(av_rescale_q(pkt->pts, ist->st->time_base, AV_TIME_BASE_Q) + input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q,  ost->st->time_base);
-                            else
-                                opkt.pts= AV_NOPTS_VALUE;
-
-                            {
-                                int64_t dts;
-                                if (pkt->dts == AV_NOPTS_VALUE)
-                                    dts = ist->next_pts;
-                                else
-                                    dts= av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q);
-                                opkt.dts= av_rescale_q(dts + input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q,  ost->st->time_base);
-                            }
-                            opkt.flags= pkt->flags;
+                    if (ost->encoding_needed) {
+                        switch(ost->st->codec->codec_type) {
+                        case CODEC_TYPE_AUDIO:
+                            do_audio_out(os, ost, ist, data_buf, data_size);
+                            break;
+                        case CODEC_TYPE_VIDEO:
+                            do_video_out(os, ost, ist, &picture, &frame_size);
+                            video_size += frame_size;
+                            if (vstats_filename && frame_size)
+                                do_video_stats(os, ost, frame_size);
+                            break;
+                        case CODEC_TYPE_SUBTITLE:
+                            do_subtitle_out(os, ost, ist, &subtitle,
+                                            pkt->pts);
+                            break;
+                        default:
+                            av_abort();
+                        }
+                    } else {
+                        AVFrame avframe; //FIXME/XXX remove this
+                        AVPacket opkt;
+                        av_init_packet(&opkt);
+
+                        /* no reencoding needed : output the packet directly */
+                        /* force the input stream PTS */
+
+                        avcodec_get_frame_defaults(&avframe);
+                        ost->st->codec->coded_frame= &avframe;
+                        avframe.key_frame = pkt->flags & PKT_FLAG_KEY;
+
+                        if(ost->st->codec->codec_type == CODEC_TYPE_AUDIO)
+                            audio_size += data_size;
+                        else if (ost->st->codec->codec_type == CODEC_TYPE_VIDEO) {
+                            video_size += data_size;
+                            ost->sync_opts++;
+                        }
 
-                            //FIXME remove the following 2 lines they shall be replaced by the bitstream filters
-                            if(av_parser_change(ist->st->parser, ost->st->codec, &opkt.data, &opkt.size, data_buf, data_size, pkt->flags & PKT_FLAG_KEY))
-                                opkt.destruct= av_destruct_packet;
+                        opkt.stream_index= ost->index;
+                        if(pkt->pts != AV_NOPTS_VALUE)
+                            opkt.pts= av_rescale_q(av_rescale_q(pkt->pts, ist->st->time_base, AV_TIME_BASE_Q) + input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q,  ost->st->time_base);
+                        else
+                            opkt.pts= AV_NOPTS_VALUE;
 
-                            write_frame(os, &opkt, ost->st->codec, bitstream_filters[ost->file_index][pkt->stream_index]);
-                            ost->st->codec->frame_number++;
-                            ost->frame_number++;
-                            av_free_packet(&opkt);
+                        {
+                            int64_t dts;
+                            if (pkt->dts == AV_NOPTS_VALUE)
+                                dts = ist->next_pts;
+                            else
+                                dts= av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q);
+                            opkt.dts= av_rescale_q(dts + input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q,  ost->st->time_base);
                         }
+                        opkt.flags= pkt->flags;
+
+                        //FIXME remove the following 2 lines they shall be replaced by the bitstream filters
+                        if(av_parser_change(ist->st->parser, ost->st->codec, &opkt.data, &opkt.size, data_buf, data_size, pkt->flags & PKT_FLAG_KEY))
+                            opkt.destruct= av_destruct_packet;
+
+                        write_frame(os, &opkt, ost->st->codec, bitstream_filters[ost->file_index][pkt->stream_index]);
+                        ost->st->codec->frame_number++;
+                        ost->frame_number++;
+                        av_free_packet(&opkt);
                     }
                 }
-            av_free(buffer_to_free);
-            /* XXX: allocate the subtitles in the codec ? */
-            if (subtitle_to_free) {
-                if (subtitle_to_free->rects != NULL) {
-                    for (i = 0; i < subtitle_to_free->num_rects; i++) {
-                        av_free(subtitle_to_free->rects[i].bitmap);
-                        av_free(subtitle_to_free->rects[i].rgba_palette);
-                    }
-                    av_freep(&subtitle_to_free->rects);
+            }
+        av_free(buffer_to_free);
+        /* XXX: allocate the subtitles in the codec ? */
+        if (subtitle_to_free) {
+            if (subtitle_to_free->rects != NULL) {
+                for (i = 0; i < subtitle_to_free->num_rects; i++) {
+                    av_free(subtitle_to_free->rects[i].bitmap);
+                    av_free(subtitle_to_free->rects[i].rgba_palette);
                 }
-                subtitle_to_free->num_rects = 0;
-                subtitle_to_free = NULL;
+                av_freep(&subtitle_to_free->rects);
             }
+            subtitle_to_free->num_rects = 0;
+            subtitle_to_free = NULL;
         }
+    }
  discard_packet:
     if (pkt == NULL) {
         /* EOF handling */
@@ -1353,7 +1348,6 @@ static int av_encode(AVFormatContext **output_files,
     AVOutputStream *ost, **ost_table = NULL;
     AVInputStream *ist, **ist_table = NULL;
     AVInputFile *file_table;
-    AVFormatContext *stream_no_data;
     int key;
 
     file_table= (AVInputFile*) av_mallocz(nb_input_files * sizeof(AVInputFile));
@@ -1611,9 +1605,10 @@ static int av_encode(AVFormatContext **output_files,
                 if (ost->video_resample) {
                     avcodec_get_frame_defaults(&ost->pict_tmp);
                     if( avpicture_alloc( (AVPicture*)&ost->pict_tmp, codec->pix_fmt,
-                                         codec->width, codec->height ) )
+                                         codec->width, codec->height ) ) {
+                        fprintf(stderr, "Cannot allocate temp picture, check pix fmt\n");
                         exit(1);
-
+                    }
                     ost->img_resample_ctx = sws_getContext(
                             icodec->width - (frame_leftBand + frame_rightBand),
                             icodec->height - (frame_topBand + frame_bottomBand),
@@ -1768,11 +1763,6 @@ static int av_encode(AVFormatContext **output_files,
         ist->is_start = 1;
     }
 
-    /* compute buffer size max (should use a complete heuristic) */
-    for(i=0;i<nb_input_files;i++) {
-        file_table[i].buffer_size_max = 2048;
-    }
-
     /* set meta data information from input file if required */
     for (i=0;i<nb_meta_data_maps;i++) {
         AVFormatContext *out_file;
@@ -1820,8 +1810,8 @@ static int av_encode(AVFormatContext **output_files,
     }
     term_init();
 
-    stream_no_data = 0;
     key = -1;
+    timer_start = av_gettime();
 
     for(; received_sigterm == 0;) {
         int file_index, ist_index;
@@ -1880,7 +1870,7 @@ static int av_encode(AVFormatContext **output_files,
             break;
 
         /* finish if limit size exhausted */
-        if (limit_filesize != 0 && (limit_filesize * 1024) < url_ftell(&output_files[0]->pb))
+        if (limit_filesize != 0 && limit_filesize < url_ftell(&output_files[0]->pb))
             break;
 
         /* read a frame from it and output it in the fifo */
@@ -1890,13 +1880,8 @@ static int av_encode(AVFormatContext **output_files,
             if (opt_shortest) break; else continue; //
         }
 
-        if (!pkt.size) {
-            stream_no_data = is;
-        } else {
-            stream_no_data = 0;
-        }
         if (do_pkt_dump) {
-            av_pkt_dump(stdout, &pkt, do_hex_dump);
+            av_pkt_dump_log(NULL, AV_LOG_DEBUG, &pkt, do_hex_dump);
         }
         /* the following test is needed in case new streams appear
            dynamically in stream : we ignore them */
@@ -2045,6 +2030,7 @@ static void opt_format(const char *arg)
         pgmyuv_compatibility_hack=1;
 //        opt_image_format(arg);
         arg = "image2";
+        fprintf(stderr, "pgmyuv format is deprecated, use image2\n");
     }
 
     file_iformat = av_find_input_format(arg);
@@ -2583,10 +2569,8 @@ static void opt_input_file(const char *filename)
     for(i=0;i<ic->nb_streams;i++) {
         int j;
         AVCodecContext *enc = ic->streams[i]->codec;
-#if defined(HAVE_THREADS)
         if(thread_count>1)
             avcodec_thread_init(enc, thread_count);
-#endif
         enc->thread_count= thread_count;
         switch(enc->codec_type) {
         case CODEC_TYPE_AUDIO:
@@ -2705,13 +2689,12 @@ static void new_video_stream(AVFormatContext *oc)
         fprintf(stderr, "Could not alloc stream\n");
         exit(1);
     }
+    avcodec_get_context_defaults2(st->codec, CODEC_TYPE_VIDEO);
     bitstream_filters[nb_output_files][oc->nb_streams - 1]= video_bitstream_filters;
     video_bitstream_filters= NULL;
 
-#if defined(HAVE_THREADS)
     if(thread_count>1)
         avcodec_thread_init(st->codec, thread_count);
-#endif
 
     video_enc = st->codec;
 
@@ -2863,14 +2846,13 @@ static void new_audio_stream(AVFormatContext *oc)
         fprintf(stderr, "Could not alloc stream\n");
         exit(1);
     }
+    avcodec_get_context_defaults2(st->codec, CODEC_TYPE_AUDIO);
 
     bitstream_filters[nb_output_files][oc->nb_streams - 1]= audio_bitstream_filters;
     audio_bitstream_filters= NULL;
 
-#if defined(HAVE_THREADS)
     if(thread_count>1)
         avcodec_thread_init(st->codec, thread_count);
-#endif
 
     audio_enc = st->codec;
     audio_enc->codec_type = CODEC_TYPE_AUDIO;
@@ -2939,6 +2921,7 @@ static void opt_new_subtitle_stream(void)
         fprintf(stderr, "Could not alloc stream\n");
         exit(1);
     }
+    avcodec_get_context_defaults2(st->codec, CODEC_TYPE_SUBTITLE);
 
     subtitle_enc = st->codec;
     subtitle_enc->codec_type = CODEC_TYPE_SUBTITLE;
@@ -3459,13 +3442,30 @@ static void opt_target(const char *arg)
     }
 }
 
+static void opt_vstats_file (const char *arg)
+{
+    av_free (vstats_filename);
+    vstats_filename=av_strdup (arg);
+}
+
+static void opt_vstats (void)
+{
+    char filename[40];
+    time_t today2 = time(NULL);
+    struct tm *today = localtime(&today2);
+
+    snprintf(filename, sizeof(filename), "vstats_%02d%02d%02d.log", today->tm_hour, today->tm_min,
+             today->tm_sec);
+    opt_vstats_file(filename);
+}
+
 static void opt_video_bsf(const char *arg)
 {
     AVBitStreamFilterContext *bsfc= av_bitstream_filter_init(arg); //FIXME split name and args for filter at '='
     AVBitStreamFilterContext **bsfp;
 
     if(!bsfc){
-        fprintf(stderr, "Unkown bitstream filter %s\n", arg);
+        fprintf(stderr, "Unknown bitstream filter %s\n", arg);
         exit(1);
     }
 
@@ -3483,7 +3483,7 @@ static void opt_audio_bsf(const char *arg)
     AVBitStreamFilterContext **bsfp;
 
     if(!bsfc){
-        fprintf(stderr, "Unkown bitstream filter %s\n", arg);
+        fprintf(stderr, "Unknown bitstream filter %s\n", arg);
         exit(1);
     }
 
@@ -3507,9 +3507,14 @@ static void show_version(void)
 
 static int opt_default(const char *opt, const char *arg){
     int type;
-    const AVOption *o;
-    for(type=0; type<CODEC_TYPE_NB; type++)
-        o = av_set_string(avctx_opts[type], opt, arg);
+    const AVOption *o= NULL;
+    int opt_types[]={AV_OPT_FLAG_VIDEO_PARAM, AV_OPT_FLAG_AUDIO_PARAM, 0, AV_OPT_FLAG_SUBTITLE_PARAM, 0};
+
+    for(type=0; type<CODEC_TYPE_NB; type++){
+        const AVOption *o2 = av_find_opt(avctx_opts[0], opt, NULL, opt_types[type], opt_types[type]);
+        if(o2)
+            o = av_set_string(avctx_opts[type], opt, arg);
+    }
     if(!o)
         o = av_set_string(avformat_opts, opt, arg);
     if(!o){
@@ -3552,7 +3557,7 @@ const OptionDef options[] = {
     { "map", HAS_ARG | OPT_EXPERT, {(void*)opt_map}, "set input stream mapping", "file:stream[:syncfile:syncstream]" },
     { "map_meta_data", HAS_ARG | OPT_EXPERT, {(void*)opt_map_meta_data}, "set meta data information of outfile from infile", "outfile:infile" },
     { "t", HAS_ARG, {(void*)opt_recording_time}, "set the recording time", "duration" },
-    { "fs", HAS_ARG | OPT_INT, {(void*)&limit_filesize}, "set the limit file size", "limit_size" }, //
+    { "fs", HAS_ARG | OPT_INT64, {(void*)&limit_filesize}, "set the limit file size in bytes", "limit_size" }, //
     { "ss", HAS_ARG, {(void*)opt_start_time}, "set the start time offset", "time_off" },
     { "itsoffset", HAS_ARG, {(void*)opt_input_ts_offset}, "set the input ts offset", "time_off" },
     { "title", HAS_ARG | OPT_STRING, {(void*)&str_title}, "set the title", "string" },
@@ -3615,7 +3620,8 @@ const OptionDef options[] = {
     { "deinterlace", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&do_deinterlace},
       "deinterlace pictures" },
     { "psnr", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&do_psnr}, "calculate PSNR of compressed frames" },
-    { "vstats", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&do_vstats}, "dump video coding statistics to file" },
+    { "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" },
     { "vhook", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)add_frame_hooker}, "insert video processing module", "module" },
     { "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" },
@@ -3759,8 +3765,9 @@ int main(int argc, char **argv)
 
     av_register_all();
 
-    for(i=0; i<CODEC_TYPE_NB; i++)
-        avctx_opts[i]= avcodec_alloc_context();
+    for(i=0; i<CODEC_TYPE_NB; i++){
+        avctx_opts[i]= avcodec_alloc_context2(i);
+    }
     avformat_opts = av_alloc_format_context();
 
     if (argc <= 1)
@@ -3811,6 +3818,12 @@ int main(int argc, char **argv)
     av_free(intra_matrix);
     av_free(inter_matrix);
 
+    if (fvstats)
+        fclose(fvstats);
+    av_free(vstats_filename);
+
+    av_free(opt_names);
+
 #ifdef CONFIG_POWERPC_PERF
     extern void powerpc_display_perf_report(void);
     powerpc_display_perf_report();