]> git.sesse.net Git - ffmpeg/blobdiff - ffmpeg.c
End startcode prefix search at the end of a AVC unit.
[ffmpeg] / ffmpeg.c
index 86b8049f16488e07a9582e776f412d44041eca98..d1a00b81d0647a3954f728e18b594a3311decd9f 100644 (file)
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -91,7 +91,7 @@ static const OptionDef options[];
 
 #define MAX_FILES 20
 
-static char *last_asked_format = NULL;
+static const char *last_asked_format = NULL;
 static AVFormatContext *input_files[MAX_FILES];
 static int64_t input_files_ts_offset[MAX_FILES];
 static double input_files_ts_scale[MAX_FILES][MAX_STREAMS];
@@ -219,7 +219,7 @@ static int64_t timer_start;
 
 static uint8_t *audio_buf;
 static uint8_t *audio_out;
-static uint8_t *audio_out2;
+unsigned int allocated_audio_out_size, allocated_audio_buf_size;
 
 static short *samples;
 
@@ -450,7 +450,7 @@ static int av_exit(int ret)
     av_free(sws_opts);
     av_free(audio_buf);
     av_free(audio_out);
-    av_free(audio_out2);
+    allocated_audio_buf_size= allocated_audio_out_size= 0;
     av_free(samples);
 
     if (received_sigterm) {
@@ -557,21 +557,36 @@ static void do_audio_out(AVFormatContext *s,
                          unsigned char *buf, int size)
 {
     uint8_t *buftmp;
-    const int audio_out_size= 4*MAX_AUDIO_PACKET_SIZE;
+    int64_t audio_out_size, audio_buf_size;
 
     int size_out, frame_bytes, ret;
     AVCodecContext *enc= ost->st->codec;
     AVCodecContext *dec= ist->st->codec;
     int osize= av_get_bits_per_sample_format(enc->sample_fmt)/8;
     int isize= av_get_bits_per_sample_format(dec->sample_fmt)/8;
+    const int coded_bps = av_get_bits_per_sample(enc->codec->id);
 
-    /* SC: dynamic allocation of buffers */
-    if (!audio_buf)
-        audio_buf = av_malloc(2*MAX_AUDIO_PACKET_SIZE);
-    if (!audio_out)
-        audio_out = av_malloc(audio_out_size);
-    if (!audio_buf || !audio_out)
-        return;               /* Should signal an error ! */
+    audio_buf_size= (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; //saftey factors for the deprecated resampling API
+    audio_buf_size*= osize*enc->channels;
+
+    audio_out_size= FFMAX(audio_buf_size, enc->frame_size * osize * enc->channels);
+    if(coded_bps > 8*osize)
+        audio_out_size= audio_out_size * coded_bps / (8*osize);
+    audio_out_size += FF_MIN_BUFFER_SIZE;
+
+    if(audio_out_size > INT_MAX || audio_buf_size > INT_MAX){
+        fprintf(stderr, "Buffer sizes too large\n");
+        av_exit(1);
+    }
+
+    av_fast_malloc(&audio_buf, &allocated_audio_buf_size, audio_buf_size);
+    av_fast_malloc(&audio_out, &allocated_audio_out_size, audio_out_size);
+    if (!audio_buf || !audio_out){
+        fprintf(stderr, "Out of memory in do_audio_out\n");
+        av_exit(1);
+    }
 
     if (enc->channels != dec->channels)
         ost->audio_resample = 1;
@@ -594,10 +609,6 @@ static void do_audio_out(AVFormatContext *s,
 #define MAKE_SFMT_PAIR(a,b) ((a)+SAMPLE_FMT_NB*(b))
     if (!ost->audio_resample && dec->sample_fmt!=enc->sample_fmt &&
         MAKE_SFMT_PAIR(enc->sample_fmt,dec->sample_fmt)!=ost->reformat_pair) {
-        if (!audio_out2)
-            audio_out2 = av_malloc(audio_out_size);
-        if (!audio_out2)
-            av_exit(1);
         if (ost->reformat_ctx)
             av_audio_convert_free(ost->reformat_ctx);
         ost->reformat_ctx = av_audio_convert_alloc(enc->sample_fmt, 1,
@@ -671,7 +682,7 @@ static void do_audio_out(AVFormatContext *s,
 
     if (!ost->audio_resample && dec->sample_fmt!=enc->sample_fmt) {
         const void *ibuf[6]= {buftmp};
-        void *obuf[6]= {audio_out2};
+        void *obuf[6]= {audio_buf};
         int istride[6]= {isize};
         int ostride[6]= {osize};
         int len= size_out/istride[0];
@@ -681,7 +692,7 @@ static void do_audio_out(AVFormatContext *s,
                 av_exit(1);
             return;
         }
-        buftmp = audio_out2;
+        buftmp = audio_buf;
         size_out = len*osize;
     }
 
@@ -723,7 +734,6 @@ static void do_audio_out(AVFormatContext *s,
         }
     } else {
         AVPacket pkt;
-        int coded_bps = av_get_bits_per_sample(enc->codec->id)/8;
         av_init_packet(&pkt);
 
         ost->sync_opts += size_out / (osize * enc->channels);
@@ -732,7 +742,12 @@ static void do_audio_out(AVFormatContext *s,
         /* determine the size of the coded buffer */
         size_out /= osize;
         if (coded_bps)
-            size_out *= coded_bps;
+            size_out = size_out*coded_bps/8;
+
+        if(size_out > audio_out_size){
+            fprintf(stderr, "Internal error, buffer size too small\n");
+            av_exit(1);
+        }
 
         //FIXME pass ost->sync_opts as AVFrame.pts in avcodec_encode_audio()
         ret = avcodec_encode_audio(enc, audio_out, size_out,
@@ -941,6 +956,15 @@ static void do_video_out(AVFormatContext *s,
         }
     }
 
+    if(    (ost->resample_height != (ist->st->codec->height - (ost->topBand  + ost->bottomBand)))
+        || (ost->resample_width  != (ist->st->codec->width  - (ost->leftBand + ost->rightBand)))
+        || (ost->resample_pix_fmt!= ist->st->codec->pix_fmt) ) {
+
+        fprintf(stderr,"Input Stream #%d.%d frame size changed to %dx%d, %s\n", ist->file_index, ist->index, ist->st->codec->width,     ist->st->codec->height,avcodec_get_pix_fmt_name(ist->st->codec->pix_fmt));
+        if(!ost->video_resample)
+            av_exit(1);
+    }
+
     if (ost->video_resample) {
         padding_src = NULL;
         final_picture = &ost->pict_tmp;
@@ -948,7 +972,6 @@ static void do_video_out(AVFormatContext *s,
           || (ost->resample_width  != (ist->st->codec->width  - (ost->leftBand + ost->rightBand)))
           || (ost->resample_pix_fmt!= ist->st->codec->pix_fmt) ) {
 
-            fprintf(stderr,"Input Stream #%d.%d frame size changed to %dx%d, %s\n", ist->file_index, ist->index, ist->st->codec->width, ist->st->codec->height,avcodec_get_pix_fmt_name(ist->st->codec->pix_fmt));
             /* keep bands proportional to the frame size */
             topBand    = ((int64_t)ist->st->codec->height * ost->original_topBand    / ost->original_height) & ~1;
             bottomBand = ((int64_t)ist->st->codec->height * ost->original_bottomBand / ost->original_height) & ~1;
@@ -1940,11 +1963,11 @@ static int av_encode(AVFormatContext **output_files,
                     ost->original_height = icodec->height;
                     ost->original_width  = icodec->width;
 
-                    ost->resample_height = icodec->height - (frame_topBand  + frame_bottomBand);
-                    ost->resample_width  = icodec->width  - (frame_leftBand + frame_rightBand);
-                    ost->resample_pix_fmt= icodec->pix_fmt;
                     codec->bits_per_raw_sample= 0;
                 }
+                ost->resample_height = icodec->height - (frame_topBand  + frame_bottomBand);
+                ost->resample_width  = icodec->width  - (frame_leftBand + frame_rightBand);
+                ost->resample_pix_fmt= icodec->pix_fmt;
                 ost->encoding_needed = 1;
                 ist->decoding_needed = 1;
                 break;
@@ -2936,7 +2959,11 @@ static void opt_input_file(const char *filename)
             frame_pix_fmt = enc->pix_fmt;
             rfps      = ic->streams[i]->r_frame_rate.num;
             rfps_base = ic->streams[i]->r_frame_rate.den;
-            if(enc->lowres) enc->flags |= CODEC_FLAG_EMU_EDGE;
+            if(enc->lowres) {
+                enc->flags |= CODEC_FLAG_EMU_EDGE;
+                frame_height >>= enc->lowres;
+                frame_width  >>= enc->lowres;
+            }
             if(me_threshold)
                 enc->debug |= FF_DEBUG_MV;
 
@@ -3821,13 +3848,7 @@ static int opt_preset(const char *opt, const char *arg)
 
 static const OptionDef options[] = {
     /* main options */
-    { "L", OPT_EXIT, {(void*)show_license}, "show license" },
-    { "h", OPT_EXIT, {(void*)show_help}, "show help" },
-    { "version", OPT_EXIT, {(void*)show_version}, "show version" },
-    { "formats"  , OPT_EXIT, {(void*)show_formats  }, "show available formats" },
-    { "codecs"   , OPT_EXIT, {(void*)show_codecs   }, "show available codecs" },
-    { "bsfs"     , OPT_EXIT, {(void*)show_bsfs     }, "show available bit stream filters" },
-    { "protocols", OPT_EXIT, {(void*)show_protocols}, "show available protocols" },
+#include "cmdutils_common_opts.h"
     { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
     { "i", HAS_ARG, {(void*)opt_input_file}, "input file name", "filename" },
     { "y", OPT_BOOL, {(void*)&file_overwrite}, "overwrite output files" },
@@ -3851,7 +3872,6 @@ static const OptionDef options[] = {
     { "loop_input", OPT_BOOL | OPT_EXPERT, {(void*)&loop_input}, "loop (current only works with images)" },
     { "loop_output", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&loop_output}, "number of times to loop output in formats that support looping (0 loops forever)", "" },
     { "v", HAS_ARG | OPT_FUNC2, {(void*)opt_verbose}, "set ffmpeg verbosity level", "number" },
-    { "loglevel", HAS_ARG | OPT_FUNC2, {(void*)opt_loglevel}, "set libav* logging level", "loglevel" },
     { "target", HAS_ARG, {(void*)opt_target}, "specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" },
     { "threads", OPT_FUNC2 | HAS_ARG | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
     { "vsync", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&video_sync_method}, "video sync method", "" },
@@ -3944,7 +3964,7 @@ static const OptionDef options[] = {
     { "apre", OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_EXPERT, {(void*)opt_preset}, "set the audio options to the indicated preset", "preset" },
     { "vpre", OPT_FUNC2 | HAS_ARG | OPT_VIDEO | OPT_EXPERT, {(void*)opt_preset}, "set the video options to the indicated preset", "preset" },
     { "spre", OPT_FUNC2 | HAS_ARG | OPT_SUBTITLE | OPT_EXPERT, {(void*)opt_preset}, "set the subtitle options to the indicated preset", "preset" },
-    { "fpre", OPT_FUNC2 | HAS_ARG | OPT_EXPERT, {(void*)opt_preset}, "set options to the indicated preset file", "filename" },
+    { "fpre", OPT_FUNC2 | HAS_ARG | OPT_EXPERT, {(void*)opt_preset}, "set options from indicated preset file", "filename" },
 
     { "default", OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
     { NULL, },