]> git.sesse.net Git - ffmpeg/blobdiff - ffmpeg.c
Fix Indel --> Intel typo.
[ffmpeg] / ffmpeg.c
index cf866b3a242be66e81b123275935a5df18ad4377..7008ad88456abab8dd864934a3e20bcfbb421fd7 100644 (file)
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -19,6 +19,7 @@
 #define HAVE_AV_CONFIG_H
 #include <limits.h>
 #include "avformat.h"
+#include "swscale.h"
 #include "framehook.h"
 #include "dsputil.h"
 #include "opt.h"
@@ -104,7 +105,6 @@ static int frame_rightBand = 0;
 static int max_frames[4] = {INT_MAX, INT_MAX, INT_MAX, INT_MAX};
 static int frame_rate = 25;
 static int frame_rate_base = 1;
-static int video_bit_rate = 200*1000;
 static int video_bit_rate_tolerance = 4000*1000;
 static float video_qscale = 0;
 static int video_qmin = 2;
@@ -161,7 +161,6 @@ static int frame_skip_factor= 0;
 static int frame_skip_exp= 0;
 static int loop_input = 0;
 static int loop_output = AVFMT_NOOUTPUTLOOP;
-static int genpts = 0;
 static int qp_hist = 0;
 
 static int gop_size = 12;
@@ -193,6 +192,7 @@ static char *str_title = NULL;
 static char *str_author = NULL;
 static char *str_copyright = NULL;
 static char *str_comment = NULL;
+static char *str_album = NULL;
 static int do_benchmark = 0;
 static int do_hex_dump = 0;
 static int do_pkt_dump = 0;
@@ -246,9 +246,12 @@ static int limit_filesize = 0; //
 static int pgmyuv_compatibility_hack=0;
 static int dts_delta_threshold = 10;
 
+static int sws_flags = SWS_BICUBIC;
+
 const char **opt_names=NULL;
 int opt_name_count=0;
 AVCodecContext *avctx_opts;
+AVFormatContext *avformat_opts;
 
 static AVBitStreamFilterContext *video_bitstream_filters=NULL;
 static AVBitStreamFilterContext *audio_bitstream_filters=NULL;
