Skip to content
Snippets Groups Projects
ffmpeg.c 134 KiB
Newer Older
  • Learn to ignore specific revisions
  •         file_oformat = guess_format(NULL, filename, NULL);
            if (!file_oformat) {
                fprintf(stderr, "Unable for find a suitable output format for '%s'\n",
                        filename);
                exit(1);
            }
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        }
    
        pstrcpy(oc->filename, sizeof(oc->filename), filename);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
        if (!strcmp(file_oformat->name, "ffm") &&
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            strstart(filename, "http:", NULL)) {
            /* special case for files sent to ffserver: we get the stream
               parameters from ffserver */
            if (read_ffserver_streams(oc, filename) < 0) {
                fprintf(stderr, "Could not read stream parameters from '%s'\n", filename);
                exit(1);
            }
        } else {
    
            use_video = file_oformat->video_codec != CODEC_ID_NONE || video_stream_copy || video_codec_id != CODEC_ID_NONE;
            use_audio = file_oformat->audio_codec != CODEC_ID_NONE || audio_stream_copy || audio_codec_id != CODEC_ID_NONE;
    
            /* disable if no corresponding type found and at least one
               input file */
            if (nb_input_files > 0) {
                check_audio_video_inputs(&input_has_video, &input_has_audio);
                if (!input_has_video)
                    use_video = 0;
                if (!input_has_audio)
                    use_audio = 0;
            }
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            if (audio_disable) {
                use_audio = 0;
            }
            if (video_disable) {
                use_video = 0;
            }
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            if (use_video) {
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            }
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            if (use_audio) {
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            }
    
    
                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);
    
            if (str_album)
                pstrcpy(oc->album, sizeof(oc->album), str_album);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        }
    
    
        output_files[nb_output_files++] = oc;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
        /* check filename in case of an image number is expected */
    
        if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
    
                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 &&
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                (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);
                        }
    
                        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
                }
            }
    
    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));
        if (av_set_parameters(oc, ap) < 0) {
            fprintf(stderr, "%s: Invalid encoding parameters\n",
                    oc->filename);
            exit(1);
        }
    
    
        oc->preload= (int)(mux_preload*AV_TIME_BASE);
        oc->max_delay= (int)(mux_max_delay*AV_TIME_BASE);
    
        oc->loop_output = loop_output;
    
        for(i=0; i<opt_name_count; i++){
    
            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);
        }
    
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        /* reset some options */
    
        file_oformat = NULL;
        file_iformat = NULL;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    }
    
    
    /* 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(__MINGW32__) || 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
    
    #if defined(CONFIG_FFM_DEMUXER) || defined(CONFIG_FFM_MUXER)
    
    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;
    
                " %s%s %-15s %s\n",
                decode ? "D":" ",
                encode ? "E":" ",
    
    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;
    
            switch(p2->type) {
            case CODEC_TYPE_VIDEO:
                type_str = "V";
                break;
            case CODEC_TYPE_AUDIO:
                type_str = "A";
                break;
            case CODEC_TYPE_SUBTITLE:
                type_str = "S";
                break;
            default:
                type_str = "?";
                break;
            }
    
                " %s%s%s%s%s%s %s",
                decode ? "D": (/*p2->decoder ? "d":*/" "),
                encode ? "E":" ",
    
                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);
    }
    
    
    static 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++;
        }
    }
    
    
    static void opt_inter_matrix(const char *arg)
    
    {
        inter_matrix = av_mallocz(sizeof(uint16_t) * 64);
        parse_matrix_coeffs(inter_matrix, arg);
    }
    
    
    static 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;
    
        static const char *const frame_rates[] = {"25", "30000/1001", "24000/1001"};
    
    
        if(!strncmp(arg, "pal-", 4)) {
            norm = 0;
            arg += 4;
        } else if(!strncmp(arg, "ntsc-", 5)) {
            norm = 1;
            arg += 5;
    
        } else if(!strncmp(arg, "film-", 5)) {
            norm = 2;
            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->time_base.den * 1000 / c->time_base.num;
    
                            if(fr == 25000) {
                                norm = 0;
                                break;
                            } else if((fr == 29970) || (fr == 23976)) {
                                norm = 1;
                                break;
                            }
                        }
                        if(norm >= 0)
                            break;
                    }
                }
            }
            if(verbose && norm >= 0)
    
                fprintf(stderr, "Assuming %s for target.\n", norm ? "NTSC" : "PAL");
    
            fprintf(stderr, "Could not determine norm (PAL/NTSC/NTSC-Film) for target.\n");
            fprintf(stderr, "Please prefix target with \"pal-\", \"ntsc-\" or \"film-\",\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");
    
            opt_frame_rate(frame_rates[norm]);
    
            opt_default("gop", norm ? "18" : "15");
    
            opt_default("maxrate", "1150000");
            opt_default("minrate", "1150000");
    
            opt_default("bufsize", "327680"); // 40*1024*8;
    
            audio_channels = 2;
    
            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
               and the first pack from the other stream, respectively, may also have
               been written before.
               So the real data starts at SCR 36000+3*1200. */
            mux_preload= (36000+3*1200) / 90000.0; //0.44
    
        } else if(!strcmp(arg, "svcd")) {
    
            opt_video_codec("mpeg2video");
            opt_audio_codec("mp2");
    
    
            opt_frame_size(norm ? "480x480" : "480x576");
    
            opt_frame_rate(frame_rates[norm]);
    
            opt_default("gop", norm ? "18" : "15");
    
            opt_default("maxrate", "2516000");
            opt_default("minrate", "0"); //1145000;
    
            opt_default("bufsize", "1835008"); //224*1024*8;
    
            opt_default("flags", "+SCAN_OFFSET");
    
    
            opt_default("packetsize", "2324");
    
        } else if(!strcmp(arg, "dvd")) {
    
            opt_video_codec("mpeg2video");
            opt_audio_codec("ac3");
    
    
            opt_frame_size(norm ? "720x480" : "720x576");
    
            opt_frame_rate(frame_rates[norm]);
    
            opt_default("gop", norm ? "18" : "15");
    
            opt_default("maxrate", "9000000");
            opt_default("minrate", "0"); //1500000;
    
            opt_default("bufsize", "1835008"); //224*1024*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
    
    
            opt_format("dv");
    
            opt_frame_size(norm ? "720x480" : "720x576");
    
            opt_frame_pix_fmt(!strncmp(arg, "dv50", 4) ? "yuv422p" :
                                                 (norm ? "yuv411p" : "yuv420p"));
    
            opt_frame_rate(frame_rates[norm]);
    
            audio_sample_rate = 48000;
            audio_channels = 2;
    
    
        } else {
            fprintf(stderr, "Unknown target: %s\n", arg);
            exit(1);
        }
    }
    
    
    static void opt_vstats_file (const char *arg)
    {
        av_free (vstats_filename);
        vstats_filename=av_strdup (arg);
    }
    
    static void opt_vstats (void)
    {
        char filename[40];
        time_t today2 = time(NULL);
        struct tm *today = localtime(&today2);
    
        snprintf(filename, sizeof(filename), "vstats_%02d%02d%02d.log", today->tm_hour, today->tm_min,
                 today->tm_sec);
        opt_vstats_file(filename);
    }
    
    
    static void opt_video_bsf(const char *arg)
    {
        AVBitStreamFilterContext *bsfc= av_bitstream_filter_init(arg); //FIXME split name and args for filter at '='
        AVBitStreamFilterContext **bsfp;
    
        if(!bsfc){
    
    Alex Beregszaszi's avatar
    Alex Beregszaszi committed
            fprintf(stderr, "Unknown bitstream filter %s\n", arg);
    
            exit(1);
        }
    
        bsfp= &video_bitstream_filters;
        while(*bsfp)
            bsfp= &(*bsfp)->next;
    
        *bsfp= bsfc;
    }
    
    //FIXME avoid audio - video code duplication
    static void opt_audio_bsf(const char *arg)
    {
        AVBitStreamFilterContext *bsfc= av_bitstream_filter_init(arg); //FIXME split name and args for filter at '='
        AVBitStreamFilterContext **bsfp;
    
        if(!bsfc){
    
    Alex Beregszaszi's avatar
    Alex Beregszaszi committed
            fprintf(stderr, "Unknown bitstream filter %s\n", arg);
    
            exit(1);
        }
    
        bsfp= &audio_bitstream_filters;
        while(*bsfp)
            bsfp= &(*bsfp)->next;
    
        *bsfp= bsfc;
    }
    
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    static void show_version(void)
    {
    
        /* TODO: add function interface to avutil and avformat */
    
               "libavutil   %d\n"
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
               "libavcodec  %d\n"
    
               "libavformat %d\n",
    
               LIBAVUTIL_BUILD, avcodec_build(), LIBAVFORMAT_BUILD);
    
    static int opt_default(const char *opt, const char *arg){
    
        const AVOption *o= NULL;
        int opt_types[]={AV_OPT_FLAG_VIDEO_PARAM, AV_OPT_FLAG_AUDIO_PARAM, 0, AV_OPT_FLAG_SUBTITLE_PARAM, 0};
    
        for(type=0; type<CODEC_TYPE_NB; type++){
            const AVOption *o2 = av_find_opt(avctx_opts[0], opt, NULL, opt_types[type], opt_types[type]);
            if(o2)
                o = av_set_string(avctx_opts[type], opt, arg);
        }
    
        if(!o)
            o = av_set_string(avformat_opts, opt, arg);
    
            o = av_set_string(sws_opts, opt, arg);
    
        if(!o){
            if(opt[0] == 'a')
                o = av_set_string(avctx_opts[CODEC_TYPE_AUDIO], opt+1, arg);
            else if(opt[0] == 'v')
                o = av_set_string(avctx_opts[CODEC_TYPE_VIDEO], opt+1, arg);
            else if(opt[0] == 's')
                o = av_set_string(avctx_opts[CODEC_TYPE_SUBTITLE], opt+1, arg);
        }
    
        if(!o)
            return -1;
    
    //    av_log(NULL, AV_LOG_ERROR, "%s:%s: %f 0x%0X\n", opt, arg, av_get_double(avctx_opts, opt, NULL), (int)av_get_int(avctx_opts, opt, NULL));
    
    
        //FIXME we should always use avctx_opts, ... for storing options so there wont be any need to keep track of whats set over this
        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[0]->flags & CODEC_FLAG_BITEXACT)
    
    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" },
        { "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]" },
    
        { "map_meta_data", HAS_ARG | OPT_EXPERT, {(void*)opt_map_meta_data}, "set meta data information of outfile from infile", "outfile:infile" },
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        { "t", HAS_ARG, {(void*)opt_recording_time}, "set the recording time", "duration" },
    
        { "fs", HAS_ARG | OPT_INT64, {(void*)&limit_filesize}, "set the limit file size in bytes", "limit_size" }, //
    
        { "ss", HAS_ARG, {(void*)opt_start_time}, "set the start time offset", "time_off" },
    
        { "itsoffset", HAS_ARG, {(void*)opt_input_ts_offset}, "set the input ts offset", "time_off" },
    
    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" },
    
        { "album", HAS_ARG | OPT_STRING, {(void*)&str_album}, "set the album", "string" },
    
        { "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" },
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        { "re", OPT_BOOL | OPT_EXPERT, {(void*)&rate_emu}, "read input at native frame rate", "" },
    
        { "loop_input", OPT_BOOL | OPT_EXPERT, {(void*)&loop_input}, "loop (current only works with images)" },
    
        { "loop_output", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&loop_output}, "number of times to loop output in formats that support looping (0 loops forever)", "" },
    
        { "v", HAS_ARG, {(void*)opt_verbose}, "control amount of logging", "verbose" },
    
        { "target", HAS_ARG, {(void*)opt_target}, "specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" },
    
        { "threads", HAS_ARG | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
    
        { "vsync", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&video_sync_method}, "video sync method", "" },
        { "async", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&audio_sync_method}, "audio sync method", "" },
    
        { "vglobal", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&video_global_header}, "video global header storage type", "" },
    
        { "copyts", OPT_BOOL | OPT_EXPERT, {(void*)&copy_ts}, "copy timestamps" },
    
        { "shortest", OPT_BOOL | OPT_EXPERT, {(void*)&opt_shortest}, "finish encoding within shortest input" }, //
    
        { "dts_delta_threshold", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&dts_delta_threshold}, "timestamp discontinuity delta threshold", "" },
    
        { "vframes", OPT_INT | HAS_ARG | OPT_VIDEO, {(void*)&max_frames[CODEC_TYPE_VIDEO]}, "set the number of video frames to record", "number" },
        { "dframes", OPT_INT | HAS_ARG, {(void*)&max_frames[CODEC_TYPE_DATA]}, "set the number of data frames to record", "number" },
    
        { "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, 'list' as argument shows all the pixel formats supported", "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" },
    
        { "intra", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&intra_only}, "use only intra frames"},
        { "vn", OPT_BOOL | OPT_VIDEO, {(void*)&video_disable}, "disable video" },
    
    Måns Rullgård's avatar
    Måns Rullgård committed
        { "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 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" },
    
    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" },
    
        { "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",
    
        { "me_threshold", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_me_threshold}, "motion estimaton threshold",  "" },
    
        { "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" },
        { "psnr", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&do_psnr}, "calculate PSNR of compressed frames" },
    
        { "vstats", OPT_EXPERT | OPT_VIDEO, {(void*)&opt_vstats}, "dump video coding statistics to file" },
        { "vstats_file", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_vstats_file}, "dump video coding statistics to file", "file" },
    
        { "vhook", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)add_frame_hooker}, "insert video processing module", "module" },
    
        { "intra_matrix", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_intra_matrix}, "specify intra matrix coeffs", "matrix" },
        { "inter_matrix", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_inter_matrix}, "specify inter matrix coeffs", "matrix" },
    
        { "top", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_top_field_first}, "top=1/bottom=0/auto=-1 field first", "" },
    
        { "dc", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&intra_dc_precision}, "intra_dc_precision", "precision" },
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        { "vtag", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_video_tag}, "force video tag/fourcc", "fourcc/tag" },
    
        { "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" },
    
        { "aframes", OPT_INT | HAS_ARG | OPT_AUDIO, {(void*)&max_frames[CODEC_TYPE_AUDIO]}, "set the number of audio frames to record", "number" },
    
        { "aq", OPT_FLOAT | HAS_ARG | OPT_AUDIO, {(void*)&audio_qscale}, "set audio quality (codec-specific)", "quality", },
    
        { "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" },
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        { "atag", HAS_ARG | OPT_EXPERT | OPT_AUDIO, {(void*)opt_audio_tag}, "force audio tag/fourcc", "fourcc/tag" },
    
        { "vol", OPT_INT | HAS_ARG | OPT_AUDIO, {(void*)&audio_volume}, "change audio volume (256=normal)" , "volume" }, //
    
        { "newaudio", OPT_AUDIO, {(void*)opt_new_audio_stream}, "add a new audio stream to the current output stream" },
        { "alang", HAS_ARG | OPT_STRING | OPT_AUDIO, {(void *)&audio_language}, "set the ISO 639 language code (3 letters) of the current audio stream" , "code" },
    
        /* subtitle options */
        { "scodec", HAS_ARG | OPT_SUBTITLE, {(void*)opt_subtitle_codec}, "force subtitle codec ('copy' to copy stream)", "codec" },
        { "newsubtitle", OPT_SUBTITLE, {(void*)opt_new_subtitle_stream}, "add a new subtitle stream to the current output stream" },
        { "slang", HAS_ARG | OPT_STRING | OPT_SUBTITLE, {(void *)&subtitle_language}, "set the ISO 639 language code (3 letters) of the current subtitle stream" , "code" },
    
        /* grab options */
        { "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" },
    
        { "isync", OPT_BOOL | OPT_EXPERT | OPT_GRAB, {(void*)&input_sync}, "sync read on input", "" },
    
        { "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" },
    
    
        { "absf", HAS_ARG | OPT_AUDIO | OPT_EXPERT, {(void*)opt_audio_bsf}, "", "bitstream filter" },
        { "vbsf", HAS_ARG | OPT_VIDEO | OPT_EXPERT, {(void*)opt_video_bsf}, "", "bitstream filter" },
    
    
        { "default", OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        { NULL, },
    };
    
    
    static void show_banner(void)
    {
    
    Diego Biurrun's avatar
    Diego Biurrun committed
        fprintf(stderr, "FFmpeg version " FFMPEG_VERSION ", Copyright (c) 2000-2007 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");
        fprintf(stderr, "  libavformat version: " AV_STRINGIFY(LIBAVFORMAT_VERSION) "\n");
    
        fprintf(stderr, "  built on " __DATE__ " " __TIME__);
    
        fprintf(stderr, ", gcc: " __VERSION__ "\n");
    
        fprintf(stderr, ", using a non-gcc compiler\n");
    
    }
    
    static void show_license(void)
    {
        show_banner();
    
        "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"
    
        "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 FFmpeg; if not, write to the Free Software\n"
    
        "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\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.1 of the License, or (at your option) any later version.\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 FFmpeg; if not, write to the Free Software\n"
    
        "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n"
    
    /**
     * Trivial log callback.
     * Only suitable for show_help and similar since it lacks prefix handling.
     */
    static void log_callback_help(void* ptr, int level, const char* fmt, va_list vl)
    {
        vfprintf(stdout, fmt, vl);
    }
    
    
    static void show_help(void)
    
        av_log_set_callback(log_callback_help);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        printf("usage: ffmpeg [[infile options] -i infile]... {[outfile options] outfile}...\n"
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
               "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, "\nSubtitle options:\n",
    
                          OPT_SUBTITLE | OPT_GRAB,
    
        show_help_options(options, "\nAudio/Video grab options:\n",
    
                          OPT_GRAB);
        show_help_options(options, "\nAdvanced options:\n",
    
                          OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_GRAB,
    
        av_opt_show(avformat_opts, NULL);
    
    Aurelien Jacobs's avatar
    Aurelien Jacobs committed
            av_opt_show(sws_opts, NULL);
    
    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;
    
        for(i=0; i<CODEC_TYPE_NB; i++){
            avctx_opts[i]= avcodec_alloc_context2(i);
        }
    
        avformat_opts = av_alloc_format_context();
    
    Aurelien Jacobs's avatar
    Aurelien Jacobs committed
            sws_opts = sws_getContext(16,16,0, 16,16,0, sws_flags, NULL,NULL,NULL);
    
    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);
        }
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        if (nb_input_files == 0) {
    
            fprintf(stderr, "Must supply at least one input file\n");
            exit(1);
    
        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];
    
            if (!(s->oformat->flags & AVFMT_NOFILE))
    
                url_fclose(&s->pb);
    
            for(j=0;j<s->nb_streams;j++) {
                av_free(s->streams[j]->codec);
    
                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
    
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        av_free(intra_matrix);
        av_free(inter_matrix);
    
    
        if (fvstats)
            fclose(fvstats);
        av_free(vstats_filename);
    
    
    #ifdef CONFIG_POWERPC_PERF
    
        extern void powerpc_display_perf_report(void);
        powerpc_display_perf_report();
    
    #endif /* CONFIG_POWERPC_PERF */
    
        if (received_sigterm) {
            fprintf(stderr,
                "Received signal %d: terminating.\n",
                (int) received_sigterm);
            exit (255);
        }
    
        exit(0); /* not all OS-es handle main() return value */
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        return 0;
    }