Skip to content
Snippets Groups Projects
ffmpeg.c 127 KiB
Newer Older
  • Learn to ignore specific revisions
  •                 audio_enc->thread_count = thread_count;
    
                    /* For audio codecs other than AC3 we limit */
                    /* the number of coded channels to stereo   */
                    if (audio_channels > 2 && codec_id != CODEC_ID_AC3) {
                        audio_enc->channels = 2;
                    } else
                        audio_enc->channels = audio_channels;
                }
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            }
    
            oc->nb_streams = nb_streams;
    
            if (!nb_streams) {
    
                fprintf(stderr, "No audio or video streams available\n");
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                exit(1);
            }
    
    
                pstrcpy(oc->title, sizeof(oc->title), str_title);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            if (str_author)
    
                pstrcpy(oc->author, sizeof(oc->author), str_author);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            if (str_copyright)
    
                pstrcpy(oc->copyright, sizeof(oc->copyright), str_copyright);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            if (str_comment)
    
                pstrcpy(oc->comment, sizeof(oc->comment), str_comment);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        }
    
    
        output_files[nb_output_files++] = oc;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
        strcpy(oc->filename, filename);
    
    
        /* check filename in case of an image number is expected */
    
        if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
            if (filename_number_test(oc->filename) < 0) {
                print_error(oc->filename, AVERROR_NUMEXPECTED);
    
        if (!(oc->oformat->flags & AVFMT_NOFILE)) {
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            /* test if it already exists to avoid loosing precious files */
            if (!file_overwrite && 
                (strchr(filename, ':') == NULL ||
                 strstart(filename, "file:", NULL))) {
                if (url_exist(filename)) {
                    int c;
                    
    
                    if ( !using_stdin ) {
                        fprintf(stderr,"File '%s' already exists. Overwrite ? [y/N] ", filename);
                        fflush(stderr);
                        c = getchar();
                        if (toupper(c) != 'Y') {
                            fprintf(stderr, "Not overwriting - exiting\n");
                            exit(1);
                        }
    				}
    				else {
                        fprintf(stderr,"File '%s' already exists. Exiting.\n", filename);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                        exit(1);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                }
            }
            
            /* open the file */
            if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0) {
                fprintf(stderr, "Could not open '%s'\n", filename);
                exit(1);
            }
        }
    
    
        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);
        }
    
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        /* reset some options */
    
        file_oformat = NULL;
        file_iformat = NULL;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        audio_disable = 0;
        video_disable = 0;
        audio_codec_id = CODEC_ID_NONE;
        video_codec_id = CODEC_ID_NONE;
    
        audio_stream_copy = 0;
        video_stream_copy = 0;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    }
    
    
    /* prepare dummy protocols for grab */
    
    static void prepare_grab(void)
    
    {
        int has_video, has_audio, i, j;
        AVFormatContext *oc;
        AVFormatContext *ic;
    
        /* see if audio/video inputs are needed */
        has_video = 0;
        has_audio = 0;
        memset(ap, 0, sizeof(*ap));
    
        for(j=0;j<nb_output_files;j++) {
            oc = output_files[j];
            for(i=0;i<oc->nb_streams;i++) {
                AVCodecContext *enc = &oc->streams[i]->codec;
                switch(enc->codec_type) {
                case CODEC_TYPE_AUDIO:
                    if (enc->sample_rate > ap->sample_rate)
                        ap->sample_rate = enc->sample_rate;
                    if (enc->channels > ap->channels)
                        ap->channels = enc->channels;
                    has_audio = 1;
                    break;
                case CODEC_TYPE_VIDEO:
    
                    if (enc->width > vp->width)
                        vp->width = enc->width;
                    if (enc->height > vp->height)
                        vp->height = enc->height;
    
                    
                    assert(enc->frame_rate_base == DEFAULT_FRAME_RATE_BASE);
                    if (enc->frame_rate > vp->frame_rate){
                        vp->frame_rate      = enc->frame_rate;
                        vp->frame_rate_base = enc->frame_rate_base;
                    }
    
                }
            }
        }
        
        if (has_video == 0 && has_audio == 0) {
            fprintf(stderr, "Output file must have at least one audio or video stream\n");
            exit(1);
        }
        
        if (has_video) {
    
            fmt1 = av_find_input_format(video_grab_format);
    
    	vp->standard = video_standard;
    
            if (av_open_input_file(&ic, "", fmt1, 0, vp) < 0) {
    
                fprintf(stderr, "Could not find video grab device\n");
    
            /* If not enough info to get the stream parameters, we decode the
               first frames to get it. */
    	if ((ic->ctx_flags & AVFMTCTX_NOHEADER) && av_find_stream_info(ic) < 0) {
                fprintf(stderr, "Could not find video grab parameters\n");
                exit(1);
            }
    
            /* by now video grab has one stream */
    
            ic->streams[0]->r_frame_rate      = vp->frame_rate;
            ic->streams[0]->r_frame_rate_base = vp->frame_rate_base;
    
    
            if (verbose >= 0)
                dump_format(ic, nb_input_files, "", 0);
    
    
        if (has_audio && audio_grab_format) {
    
            fmt1 = av_find_input_format(audio_grab_format);
    
            if (av_open_input_file(&ic, "", fmt1, 0, ap) < 0) {
    
                fprintf(stderr, "Could not find audio grab device\n");
    
    
            if (verbose >= 0)
                dump_format(ic, nb_input_files, "", 0);
    
    
    /* same option as mencoder */
    
    static void opt_pass(const char *pass_str)
    
    {
        int pass;
        pass = atoi(pass_str);
        if (pass != 1 && pass != 2) {
            fprintf(stderr, "pass number can be only 1 or 2\n");
            exit(1);
        }
        do_pass = pass;
    }
    
    #if defined(CONFIG_WIN32) || defined(CONFIG_OS2)
    
    static int64_t getutime(void)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    #else
    
    static int64_t getutime(void)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
    
        struct rusage rusage;
    
        getrusage(RUSAGE_SELF, &rusage);
        return (rusage.ru_utime.tv_sec * 1000000LL) + rusage.ru_utime.tv_usec;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    }
    #endif
    
    static void opt_bitexact(void)
    
        /* disable generate of real time pts in ffm (need to be supressed anyway) */
        ffm_nopts = 1;
    }
    
    
    static void show_formats(void)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
    
        AVInputFormat *ifmt;
        AVOutputFormat *ofmt;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        URLProtocol *up;
    
        AVCodec *p, *p2;
        const char **pp, *last_name;
    
        printf("File formats:\n");
        last_name= "000";
        for(;;){
            int decode=0;
            int encode=0;
            const char *name=NULL;
    
            for(ofmt = first_oformat; ofmt != NULL; ofmt = ofmt->next) {
                if((name == NULL || strcmp(ofmt->name, name)<0) &&
                    strcmp(ofmt->name, last_name)>0){
                    name= ofmt->name;
                    encode=1;
                }
            }
            for(ifmt = first_iformat; ifmt != NULL; ifmt = ifmt->next) {
                if((name == NULL || strcmp(ifmt->name, name)<0) &&
                    strcmp(ifmt->name, last_name)>0){
                    name= ifmt->name;
                    encode=0;
                }
                if(name && strcmp(ifmt->name, name)==0)
                    decode=1;
            }
            if(name==NULL)
                break;
            last_name= name;
            
            printf(
                " %s%s %s\n", 
                decode ? "D":" ", 
                encode ? "E":" ", 
                name);
    
        printf("Image formats:\n");
    
        for(image_fmt = first_image_format; image_fmt != NULL; 
            image_fmt = image_fmt->next) {
    
            printf(
                " %s%s %s\n",
                image_fmt->img_read  ? "D":" ",
                image_fmt->img_write ? "E":" ",
                image_fmt->name);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        printf("Codecs:\n");
    
        last_name= "000";
        for(;;){
            int decode=0;
            int encode=0;
            int cap=0;
    
            p2=NULL;
            for(p = first_avcodec; p != NULL; p = p->next) {
                if((p2==NULL || strcmp(p->name, p2->name)<0) &&
                    strcmp(p->name, last_name)>0){
                    p2= p;
                    decode= encode= cap=0;
                }
                if(p2 && strcmp(p->name, p2->name)==0){
                    if(p->decode) decode=1;
                    if(p->encode) encode=1;
                    cap |= p->capabilities;
                }
            }
            if(p2==NULL)
                break;
            last_name= p2->name;
            
            printf(
                " %s%s%s%s%s%s %s", 
                decode ? "D": (/*p2->decoder ? "d":*/" "), 
                encode ? "E":" ", 
                p2->type == CODEC_TYPE_AUDIO ? "A":"V",
                cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S":" ",
                cap & CODEC_CAP_DR1 ? "D":" ",
                cap & CODEC_CAP_TRUNCATED ? "T":" ",
                p2->name);
           /* if(p2->decoder && decode==0)
                printf(" use %s for decoding", p2->decoder->name);*/
            printf("\n");
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        }
        printf("\n");
    
    
        printf("Supported file protocols:\n");
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        for(up = first_protocol; up != NULL; up = up->next)
            printf(" %s:", up->name);
        printf("\n");
        
    
        printf("Frame size, frame rate abbreviations:\n ntsc pal qntsc qpal sntsc spal film ntsc-film sqcif qcif cif 4cif\n");
        printf("Motion estimation methods:\n");
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        pp = motion_str;
        while (*pp) {
            printf(" %s", *pp);
    
            if ((pp - motion_str + 1) == ME_ZERO) 
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                printf("(fastest)");
    
            else if ((pp - motion_str + 1) == ME_FULL) 
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                printf("(slowest)");
    
            else if ((pp - motion_str + 1) == ME_EPZS) 
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                printf("(default)");
            pp++;
        }
    
        printf("\n\n");
        printf(
    "Note, the names of encoders and decoders dont always match, so there are\n"
    "several cases where the above table shows encoder only or decoder only entries\n"
    "even though both encoding and decoding are supported for example, the h263\n"
    "decoder corresponds to the h263 and h263p encoders, for file formats its even\n"
    "worse\n");
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        exit(1);
    }
    
    
    void parse_matrix_coeffs(uint16_t *dest, const char *str)
    {
        int i;
        const char *p = str;
        for(i = 0;; i++) {
            dest[i] = atoi(p);
            if(i == 63)
                break;
            p = strchr(p, ',');
            if(!p) {
                fprintf(stderr, "Syntax error in matrix \"%s\" at coeff %d\n", str, i);
                exit(1);
            }
            p++;
        }
    }
    
    void opt_inter_matrix(const char *arg)
    {
        inter_matrix = av_mallocz(sizeof(uint16_t) * 64);
        parse_matrix_coeffs(inter_matrix, arg);
    }
    
    void opt_intra_matrix(const char *arg)
    {
        intra_matrix = av_mallocz(sizeof(uint16_t) * 64);
        parse_matrix_coeffs(intra_matrix, arg);
    }
    
    
    static void opt_target(const char *arg)
    {
        int norm = -1;
    
        if(!strncmp(arg, "pal-", 4)) {
            norm = 0;
            arg += 4;
        } else if(!strncmp(arg, "ntsc-", 5)) {
            norm = 1;
            arg += 5;
        } else {
            int fr;
            /* Calculate FR via float to avoid int overflow */
            fr = (int)(frame_rate * 1000.0 / frame_rate_base);
            if(fr == 25000) {
                norm = 0;
            } else if((fr == 29970) || (fr == 23976)) {
                norm = 1;
            } else {
                /* Try to determine PAL/NTSC by peeking in the input files */
                if(nb_input_files) {
                    int i, j;
                    for(j = 0; j < nb_input_files; j++) {
                        for(i = 0; i < input_files[j]->nb_streams; i++) {
                            AVCodecContext *c = &input_files[j]->streams[i]->codec;
                            if(c->codec_type != CODEC_TYPE_VIDEO)
                                continue;
                            fr = c->frame_rate * 1000 / c->frame_rate_base;
                            if(fr == 25000) {
                                norm = 0;
                                break;
                            } else if((fr == 29970) || (fr == 23976)) {
                                norm = 1;
                                break;
                            }
                        }
                        if(norm >= 0)
                            break;
                    }
                }
            }
            if(verbose && norm >= 0)
                printf("Assuming %s for target.\n", norm ? "NTSC" : "PAL");
        }
    
        if(norm < 0) {
            fprintf(stderr, "Could not determine norm (PAL/NTSC) for target.\n");
            fprintf(stderr, "Please prefix target with \"pal-\" or \"ntsc-\",\n");
            fprintf(stderr, "or set a framerate with \"-r xxx\".\n");
            exit(1);
        }
    
        if(!strcmp(arg, "vcd")) {
    
            opt_video_codec("mpeg1video");
            opt_audio_codec("mp2");
            opt_format("vcd");
    
            opt_frame_size(norm ? "352x240" : "352x288");
    
            video_bit_rate = 1150000;
            video_rc_max_rate = 1150000;
            video_rc_min_rate = 1150000;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
            video_rc_buffer_size = 40*1024*8;
    
    
            audio_bit_rate = 224000;
            audio_sample_rate = 44100;
    
        } else if(!strcmp(arg, "svcd")) {
    
            opt_video_codec("mpeg2video");
            opt_audio_codec("mp2");
    
    
            opt_frame_size(norm ? "480x480" : "480x576");
            opt_gop_size(norm ? "18" : "15");
    
            video_bit_rate = 2040000;
            video_rc_max_rate = 2516000;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
            video_rc_buffer_size = 224*1024*8;
    
            use_scan_offset = 1;
    
    
            audio_bit_rate = 224000;
            audio_sample_rate = 44100;
    
        } else if(!strcmp(arg, "dvd")) {
    
            opt_video_codec("mpeg2video");
            opt_audio_codec("ac3");
            opt_format("vob");
    
            opt_frame_size(norm ? "720x480" : "720x576");
            opt_gop_size(norm ? "18" : "15");
    
            video_bit_rate = 6000000;
            video_rc_max_rate = 9000000;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
            video_rc_buffer_size = 224*1024*8;
    
    
            audio_bit_rate = 448000;
            audio_sample_rate = 48000;
    
        } else {
            fprintf(stderr, "Unknown target: %s\n", arg);
            exit(1);
        }
    }
    
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    static void show_version(void)
    {
        printf("ffmpeg      " FFMPEG_VERSION "\n"
               "libavcodec  %d\n"
               "libavformat %d\n", 
               avcodec_build(), LIBAVFORMAT_BUILD);
        exit(1);
    }
    
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    const OptionDef options[] = {
    
        /* main options */
        { "L", 0, {(void*)show_license}, "show license" },
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        { "h", 0, {(void*)show_help}, "show help" },
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        { "version", 0, {(void*)show_version}, "show version" },
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        { "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" },
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        { "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" },
        { "t", HAS_ARG, {(void*)opt_recording_time}, "set the recording time", "duration" },
    
        { "ss", HAS_ARG, {(void*)opt_start_time}, "set the start time offset", "time_off" },
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        { "title", HAS_ARG | OPT_STRING, {(void*)&str_title}, "set the title", "string" },
    
        { "timestamp", HAS_ARG, {(void*)&opt_rec_timestamp}, "set the timestamp", "time" },
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        { "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" },
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        { "debug", HAS_ARG | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" },
    
        { "vismv", HAS_ARG | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" },
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        { "benchmark", OPT_BOOL | OPT_EXPERT, {(void*)&do_benchmark}, 
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
          "add timings for benchmarking" },
    
        { "dump", OPT_BOOL | OPT_EXPERT, {(void*)&do_pkt_dump}, 
    
          "dump each input packet" },
    
        { "hex", OPT_BOOL | OPT_EXPERT, {(void*)&do_hex_dump}, 
          "when dumping packets, also dump the payload" },
    
        { "bitexact", OPT_EXPERT, {(void*)opt_bitexact}, "only use bit exact algorithms (for codec testing)" }, 
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        { "re", OPT_BOOL | OPT_EXPERT, {(void*)&rate_emu}, "read input at native frame rate", "" },
        { "loop", OPT_BOOL | OPT_EXPERT, {(void*)&loop_input}, "loop (current only works with images)" },
    
        { "v", HAS_ARG, {(void*)opt_verbose}, "control amount of logging", "verbose" },
    
        { "target", HAS_ARG, {(void*)opt_target}, "specify target file type (\"vcd\", \"svcd\" or \"dvd\")", "type" },
    
        { "threads", HAS_ARG | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
    
        { "sync", HAS_ARG | OPT_EXPERT, {(void*)opt_sync_method}, "sync method", "" },
    
    
        /* video options */
        { "b", HAS_ARG | OPT_VIDEO, {(void*)opt_video_bitrate}, "set video bitrate (in kbit/s)", "bitrate" },
        { "r", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_rate}, "set frame rate (Hz value, fraction or abbreviation)", "rate" },
        { "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
        { "aspect", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_aspect_ratio}, "set aspect ratio (4:3, 16:9 or 1.3333, 1.7777)", "aspect" },
        { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_frame_pix_fmt}, "set pixel format", "format" },
        { "croptop", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_crop_top}, "set top crop band size (in pixels)", "size" },
        { "cropbottom", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_crop_bottom}, "set bottom crop band size (in pixels)", "size" },
        { "cropleft", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_crop_left}, "set left crop band size (in pixels)", "size" },
        { "cropright", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_crop_right}, "set right crop band size (in pixels)", "size" },
    
        { "padtop", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_pad_top}, "set top pad band size (in pixels)", "size" },
        { "padbottom", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_pad_bottom}, "set bottom pad band size (in pixels)", "size" },
        { "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" },
        { "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" },
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        { "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" },
    
        { "mbqmin", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_mb_qmin}, "min macroblock quantiser scale (VBR)", "q" },
        { "mbqmax", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_mb_qmax}, "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" },
        { "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" },
    
    //    { "b_strategy", HAS_ARG | OPT_EXPERT, {(void*)opt_b_strategy}, "dynamic b frame selection strategy", "strategy" },
        { "rc_eq", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_video_rc_eq}, "set rate control equation", "equation" },
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        { "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 buffere 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" },
        { "dct_algo", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_dct_algo}, "set dct algo",  "algo" },
        { "idct_algo", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_idct_algo}, "set idct algo",  "algo" },
    
        { "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",  "" },
    
        { "er", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_error_resilience}, "set error resilience",  "n" },
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        { "ec", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_error_concealment}, "set error concealment",  "bit_mask" },
    
        { "bf", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_b_frames}, "use 'frames' B frames", "frames" },
    
        { "hq", OPT_BOOL, {(void*)&mb_decision}, "activate high quality settings" },
        { "mbd", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_mb_decision}, "macroblock decision", "mode" },
    
        { "mbcmp", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_mb_cmp}, "macroblock compare function", "cmp function" },
    
        { "ildctcmp", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_ildct_cmp}, "ildct compare function", "cmp function" },
    
        { "subcmp", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_sub_cmp}, "subpel compare function", "cmp function" },
        { "cmp", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_cmp}, "fullpel compare function", "cmp function" },
    
        { "precmp", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_pre_cmp}, "pre motion estimation compare function", "cmp function" },
        { "preme", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_pre_me}, "pre motion estimation", "" },
        { "lumi_mask", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_lumi_mask}, "luminance masking", "" },
        { "dark_mask", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_dark_mask}, "darkness masking", "" },
        { "scplx_mask", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_scplx_mask}, "spatial complexity masking", "" },
        { "tcplx_mask", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_tcplx_mask}, "teporal complexity masking", "" },
        { "p_mask", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_p_mask}, "inter masking", "" },
    
        { "4mv", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&use_4mv}, "use four motion vector by macroblock (MPEG4)" },
    
        { "obmc", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&use_obmc}, "use overlapped block motion compensation (h263+)" },
    
        { "lf", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&use_loop}, "use loop filter (h263+)" },
    
        { "part", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&use_part}, "use data partitioning (MPEG4)" },
    
        { "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)" },
        { "pass", HAS_ARG | OPT_VIDEO, {(void*)&opt_pass}, "select the pass number (1 or 2)", "n" },
        { "passlogfile", HAS_ARG | OPT_STRING | OPT_VIDEO, {(void*)&pass_logfilename}, "select two pass log file name", "file" },
        { "deinterlace", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&do_deinterlace}, 
          "deinterlace pictures" },
    
        { "ildct", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&do_interlace_dct}, 
          "force interlaced dct support in encoder (MPEG2/MPEG4)" },
        { "ilme", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&do_interlace_me}, 
    
          "force interlaced me support in encoder (MPEG2/MPEG4)" },
    
        { "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" }, 
        { "vhook", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)add_frame_hooker}, "insert video processing module", "module" },
        { "aic", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&use_aic}, "enable Advanced intra coding (h263+)" },
    
        { "aiv", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&use_aiv}, "enable Alternative inter vlc (h263+)" },
    
        { "umv", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&use_umv}, "enable Unlimited Motion Vector (h263+)" },
    
        { "ssm", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&use_ss}, "enable Slice Structured mode (h263+)" },
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        { "alt", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&use_alt_scan}, "enable alternate scantable (MPEG2/MPEG4)" },
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        { "qprd", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&use_qprd}, "" },
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        { "cbp", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&use_cbprd}, "" },
    
        { "trell", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&use_trell}, "enable trellis quantization" },
    
        { "cgop", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&closed_gop}, "closed gop" },
    
        { "scan_offset", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&use_scan_offset}, "enable SVCD Scan Offset placeholder" },
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        { "qpel", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&use_qpel}, "enable 1/4-pel" },
    
        { "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", "" },
        { "nr", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_noise_reduction}, "noise reduction", "" },
    
        { "qns", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qns}, "quantization noise shaping", "" },
    
        { "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" },
    
        { "coder", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&coder}, "coder type", "" },
        { "context", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&context}, "context model", "" },
        { "pred", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&predictor}, "prediction method", "" },
    
    
        /* audio options */
        { "ab", HAS_ARG | OPT_AUDIO, {(void*)opt_audio_bitrate}, "set audio bitrate (in kbit/s)", "bitrate", },
        { "ar", HAS_ARG | OPT_AUDIO, {(void*)opt_audio_rate}, "set audio sampling rate (in Hz)", "rate" },
        { "ac", HAS_ARG | OPT_AUDIO, {(void*)opt_audio_channels}, "set number of audio channels", "channels" },
        { "an", OPT_BOOL | OPT_AUDIO, {(void*)&audio_disable}, "disable audio" },
        { "acodec", HAS_ARG | OPT_AUDIO, {(void*)opt_audio_codec}, "force audio codec ('copy' to copy stream)", "codec" },
    
        /* grab options */
        { "vd", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_GRAB, {(void*)opt_video_device}, "set video grab device", "device" },
        { "vc", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_GRAB, {(void*)opt_video_channel}, "set video grab channel (DV1394 only)", "channel" },
        { "tvstd", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_GRAB, {(void*)opt_video_standard}, "set television standard (NTSC, PAL (SECAM))", "standard" },
        { "dv1394", OPT_EXPERT | OPT_GRAB, {(void*)opt_dv1394}, "set DV1394 grab", "" },
        { "ad", HAS_ARG | OPT_EXPERT | OPT_AUDIO | OPT_GRAB, {(void*)opt_audio_device}, "set audio device", "device" },
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        { NULL, },
    };
    
    
    static void show_banner(void)
    {
        printf("ffmpeg version " FFMPEG_VERSION ", Copyright (c) 2000-2003 Fabrice Bellard\n");
    }
    
    static void show_license(void)
    {
        show_banner();
    
        "This program 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"
        "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"
        "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n"
    
        "This library 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"
        "\n"
        "This library 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"
        "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n"
        );
    
        exit(1);
    }
    
    static void show_help(void)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        printf("usage: ffmpeg [[options] -i input_file]... {[options] outfile}...\n"
               "Hyper fast Audio and Video encoder\n");
        printf("\n");
    
        show_help_options(options, "Main options:\n",
                          OPT_EXPERT | OPT_AUDIO | OPT_VIDEO, 0);
        show_help_options(options, "\nVideo options:\n",
                          OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_GRAB, 
                          OPT_VIDEO);
        show_help_options(options, "\nAdvanced Video options:\n",
                          OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_GRAB, 
                          OPT_VIDEO | OPT_EXPERT);
        show_help_options(options, "\nAudio options:\n",
                          OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_GRAB, 
                          OPT_AUDIO);
        show_help_options(options, "\nAdvanced Audio options:\n",
                          OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_GRAB, 
                          OPT_AUDIO | OPT_EXPERT);
        show_help_options(options, "\nAudio/Video grab options:\n",
                          OPT_GRAB, 
                          OPT_GRAB);
        show_help_options(options, "\nAdvanced options:\n",
                          OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_GRAB, 
                          OPT_EXPERT);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        exit(1);
    }
    
    void parse_arg_file(const char *filename)
    {
        opt_output_file(filename);
    }
    
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    int main(int argc, char **argv)
    {
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        int i;
    
        int64_t ti;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
        if (argc <= 1)
            show_help();
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        parse_options(argc, argv, options);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        /* file converter / grab */
        if (nb_output_files <= 0) {
            fprintf(stderr, "Must supply at least one output file\n");
            exit(1);
        }
        
        if (nb_input_files == 0) {
            prepare_grab();
    
        }
    
        ti = getutime();
        av_encode(output_files, nb_output_files, input_files, nb_input_files, 
                  stream_maps, nb_stream_maps);
        ti = getutime() - ti;
        if (do_benchmark) {
            printf("bench: utime=%0.3fs\n", ti / 1000000.0);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        }
    
        /* close files */
        for(i=0;i<nb_output_files;i++) {
    
            /* maybe av_close_output_file ??? */
            AVFormatContext *s = output_files[i];
    	int j;
            if (!(s->oformat->flags & AVFMT_NOFILE))
    	    url_fclose(&s->pb);
    	for(j=0;j<s->nb_streams;j++)
    	    av_free(s->streams[j]);
            av_free(s);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        }
    
        for(i=0;i<nb_input_files;i++)
            av_close_input_file(input_files[i]);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
        if(intra_matrix)
            av_free(intra_matrix);
        if(inter_matrix)
            av_free(inter_matrix);
    
        extern void powerpc_display_perf_report(void);
        powerpc_display_perf_report();
    
    #endif /* POWERPC_PERFORMANCE_REPORT */
    
    #ifndef CONFIG_WIN32
        if (received_sigterm) {
            fprintf(stderr,
                "Received signal %d: terminating.\n",
                (int) received_sigterm);
            exit (255);
        }
    #endif
        exit(0); /* not all OS-es handle main() return value */
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        return 0;
    }