@@ -273,7 +276,8 @@ typedef struct AVOutputStream {
     /* video only */
     int video_resample;
     AVFrame pict_tmp;      /* temporary image for resampling */
-    ImgReSampleContext *img_resample_ctx; /* for image resampling */
+    struct SwsContext *img_resample_ctx; /* for image resampling */
+    int resample_height;
 
     int video_crop;
     int topBand;             /* cropping area sizes */
@@ -728,12 +732,10 @@ static void do_video_out(AVFormatContext *s,
 {
     int nb_frames, i, ret;
     AVFrame *final_picture, *formatted_picture, *resampling_dst, *padding_src;
-    AVFrame picture_format_temp, picture_crop_temp, picture_pad_temp;
+    AVFrame picture_crop_temp, picture_pad_temp;
     uint8_t *buf = NULL, *buf1 = NULL;
     AVCodecContext *enc, *dec;
-    enum PixelFormat target_pixfmt;
 
-    avcodec_get_frame_defaults(&picture_format_temp);
     avcodec_get_frame_defaults(&picture_crop_temp);
     avcodec_get_frame_defaults(&picture_pad_temp);
 
@@ -770,38 +772,14 @@ static void do_video_out(AVFormatContext *s,
     if (nb_frames <= 0)
         return;
 
-    /* convert pixel format if needed */
-    target_pixfmt = ost->video_resample ? PIX_FMT_YUV420P : enc->pix_fmt;
-    if (dec->pix_fmt != target_pixfmt) {
-        int size;
-
-        /* create temporary picture */
-        size = avpicture_get_size(target_pixfmt, dec->width, dec->height);
-        buf = av_malloc(size);
-        if (!buf)
-            return;
-        formatted_picture = &picture_format_temp;
-        avpicture_fill((AVPicture*)formatted_picture, buf, target_pixfmt, dec->width, dec->height);
-
-        if (img_convert((AVPicture*)formatted_picture, target_pixfmt,
-                        (AVPicture *)in_picture, dec->pix_fmt,
-                        dec->width, dec->height) < 0) {
-
-            if (verbose >= 0)
-                fprintf(stderr, "pixel format conversion not handled\n");
-
-            goto the_end;
-        }
-    } else {
-        formatted_picture = in_picture;
-    }
-
     if (ost->video_crop) {
-        if (img_crop((AVPicture *)&picture_crop_temp, (AVPicture *)formatted_picture, target_pixfmt, ost->topBand, ost->leftBand) < 0) {
+        if (img_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;
         }
         formatted_picture = &picture_crop_temp;
+    } else {
+        formatted_picture = in_picture;
     }
 
     final_picture = formatted_picture;
@@ -810,7 +788,7 @@ static void do_video_out(AVFormatContext *s,
     if (ost->video_pad) {
         final_picture = &ost->pict_tmp;
         if (ost->video_resample) {
-            if (img_crop((AVPicture *)&picture_pad_temp, (AVPicture *)final_picture, target_pixfmt, ost->padtop, ost->padleft) < 0) {
+            if (img_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;
             }
@@ -818,36 +796,11 @@ static void do_video_out(AVFormatContext *s,
         }
     }
 
-    /* XXX: resampling could be done before raw format conversion in
-       some cases to go faster */
-    /* XXX: only works for YUV420P */
     if (ost->video_resample) {
         padding_src = NULL;
         final_picture = &ost->pict_tmp;
-        img_resample(ost->img_resample_ctx, (AVPicture *)resampling_dst, (AVPicture*)formatted_picture);
-    }
-
-    if (enc->pix_fmt != target_pixfmt) {
-        int size;
-
-        av_free(buf);
-        /* create temporary picture */
-        size = avpicture_get_size(enc->pix_fmt, enc->width, enc->height);
-        buf = av_malloc(size);
-        if (!buf)
-            return;
-        final_picture = &picture_format_temp;
-        avpicture_fill((AVPicture*)final_picture, buf, enc->pix_fmt, enc->width, enc->height);
-
-        if (img_convert((AVPicture*)final_picture, enc->pix_fmt,
-                        (AVPicture*)&ost->pict_tmp, target_pixfmt,
-                        enc->width, enc->height) < 0) {
-
-            if (verbose >= 0)
-                fprintf(stderr, "pixel format conversion not handled\n");
-
-            goto the_end;
-        }
+        sws_scale(ost->img_resample_ctx, formatted_picture->data, formatted_picture->linesize,
+              0, ost->resample_height, resampling_dst->data, resampling_dst->linesize);
     }
 
     if (ost->video_pad) {
@@ -1680,7 +1633,8 @@ static int av_encode(AVFormatContext **output_files,
                                 (frame_padleft + frame_padright)) ||
                         (codec->height != icodec->height -
                                 (frame_topBand  + frame_bottomBand) +
-                                (frame_padtop + frame_padbottom)));
+                                (frame_padtop + frame_padbottom)) ||
+                        (codec->pix_fmt != icodec->pix_fmt));
                 if (ost->video_crop) {
                     ost->topBand = frame_topBand;
                     ost->leftBand = frame_leftBand;
@@ -1699,16 +1653,23 @@ 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, PIX_FMT_YUV420P,
+                    if( avpicture_alloc( (AVPicture*)&ost->pict_tmp, codec->pix_fmt,
                                          codec->width, codec->height ) )
                         goto fail;
 
-                    ost->img_resample_ctx = img_resample_init(
+                    ost->img_resample_ctx = sws_getContext(
+                            icodec->width - (frame_leftBand + frame_rightBand),
+                            icodec->height - (frame_topBand + frame_bottomBand),
+                            icodec->pix_fmt,
                             codec->width - (frame_padleft + frame_padright),
                             codec->height - (frame_padtop + frame_padbottom),
-                            icodec->width - (frame_leftBand + frame_rightBand),
-                            icodec->height - (frame_topBand + frame_bottomBand));
-
+                            codec->pix_fmt,
+                            sws_flags, NULL, NULL, NULL);
+                    if (ost->img_resample_ctx == NULL) {
+                        fprintf(stderr, "Cannot get resampling context\n");
+                        exit(1);
+                    }
+                    ost->resample_height = icodec->height - (frame_topBand + frame_bottomBand);
                 }
                 ost->encoding_needed = 1;
                 ist->decoding_needed = 1;
@@ -2086,7 +2047,7 @@ static int av_encode(AVFormatContext **output_files,
                                           initialized but set to zero */
                 av_free(ost->pict_tmp.data[0]);
                 if (ost->video_resample)
-                    img_resample_close(ost->img_resample_ctx);
+                    sws_freeContext(ost->img_resample_ctx);
                 if (ost->audio_resample)
                     audio_resample_close(ost->resample);
                 av_free(ost);
@@ -2154,11 +2115,6 @@ static void opt_format(const char *arg)
     }
 }
 
-static void opt_video_bitrate(const char *arg)
-{
-    video_bit_rate = atoi(arg) * 1000;
-}
-
 static void opt_video_bitrate_tolerance(const char *arg)
 {
     video_bit_rate_tolerance = atoi(arg) * 1000;
@@ -2819,7 +2775,10 @@ static void opt_input_file(const char *filename)
                    !strcmp( filename, "/dev/stdin" );
 
     /* get default parameters from command line */
+    ic = av_alloc_format_context();
+
     memset(ap, 0, sizeof(*ap));
+    ap->prealloced_context = 1;
     ap->sample_rate = audio_sample_rate;
     ap->channels = audio_channels;
     ap->time_base.den = frame_rate;
@@ -2836,6 +2795,12 @@ static void opt_input_file(const char *filename)
     if(pgmyuv_compatibility_hack)
         ap->video_codec_id= CODEC_ID_PGMYUV;
 
+    for(i=0; i<opt_name_count; i++){
+        AVOption *opt;
+        double d= av_get_double(avformat_opts, opt_names[i], &opt);
+        if(d==d && (opt->flags&AV_OPT_FLAG_DECODING_PARAM))
+            av_set_double(ic, opt_names[i], d);
+    }
     /* open the input file with generic libav function */
     err = av_open_input_file(&ic, filename, file_iformat, 0, ap);
     if (err < 0) {
@@ -2845,9 +2810,6 @@ static void opt_input_file(const char *filename)
 
     ic->loop_input = loop_input;
 
-    if(genpts)
-        ic->flags|= AVFMT_FLAG_GENPTS;
-
     /* If not enough info to get the stream parameters, we decode the
        first frames to get it. (used in mpeg case for example) */
     ret = av_find_stream_info(ic);
@@ -3052,7 +3014,6 @@ static void new_video_stream(AVFormatContext *oc)
                  av_set_double(video_enc, opt_names[i], d);
         }
 
-        video_enc->bit_rate = video_bit_rate;
         video_enc->bit_rate_tolerance = video_bit_rate_tolerance;
         video_enc->time_base.den = frame_rate;
         video_enc->time_base.num = frame_rate_base;
@@ -3075,7 +3036,7 @@ static void new_video_stream(AVFormatContext *oc)
 
         video_enc->width = frame_width + frame_padright + frame_padleft;
         video_enc->height = frame_height + frame_padtop + frame_padbottom;
-        video_enc->sample_aspect_ratio = av_d2q(frame_aspect_ratio*frame_height/frame_width, 255);
+        video_enc->sample_aspect_ratio = av_d2q(frame_aspect_ratio*video_enc->height/video_enc->width, 255);
         video_enc->pix_fmt = frame_pix_fmt;
 
         if(codec && codec->pix_fmts){
@@ -3342,7 +3303,7 @@ static void opt_new_video_stream(void)
 static void opt_output_file(const char *filename)
 {
     AVFormatContext *oc;
-    int use_video, use_audio, input_has_video, input_has_audio;
+    int use_video, use_audio, input_has_video, input_has_audio, i;
     AVFormatParameters params, *ap = &params;
 
     if (!strcmp(filename, "-"))
@@ -3415,13 +3376,15 @@ static void opt_output_file(const char *filename)
             pstrcpy(oc->copyright, sizeof(oc->copyright), str_copyright);
         if (str_comment)
             pstrcpy(oc->comment, sizeof(oc->comment), str_comment);
+        if (str_album)
+            pstrcpy(oc->album, sizeof(oc->album), str_album);
     }
 
     output_files[nb_output_files++] = oc;
 
     /* check filename in case of an image number is expected */
     if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
-        if (filename_number_test(oc->filename) < 0) {
+        if (!av_filename_number_test(oc->filename)) {
             print_error(oc->filename, AVERROR_NUMEXPECTED);
             exit(1);
         }
@@ -3472,6 +3435,13 @@ static void opt_output_file(const char *filename)
     oc->max_delay= (int)(mux_max_delay*AV_TIME_BASE);
     oc->loop_output = loop_output;
 
+    for(i=0; i<opt_name_count; i++){
+        AVOption *opt;
+        double d = av_get_double(avformat_opts, opt_names[i], &opt);
+        if(d==d && (opt->flags&AV_OPT_FLAG_ENCODING_PARAM))
+            av_set_double(oc, opt_names[i], d);
+    }
+
     /* reset some options */
     file_oformat = NULL;
     file_iformat = NULL;
@@ -3602,7 +3572,9 @@ static int64_t getutime(void)
 }
 #endif
 
+#if defined(CONFIG_FFM_DEMUXER) || defined(CONFIG_FFM_MUXER)
 extern int ffm_nopts;
+#endif
 
 static void show_formats(void)
 {
@@ -3841,7 +3813,7 @@ static void opt_target(const char *arg)
         opt_frame_rate(frame_rates[norm]);
         opt_gop_size(norm ? "18" : "15");
 
-        video_bit_rate = 1150000;
+        opt_default("b", "1150000");
         video_rc_max_rate = 1150000;
         video_rc_min_rate = 1150000;
         video_rc_buffer_size = 40*1024*8;
@@ -3868,7 +3840,7 @@ static void opt_target(const char *arg)
         opt_frame_rate(frame_rates[norm]);
         opt_gop_size(norm ? "18" : "15");
 
-        video_bit_rate = 2040000;
+        opt_default("b", "2040000");
         video_rc_max_rate = 2516000;
         video_rc_min_rate = 0; //1145000;
         video_rc_buffer_size = 224*1024*8;
@@ -3890,7 +3862,7 @@ static void opt_target(const char *arg)
         opt_frame_rate(frame_rates[norm]);
         opt_gop_size(norm ? "18" : "15");
 
-        video_bit_rate = 6000000;
+        opt_default("b", "6000000");
         video_rc_max_rate = 9000000;
         video_rc_min_rate = 0; //1500000;
         video_rc_buffer_size = 224*1024*8;
@@ -3967,6 +3939,8 @@ static void show_version(void)
 
 static int opt_default(const char *opt, const char *arg){
     AVOption *o= av_set_string(avctx_opts, opt, arg);
+    if(!o)
+        o = av_set_string(avformat_opts, opt, arg);
     if(!o)
         return -1;
 
@@ -3976,9 +3950,11 @@ static int opt_default(const char *opt, const char *arg){
     opt_names= av_realloc(opt_names, sizeof(void*)*(opt_name_count+1));
     opt_names[opt_name_count++]= o->name;
 
+#if defined(CONFIG_FFM_DEMUXER) || defined(CONFIG_FFM_MUXER)
     /* disable generate of real time pts in ffm (need to be supressed anyway) */
     if(avctx_opts->flags & CODEC_FLAG_BITEXACT)
         ffm_nopts = 1;
+#endif
 
     if(avctx_opts->debug)
         av_log_set_level(AV_LOG_DEBUG);
@@ -4006,6 +3982,7 @@ const OptionDef options[] = {
     { "author", HAS_ARG | OPT_STRING, {(void*)&str_author}, "set the author", "string" },
     { "copyright", HAS_ARG | OPT_STRING, {(void*)&str_copyright}, "set the copyright", "string" },
     { "comment", HAS_ARG | OPT_STRING, {(void*)&str_comment}, "set the comment", "string" },
+    { "album", HAS_ARG | OPT_STRING, {(void*)&str_album}, "set the album", "string" },
     { "benchmark", OPT_BOOL | OPT_EXPERT, {(void*)&do_benchmark},
       "add timings for benchmarking" },
     { "dump", OPT_BOOL | OPT_EXPERT, {(void*)&do_pkt_dump},
@@ -4026,7 +4003,6 @@ const OptionDef options[] = {
     { "dts_delta_threshold", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&dts_delta_threshold}, "timestamp discontinuity delta threshold", "" },
 
     /* video options */
-    { "b", HAS_ARG | OPT_VIDEO, {(void*)opt_video_bitrate}, "set video bitrate (in kbit/s)", "bitrate" },
     { "vframes", OPT_INT | HAS_ARG | OPT_VIDEO, {(void*)&max_frames[CODEC_TYPE_VIDEO]}, "set the number of video frames to record", "number" },
     { "aframes", OPT_INT | HAS_ARG | OPT_AUDIO, {(void*)&max_frames[CODEC_TYPE_AUDIO]}, "set the number of audio frames to record", "number" },
     { "dframes", OPT_INT | HAS_ARG, {(void*)&max_frames[CODEC_TYPE_DATA]}, "set the number of data frames to record", "number" },
@@ -4103,7 +4079,6 @@ const OptionDef options[] = {
     { "skip_factor", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&frame_skip_factor}, "frame skip factor", "factor" },
     { "skip_exp", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&frame_skip_exp}, "frame skip exponent", "exponent" },
     { "newvideo", OPT_VIDEO, {(void*)opt_new_video_stream}, "add a new video stream to the current output stream" },
-    { "genpts", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, { (void *)&genpts }, "generate pts" },
     { "qphist", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, { (void *)&qp_hist }, "show QP histogram" },
 
     /* audio options */
@@ -4230,6 +4205,7 @@ static void show_help(void)
                       OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_GRAB,
                       OPT_EXPERT);
     av_opt_show(avctx_opts, NULL);
+    av_opt_show(avformat_opts, NULL);
 
     exit(1);
 }
@@ -4247,6 +4223,7 @@ int main(int argc, char **argv)
     av_register_all();
 
     avctx_opts= avcodec_alloc_context();
+    avformat_opts = av_alloc_format_context();
 
     if (argc <= 1)
         show_help();