X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=ffmpeg.c;h=cdc78ea5d2dff41bb386726b19a789299adfd70d;hb=acff54d83128e955bad5563196ffee943d7df0cd;hp=7008ad88456abab8dd864934a3e20bcfbb421fd7;hpb=3c0ba8703cc8b3a6972aa2e6136e0ed391c4d194;p=ffmpeg diff --git a/ffmpeg.c b/ffmpeg.c index 7008ad88456..cdc78ea5d2d 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -2,36 +2,41 @@ * 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 #include #include "avformat.h" #include "swscale.h" #include "framehook.h" #include "dsputil.h" #include "opt.h" +#include "fifo.h" -#ifndef __MINGW32__ +#ifdef __MINGW32__ +#include +#else #include #include #include #include #include #include -#include #endif #ifdef CONFIG_OS2 #include @@ -88,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; @@ -105,18 +109,8 @@ 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_tolerance = 4000*1000; static float video_qscale = 0; -static int video_qmin = 2; -static int video_qmax = 31; -static int video_lmin = 2*FF_QP2LAMBDA; -static int video_lmax = 31*FF_QP2LAMBDA; -static int video_mb_lmin = 2*FF_QP2LAMBDA; -static int video_mb_lmax = 31*FF_QP2LAMBDA; static int video_qdiff = 3; -static float video_qblur = 0.5; -static float video_qsquish = 0.0; -static float video_qcomp = 0.5; static uint16_t *intra_matrix = NULL; static uint16_t *inter_matrix = NULL; #if 0 //experimental, (can be removed) @@ -126,44 +120,22 @@ static int video_rc_qmod_freq=0; #endif static char *video_rc_override_string=NULL; static char *video_rc_eq="tex^qComp"; -static int video_rc_buffer_size=0; -static float video_rc_buffer_aggressivity=1.0; -static int video_rc_max_rate=0; -static int video_rc_min_rate=0; -static float video_rc_initial_cplx=0; -static float video_b_qfactor = 1.25; -static float video_b_qoffset = 1.25; -static float video_i_qfactor = -0.8; -static float video_i_qoffset = 0.0; -static int video_intra_quant_bias= FF_DEFAULT_QUANT_BIAS; -static int video_inter_quant_bias= FF_DEFAULT_QUANT_BIAS; static int me_method = ME_EPZS; static int video_disable = 0; static int video_discard = 0; static int video_codec_id = CODEC_ID_NONE; static int video_codec_tag = 0; static int same_quality = 0; -static int b_frames = 0; -static int pre_me = 0; static int do_deinterlace = 0; -static int workaround_bugs = FF_BUG_AUTODETECT; static int packet_size = 0; -static int error_rate = 0; static int strict = 0; static int top_field_first = -1; -static int sc_threshold = 0; static int me_threshold = 0; -static int mb_threshold = 0; static int intra_dc_precision = 8; -static int me_penalty_compensation= 256; -static int frame_skip_threshold= 0; -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 qp_hist = 0; -static int gop_size = 12; static int intra_only = 0; static int audio_sample_rate = 44100; static int audio_bit_rate = 64000; @@ -178,8 +150,6 @@ static char *audio_language = NULL; static int subtitle_codec_id = CODEC_ID_NONE; static char *subtitle_language = NULL; -static int mux_rate= 0; -static int mux_packet_size= 0; static float mux_preload= 0.5; static float mux_max_delay= 0.7; @@ -234,7 +204,6 @@ static int using_vhook = 0; static int verbose = 1; static int thread_count= 1; static int q_pressed = 0; -static int me_range = 0; static int64_t video_size = 0; static int64_t audio_size = 0; static int64_t extra_size = 0; @@ -292,7 +261,7 @@ typedef struct AVOutputStream { /* audio only */ int audio_resample; ReSampleContext *resample; /* for audio resampling */ - FifoBuffer fifo; /* for compression: one audio fifo per codec */ + AVFifoBuffer fifo; /* for compression: one audio fifo per codec */ FILE *logfile; } AVOutputStream; @@ -325,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; @@ -342,6 +314,7 @@ sigterm_handler(int sig) static void term_init(void) { +#ifndef __MINGW32__ struct termios tty; tcgetattr (0, &tty); @@ -357,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 @@ -373,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 @@ -392,6 +370,7 @@ static int read_key(void) return n; } +#endif return -1; } @@ -400,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; @@ -496,7 +455,7 @@ static void do_audio_out(AVFormatContext *s, if(audio_sync_method){ double delta = get_sync_ipts(ost) * enc->sample_rate - ost->sync_opts - - fifo_size(&ost->fifo, ost->fifo.rptr)/(ost->st->codec->channels * 2); + - av_fifo_size(&ost->fifo)/(ost->st->codec->channels * 2); double idelta= delta*ist->st->codec->sample_rate / enc->sample_rate; int byte_delta= ((int)idelta)*2*ist->st->codec->channels; @@ -533,13 +492,13 @@ 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), fifo_size(&ost->fifo, ost->fifo.rptr)/(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); } } }else ost->sync_opts= lrintf(get_sync_ipts(ost) * enc->sample_rate) - - fifo_size(&ost->fifo, ost->fifo.rptr)/(ost->st->codec->channels * 2); //FIXME wrong + - av_fifo_size(&ost->fifo)/(ost->st->codec->channels * 2); //FIXME wrong if (ost->audio_resample) { buftmp = audio_buf; @@ -555,13 +514,11 @@ static void do_audio_out(AVFormatContext *s, /* now encode as many frames as possible */ if (enc->frame_size > 1) { /* output resampled raw samples */ - fifo_write(&ost->fifo, buftmp, size_out, - &ost->fifo.wptr); + av_fifo_write(&ost->fifo, buftmp, size_out); frame_bytes = enc->frame_size * 2 * enc->channels; - while (fifo_read(&ost->fifo, audio_buf, frame_bytes, - &ost->fifo.rptr) == 0) { + while (av_fifo_read(&ost->fifo, audio_buf, frame_bytes) == 0) { AVPacket pkt; av_init_packet(&pkt); @@ -755,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) @@ -855,17 +812,21 @@ 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); + if (ret == -1) { + fprintf(stderr, "Video encoding failed\n"); + exit(1); + } //enc->frame_number = enc->real_pict_num; if(ret>0){ pkt.data= bit_buffer; 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);*/ @@ -920,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; @@ -1342,14 +1303,13 @@ static int output_packet(AVInputStream *ist, int ist_index, switch(ost->st->codec->codec_type) { case CODEC_TYPE_AUDIO: - fifo_bytes = fifo_size(&ost->fifo, NULL); + fifo_bytes = av_fifo_size(&ost->fifo); ret = 0; /* encode any samples remaining in fifo */ if(fifo_bytes > 0 && enc->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) { int fs_tmp = enc->frame_size; enc->frame_size = fifo_bytes / (2 * enc->channels); - if(fifo_read(&ost->fifo, (uint8_t *)samples, fifo_bytes, - &ost->fifo.rptr) == 0) { + if(av_fifo_read(&ost->fifo, (uint8_t *)samples, fifo_bytes) == 0) { ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, samples); } enc->frame_size = fs_tmp; @@ -1456,6 +1416,10 @@ static int av_encode(AVFormatContext **output_files, nb_ostreams = 0; for(i=0;inb_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) { @@ -1566,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; @@ -1588,7 +1555,7 @@ static int av_encode(AVFormatContext **output_files, } else { switch(codec->codec_type) { case CODEC_TYPE_AUDIO: - if (fifo_init(&ost->fifo, 2 * MAX_AUDIO_PACKET_SIZE)) + if (av_fifo_init(&ost->fifo, 2 * MAX_AUDIO_PACKET_SIZE)) goto fail; if (codec->channels == icodec->channels && @@ -1857,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; @@ -1952,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]); @@ -2043,8 +2008,8 @@ static int av_encode(AVFormatContext **output_files, fclose(ost->logfile); ost->logfile = NULL; } - fifo_free(&ost->fifo); /* works even if fifo is not - initialized but set to zero */ + av_fifo_free(&ost->fifo); /* works even if fifo is not + initialized but set to zero */ av_free(ost->pict_tmp.data[0]); if (ost->video_resample) sws_freeContext(ost->img_resample_ctx); @@ -2083,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 */ @@ -2115,26 +2065,6 @@ static void opt_format(const char *arg) } } -static void opt_video_bitrate_tolerance(const char *arg) -{ - video_bit_rate_tolerance = atoi(arg) * 1000; -} - -static void opt_video_bitrate_max(const char *arg) -{ - video_rc_max_rate = atoi(arg) * 1000; -} - -static void opt_video_bitrate_min(const char *arg) -{ - video_rc_min_rate = atoi(arg) * 1000; -} - -static void opt_video_buffer_size(const char *arg) -{ - video_rc_buffer_size = atoi(arg) * 8*1024; -} - static void opt_video_rc_eq(char *arg) { video_rc_eq = arg; @@ -2145,22 +2075,11 @@ static void opt_video_rc_override_string(char *arg) video_rc_override_string = arg; } - -static void opt_workaround_bugs(const char *arg) -{ - workaround_bugs = atoi(arg); -} - static void opt_me_threshold(const char *arg) { me_threshold = atoi(arg); } -static void opt_mb_threshold(const char *arg) -{ - mb_threshold = atoi(arg); -} - static void opt_verbose(const char *arg) { verbose = atoi(arg); @@ -2374,28 +2293,6 @@ static void opt_frame_aspect_ratio(const char *arg) frame_aspect_ratio = ar; } -static void opt_gop_size(const char *arg) -{ - gop_size = atoi(arg); -} - -static void opt_b_frames(const char *arg) -{ - b_frames = atoi(arg); - if (b_frames > FF_MAX_B_FRAMES) { - fprintf(stderr, "\nCannot have more than %d B frames, increase FF_MAX_B_FRAMES.\n", FF_MAX_B_FRAMES); - exit(1); - } else if (b_frames < 1) { - fprintf(stderr, "\nNumber of B frames must be higher than 0\n"); - exit(1); - } -} - -static void opt_pre_me(const char *arg) -{ - pre_me = atoi(arg); -} - static void opt_qscale(const char *arg) { video_qscale = atof(arg); @@ -2406,66 +2303,6 @@ static void opt_qscale(const char *arg) } } -static void opt_qsquish(const char *arg) -{ - video_qsquish = atof(arg); - if (video_qsquish < 0.0 || - video_qsquish > 99.0) { - fprintf(stderr, "qsquish must be >= 0.0 and <= 99.0\n"); - exit(1); - } -} - -static void opt_lmax(const char *arg) -{ - video_lmax = atof(arg)*FF_QP2LAMBDA; -} - -static void opt_lmin(const char *arg) -{ - video_lmin = atof(arg)*FF_QP2LAMBDA; -} - -static void opt_qmin(const char *arg) -{ - video_qmin = atoi(arg); - if (video_qmin < 1 || - video_qmin > 51) { - fprintf(stderr, "qmin must be >= 1 and <= 51\n"); - exit(1); - } -} - -static void opt_qmax(const char *arg) -{ - video_qmax = atoi(arg); - if (video_qmax < 1 || - video_qmax > 51) { - fprintf(stderr, "qmax must be >= 1 and <= 51\n"); - exit(1); - } -} - -static void opt_mb_lmin(const char *arg) -{ - video_mb_lmin = atof(arg)*FF_QP2LAMBDA; - if (video_mb_lmin < 1 || - video_mb_lmin > FF_LAMBDA_MAX) { - fprintf(stderr, "mblmin must be >= 1 and <= %d\n", FF_LAMBDA_MAX / FF_QP2LAMBDA); - exit(1); - } -} - -static void opt_mb_lmax(const char *arg) -{ - video_mb_lmax = atof(arg)*FF_QP2LAMBDA; - if (video_mb_lmax < 1 || - video_mb_lmax > FF_LAMBDA_MAX) { - fprintf(stderr, "mblmax must be >= 1 and <= %d\n", FF_LAMBDA_MAX / FF_QP2LAMBDA); - exit(1); - } -} - static void opt_qdiff(const char *arg) { video_qdiff = atoi(arg); @@ -2476,56 +2313,11 @@ static void opt_qdiff(const char *arg) } } -static void opt_qblur(const char *arg) -{ - video_qblur = atof(arg); -} - -static void opt_qcomp(const char *arg) -{ - video_qcomp = atof(arg); -} - -static void opt_rc_initial_cplx(const char *arg) -{ - video_rc_initial_cplx = atof(arg); -} -static void opt_b_qfactor(const char *arg) -{ - video_b_qfactor = atof(arg); -} -static void opt_i_qfactor(const char *arg) -{ - video_i_qfactor = atof(arg); -} -static void opt_b_qoffset(const char *arg) -{ - video_b_qoffset = atof(arg); -} -static void opt_i_qoffset(const char *arg) -{ - video_i_qoffset = atof(arg); -} - -static void opt_ibias(const char *arg) -{ - video_intra_quant_bias = atoi(arg); -} -static void opt_pbias(const char *arg) -{ - video_inter_quant_bias = atoi(arg); -} - static void opt_packet_size(const char *arg) { packet_size= atoi(arg); } -static void opt_error_rate(const char *arg) -{ - error_rate= atoi(arg); -} - static void opt_strict(const char *arg) { strict= atoi(arg); @@ -2536,16 +2328,6 @@ static void opt_top_field_first(const char *arg) top_field_first= atoi(arg); } -static void opt_sc_threshold(const char *arg) -{ - sc_threshold= atoi(arg); -} - -static void opt_me_range(const char *arg) -{ - me_range = atoi(arg); -} - static void opt_thread_count(const char *arg) { thread_count= atoi(arg); @@ -2785,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; @@ -2870,7 +2651,6 @@ 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; - enc->workaround_bugs = workaround_bugs; if(enc->lowres) enc->flags |= CODEC_FLAG_EMU_EDGE; if(me_threshold) enc->debug |= FF_DEBUG_MV; @@ -2878,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); @@ -2913,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; @@ -3014,7 +2793,6 @@ static void new_video_stream(AVFormatContext *oc) av_set_double(video_enc, opt_names[i], d); } - video_enc->bit_rate_tolerance = video_bit_rate_tolerance; video_enc->time_base.den = frame_rate; video_enc->time_base.num = frame_rate_base; if(codec && codec->supported_framerates){ @@ -3049,9 +2827,7 @@ static void new_video_stream(AVFormatContext *oc) video_enc->pix_fmt = codec->pix_fmts[0]; } - if (!intra_only) - video_enc->gop_size = gop_size; - else + if (intra_only) video_enc->gop_size = 0; if (video_qscale || same_quality) { video_enc->flags |= CODEC_FLAG_QSCALE; @@ -3064,24 +2840,8 @@ static void new_video_stream(AVFormatContext *oc) if(inter_matrix) video_enc->inter_matrix = inter_matrix; - video_enc->pre_me = pre_me; - - if (b_frames) { - video_enc->max_b_frames = b_frames; - video_enc->b_quant_factor = 2.0; - } - video_enc->qmin = video_qmin; - video_enc->qmax = video_qmax; - video_enc->lmin = video_lmin; - video_enc->lmax = video_lmax; - video_enc->rc_qsquish = video_qsquish; - video_enc->mb_lmin = video_mb_lmin; - video_enc->mb_lmax = video_mb_lmax; video_enc->max_qdiff = video_qdiff; - video_enc->qblur = video_qblur; - video_enc->qcompress = video_qcomp; video_enc->rc_eq = video_rc_eq; - video_enc->workaround_bugs = workaround_bugs; video_enc->thread_count = thread_count; p= video_rc_override_string; for(i=0; p; i++){ @@ -3108,30 +2868,10 @@ static void new_video_stream(AVFormatContext *oc) if(p) p++; } video_enc->rc_override_count=i; - - video_enc->rc_max_rate = video_rc_max_rate; - video_enc->rc_min_rate = video_rc_min_rate; - video_enc->rc_buffer_size = video_rc_buffer_size; - video_enc->rc_initial_buffer_occupancy = video_rc_buffer_size*3/4; - video_enc->rc_buffer_aggressivity= video_rc_buffer_aggressivity; - video_enc->rc_initial_cplx= video_rc_initial_cplx; - video_enc->i_quant_factor = video_i_qfactor; - video_enc->b_quant_factor = video_b_qfactor; - video_enc->i_quant_offset = video_i_qoffset; - video_enc->b_quant_offset = video_b_qoffset; - video_enc->intra_quant_bias = video_intra_quant_bias; - video_enc->inter_quant_bias = video_inter_quant_bias; + video_enc->rc_initial_buffer_occupancy = video_enc->rc_buffer_size*3/4; video_enc->me_threshold= me_threshold; - video_enc->mb_threshold= mb_threshold; video_enc->intra_dc_precision= intra_dc_precision - 8; video_enc->strict_std_compliance = strict; - video_enc->error_rate = error_rate; - video_enc->scenechange_threshold= sc_threshold; - video_enc->me_range = me_range; - video_enc->me_penalty_compensation= me_penalty_compensation; - video_enc->frame_skip_threshold= frame_skip_threshold; - video_enc->frame_skip_factor= frame_skip_factor; - video_enc->frame_skip_exp= frame_skip_exp; if(packet_size){ video_enc->rtp_mode= 1; @@ -3181,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; @@ -3211,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 */ @@ -3361,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) @@ -3422,15 +3157,12 @@ 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); exit(1); } - oc->packet_size= mux_packet_size; - oc->mux_rate= mux_rate; oc->preload= (int)(mux_preload*AV_TIME_BASE); oc->max_delay= (int)(mux_max_delay*AV_TIME_BASE); oc->loop_output = loop_output; @@ -3445,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 */ @@ -3503,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; @@ -3580,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; @@ -3624,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(;;){ @@ -3811,18 +3533,18 @@ static void opt_target(const char *arg) opt_frame_size(norm ? "352x240" : "352x288"); opt_frame_rate(frame_rates[norm]); - opt_gop_size(norm ? "18" : "15"); + opt_default("gop", norm ? "18" : "15"); opt_default("b", "1150000"); - video_rc_max_rate = 1150000; - video_rc_min_rate = 1150000; - video_rc_buffer_size = 40*1024*8; + opt_default("maxrate", "1150000"); + opt_default("minrate", "1150000"); + opt_default("bufsize", "327680"); // 40*1024*8; audio_bit_rate = 224000; audio_sample_rate = 44100; - mux_packet_size= 2324; - mux_rate= 2352 * 75 * 8; + opt_default("packetsize", "2324"); + opt_default("muxrate", "1411200"); // 2352 * 75 * 8; /* We have to offset the PTS, so that it is consistent with the SCR. SCR starts at 36000, but the first two packs contain only padding @@ -3838,19 +3560,19 @@ static void opt_target(const char *arg) opt_frame_size(norm ? "480x480" : "480x576"); opt_frame_rate(frame_rates[norm]); - opt_gop_size(norm ? "18" : "15"); + opt_default("gop", norm ? "18" : "15"); opt_default("b", "2040000"); - video_rc_max_rate = 2516000; - video_rc_min_rate = 0; //1145000; - video_rc_buffer_size = 224*1024*8; + opt_default("maxrate", "2516000"); + opt_default("minrate", "0"); //1145000; + opt_default("bufsize", "1835008"); //224*1024*8; opt_default("flags", "+SCAN_OFFSET"); audio_bit_rate = 224000; audio_sample_rate = 44100; - mux_packet_size= 2324; + opt_default("packetsize", "2324"); } else if(!strcmp(arg, "dvd")) { @@ -3860,15 +3582,15 @@ static void opt_target(const char *arg) opt_frame_size(norm ? "720x480" : "720x576"); opt_frame_rate(frame_rates[norm]); - opt_gop_size(norm ? "18" : "15"); + opt_default("gop", norm ? "18" : "15"); opt_default("b", "6000000"); - video_rc_max_rate = 9000000; - video_rc_min_rate = 0; //1500000; - video_rc_buffer_size = 224*1024*8; + opt_default("maxrate", "9000000"); + opt_default("minrate", "0"); //1500000; + opt_default("bufsize", "1835008"); //224*1024*8; - mux_packet_size= 2048; // from www.mpucoder.com: DVD sectors contain 2048 bytes of data, this is also the size of one pack. - mux_rate = 10080000; // from mplex project: data_rate = 1260000. mux_rate = data_rate * 8 + opt_default("packetsize", "2048"); // from www.mpucoder.com: DVD sectors contain 2048 bytes of data, this is also the size of one pack. + opt_default("muxrate", "10080000"); // from mplex project: data_rate = 1260000. mux_rate = data_rate * 8 audio_bit_rate = 448000; audio_sample_rate = 48000; @@ -3968,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]" }, @@ -4019,44 +3740,18 @@ const OptionDef options[] = { { "padleft", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_pad_left}, "set left pad band size (in pixels)", "size" }, { "padright", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_pad_right}, "set right pad band size (in pixels)", "size" }, { "padcolor", HAS_ARG | OPT_VIDEO, {(void*)opt_pad_color}, "set color of pad bands (Hex 000000 thru FFFFFF)", "color" }, - { "g", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_gop_size}, "set the group of picture size", "gop_size" }, { "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" }, - { "qmin", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qmin}, "min video quantiser scale (VBR)", "q" }, - { "qmax", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qmax}, "max video quantiser scale (VBR)", "q" }, - { "lmin", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_lmin}, "min video lagrange factor (VBR)", "lambda" }, - { "lmax", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_lmax}, "max video lagrange factor (VBR)", "lambda" }, - { "mblmin", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_mb_lmin}, "min macroblock quantiser scale (VBR)", "q" }, - { "mblmax", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_mb_lmax}, "max macroblock quantiser scale (VBR)", "q" }, - { "qdiff", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qdiff}, "max difference between the quantiser scale (VBR)", "q" }, - { "qblur", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qblur}, "video quantiser scale blur (VBR)", "blur" }, - { "qsquish", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qsquish}, "how to keep quantiser between qmin and qmax (0 = clip, 1 = use differentiable function)", "squish" }, - { "qcomp", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qcomp}, "video quantiser scale compression (VBR)", "compression" }, - { "rc_init_cplx", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_rc_initial_cplx}, "initial complexity for 1-pass encoding", "complexity" }, - { "b_qfactor", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_b_qfactor}, "qp factor between p and b frames", "factor" }, - { "i_qfactor", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_i_qfactor}, "qp factor between p and i frames", "factor" }, - { "b_qoffset", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_b_qoffset}, "qp offset between p and b frames", "offset" }, - { "i_qoffset", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_i_qoffset}, "qp offset between p and i frames", "offset" }, - { "ibias", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_ibias}, "intra quant bias", "bias" }, - { "pbias", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_pbias}, "inter quant bias", "bias" }, + { "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" }, - { "bt", HAS_ARG | OPT_VIDEO, {(void*)opt_video_bitrate_tolerance}, "set video bitrate tolerance (in kbit/s)", "tolerance" }, - { "maxrate", HAS_ARG | OPT_VIDEO, {(void*)opt_video_bitrate_max}, "set max video bitrate tolerance (in kbit/s)", "bitrate" }, - { "minrate", HAS_ARG | OPT_VIDEO, {(void*)opt_video_bitrate_min}, "set min video bitrate tolerance (in kbit/s)", "bitrate" }, - { "bufsize", HAS_ARG | OPT_VIDEO, {(void*)opt_video_buffer_size}, "set ratecontrol buffer size (in kByte)", "size" }, { "vcodec", HAS_ARG | OPT_VIDEO, {(void*)opt_video_codec}, "force video codec ('copy' to copy stream)", "codec" }, { "me", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_motion_estimation}, "set motion estimation method", "method" }, { "me_threshold", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_me_threshold}, "motion estimaton threshold", "" }, - { "mb_threshold", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_mb_threshold}, "macroblock threshold", "" }, - { "bf", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_b_frames}, "use 'frames' B frames", "frames" }, - { "preme", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_pre_me}, "pre motion estimation", "" }, - { "bug", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_workaround_bugs}, "workaround not auto detected encoder bugs", "param" }, { "ps", HAS_ARG | OPT_EXPERT, {(void*)opt_packet_size}, "set packet size in bits", "size" }, - { "error", HAS_ARG | OPT_EXPERT, {(void*)opt_error_rate}, "error rate", "rate" }, { "strict", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_strict}, "how strictly to follow the standards", "strictness" }, { "sameq", OPT_BOOL | OPT_VIDEO, {(void*)&same_quality}, "use same video quality as source (implies VBR)" }, @@ -4070,14 +3765,8 @@ const OptionDef options[] = { { "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" }, { "top", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_top_field_first}, "top=1/bottom=0/auto=-1 field first", "" }, - { "sc_threshold", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_sc_threshold}, "scene change threshold", "threshold" }, - { "me_range", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_me_range}, "limit motion vectors range (1023 for DivX player)", "range" }, { "dc", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&intra_dc_precision}, "intra_dc_precision", "precision" }, - { "mepc", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&me_penalty_compensation}, "motion estimation bitrate penalty compensation", "factor (1.0 = 256)" }, { "vtag", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_video_tag}, "force video tag/fourcc", "fourcc/tag" }, - { "skip_threshold", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&frame_skip_threshold}, "frame skip threshold", "threshold" }, - { "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" }, { "qphist", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, { (void *)&qp_hist }, "show QP histogram" }, @@ -4109,8 +3798,6 @@ const OptionDef options[] = { { "gd", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_GRAB, {(void*)opt_grab_device}, "set grab device", "device" }, /* muxer options */ - { "muxrate", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&mux_rate}, "set mux rate", "rate" }, - { "packetsize", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&mux_packet_size}, "set packet size", "size" }, { "muxdelay", OPT_FLOAT | HAS_ARG | OPT_EXPERT, {(void*)&mux_max_delay}, "set the maximum demux-decode delay", "seconds" }, { "muxpreload", OPT_FLOAT | HAS_ARG | OPT_EXPERT, {(void*)&mux_preload}, "set the initial demux-decode delay", "seconds" }, @@ -4123,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"); @@ -4141,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 @@ -4259,8 +3946,10 @@ int main(int argc, char **argv) int j; if (!(s->oformat->flags & AVFMT_NOFILE)) url_fclose(&s->pb); - for(j=0;jnb_streams;j++) + for(j=0;jnb_streams;j++) { + av_free(s->streams[j]->codec); av_free(s->streams[j]); + } av_free(s); } for(i=0;i