Skip to content
Snippets Groups Projects
ffmpeg.c 154 KiB
Newer Older
  • Learn to ignore specific revisions
  • Fabrice Bellard's avatar
    Fabrice Bellard committed
            p++;
    
        m->stream_index = strtol(p, &p, 0);
    
            m->sync_file_index = strtol(p, &p, 0);
    
            m->sync_stream_index = strtol(p, &p, 0);
    
        } else {
            m->sync_file_index = m->file_index;
            m->sync_stream_index = m->stream_index;
        }
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    }
    
    
    static void opt_map_meta_data(const char *arg)
    {
        AVMetaDataMap *m;
    
        m->out_file = strtol(arg, &p, 0);
    
        m->in_file = strtol(p, &p, 0);
    
    static void opt_input_ts_scale(const char *arg)
    {
        unsigned int stream;
        double scale;
        char *p;
    
        stream = strtol(arg, &p, 0);
        if (*p)
            p++;
        scale= strtod(p, &p);
    
        if(stream >= MAX_STREAMS)
            av_exit(1);
    
        input_files_ts_scale[nb_input_files][stream]= scale;
    }
    
    
    static int opt_recording_time(const char *opt, const char *arg)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
    
        recording_time = parse_time_or_die(opt, arg, 1);
        return 0;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    }
    
    
    static int opt_start_time(const char *opt, const char *arg)
    
        start_time = parse_time_or_die(opt, arg, 1);
        return 0;
    
    static int opt_rec_timestamp(const char *opt, const char *arg)
    
        rec_timestamp = parse_time_or_die(opt, arg, 0) / 1000000;
        return 0;
    
    static int opt_input_ts_offset(const char *opt, const char *arg)
    
        input_ts_offset = parse_time_or_die(opt, arg, 1);
        return 0;
    
    static enum CodecID find_codec_or_die(const char *name, int type, int encoder, int strict)
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        const char *codec_string = encoder ? "encoder" : "decoder";
    
        AVCodec *codec;
    
        if(!name)
            return CODEC_ID_NONE;
        codec = encoder ?
            avcodec_find_encoder_by_name(name) :
            avcodec_find_decoder_by_name(name);
        if(!codec) {
    
            fprintf(stderr, "Unknown %s '%s'\n", codec_string, name);
    
            fprintf(stderr, "Invalid %s type '%s'\n", codec_string, name);
    
        if(codec->capabilities & CODEC_CAP_EXPERIMENTAL &&
           strict > FF_COMPLIANCE_EXPERIMENTAL) {
            fprintf(stderr, "%s '%s' is experimental and might produce bad "
                    "results.\nAdd '-strict experimental' if you want to use it.\n",
                    codec_string, codec->name);
            av_exit(1);
        }
    
    static void opt_input_file(const char *filename)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
        AVFormatContext *ic;
        AVFormatParameters params, *ap = &params;
    
        AVInputFormat *file_iformat = NULL;
    
        int64_t timestamp;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
        if (last_asked_format) {
    
            if (!(file_iformat = av_find_input_format(last_asked_format))) {
                fprintf(stderr, "Unknown input format: '%s'\n", last_asked_format);
                av_exit(1);
            }
    
        if (!strcmp(filename, "-"))
            filename = "pipe:";
    
    
        using_stdin |= !strncmp(filename, "pipe:", 5) ||
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        /* get default parameters from command line */
    
        if (!ic) {
            print_error(filename, AVERROR(ENOMEM));
            av_exit(1);
        }
    
        ap->prealloced_context = 1;
    
        ap->sample_rate = audio_sample_rate;
        ap->channels = audio_channels;
    
        ap->time_base.den = frame_rate.num;
        ap->time_base.num = frame_rate.den;
    
        ap->width = frame_width;
        ap->height = frame_height;
    
        ap->pix_fmt = frame_pix_fmt;
    
       // ap->sample_fmt = audio_sample_fmt; //FIXME:not implemented in libavformat
    
        ap->channel = video_channel;
        ap->standard = video_standard;
    
        set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM);
    
        ic->video_codec_id   =
            find_codec_or_die(video_codec_name   , AVMEDIA_TYPE_VIDEO   , 0,
                              avcodec_opts[AVMEDIA_TYPE_VIDEO   ]->strict_std_compliance);
        ic->audio_codec_id   =
            find_codec_or_die(audio_codec_name   , AVMEDIA_TYPE_AUDIO   , 0,
                              avcodec_opts[AVMEDIA_TYPE_AUDIO   ]->strict_std_compliance);
        ic->subtitle_codec_id=
            find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 0,
                              avcodec_opts[AVMEDIA_TYPE_SUBTITLE]->strict_std_compliance);
    
        ic->flags |= AVFMT_FLAG_NONBLOCK;
    
        if(pgmyuv_compatibility_hack)
            ic->video_codec_id= CODEC_ID_PGMYUV;
    
    
        /* open the input file with generic libav function */
        err = av_open_input_file(&ic, filename, file_iformat, 0, ap);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        if (err < 0) {
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        }
    
            int i, j;
            int found=0;
            for(i=0; i<ic->nb_streams; i++){
                ic->streams[i]->discard= AVDISCARD_ALL;
            }
            for(i=0; i<ic->nb_programs; i++){
                AVProgram *p= ic->programs[i];
                if(p->id != opt_programid){
                    p->discard = AVDISCARD_ALL;
                }else{
                    found=1;
                    for(j=0; j<p->nb_stream_indexes; j++){
    
                        ic->streams[p->stream_index[j]]->discard= AVDISCARD_DEFAULT;
    
                    }
                }
            }
            if(!found){
                fprintf(stderr, "Specified program id not found\n");
                av_exit(1);
            }
            opt_programid=0;
    
        /* If not enough info to get the stream parameters, we decode the
           first frames to get it. (used in mpeg case for example) */
        ret = av_find_stream_info(ic);
    
        if (ret < 0 && verbose >= 0) {
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            fprintf(stderr, "%s: could not find codec parameters\n", filename);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        }
    
    
        timestamp = start_time;
        /* add the stream start time */
        if (ic->start_time != AV_NOPTS_VALUE)
            timestamp += ic->start_time;
    
    
        /* if seeking requested, we execute it */
        if (start_time != 0) {
    
            ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
    
                fprintf(stderr, "%s: could not seek to position %0.3f\n",
    
                        filename, (double)timestamp / AV_TIME_BASE);
            }
            /* reset seek info */
            start_time = 0;
        }
    
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        /* update the current parameters so that they match the one of the input stream */
        for(i=0;i<ic->nb_streams;i++) {
    
            AVStream *st = ic->streams[i];
            AVCodecContext *enc = st->codec;
    
    Måns Rullgård's avatar
    Måns Rullgård committed
            avcodec_thread_init(enc, thread_count);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            switch(enc->codec_type) {
    
            case AVMEDIA_TYPE_AUDIO:
                set_context_opts(enc, avcodec_opts[AVMEDIA_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM);
    
                //fprintf(stderr, "\nInput Audio channels: %d", enc->channels);
    
                channel_layout = enc->channel_layout;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                audio_channels = enc->channels;
                audio_sample_rate = enc->sample_rate;
    
                audio_sample_fmt = enc->sample_fmt;
    
    Aurelien Jacobs's avatar
    Aurelien Jacobs committed
                input_codecs[nb_icodecs++] = avcodec_find_decoder_by_name(audio_codec_name);
    
                    st->discard= AVDISCARD_ALL;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                break;
    
            case AVMEDIA_TYPE_VIDEO:
                set_context_opts(enc, avcodec_opts[AVMEDIA_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                frame_height = enc->height;
                frame_width = enc->width;
    
                if(ic->streams[i]->sample_aspect_ratio.num)
                    frame_aspect_ratio=av_q2d(ic->streams[i]->sample_aspect_ratio);
                else
                    frame_aspect_ratio=av_q2d(enc->sample_aspect_ratio);
                frame_aspect_ratio *= (float) enc->width / enc->height;
    
                frame_pix_fmt = enc->pix_fmt;
    
                rfps      = ic->streams[i]->r_frame_rate.num;
                rfps_base = ic->streams[i]->r_frame_rate.den;
    
                if(enc->lowres) {
                    enc->flags |= CODEC_FLAG_EMU_EDGE;
                    frame_height >>= enc->lowres;
                    frame_width  >>= enc->lowres;
                }
    
                if (enc->time_base.den != rfps*enc->ticks_per_frame || enc->time_base.num != rfps_base) {
    
                        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);
    
                /* update the current frame rate to match the stream frame rate */
    
                frame_rate.num = rfps;
                frame_rate.den = rfps_base;
    
    Aurelien Jacobs's avatar
    Aurelien Jacobs committed
                input_codecs[nb_icodecs++] = avcodec_find_decoder_by_name(video_codec_name);
    
                    st->discard= AVDISCARD_ALL;
    
                else if(video_discard)
    
                    st->discard= video_discard;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                break;
    
    Aurelien Jacobs's avatar
    Aurelien Jacobs committed
                input_codecs[nb_icodecs++] = avcodec_find_decoder_by_name(subtitle_codec_name);
    
                    st->discard = AVDISCARD_ALL;
    
            case AVMEDIA_TYPE_ATTACHMENT:
            case AVMEDIA_TYPE_UNKNOWN:
    
    Aurelien Jacobs's avatar
    Aurelien Jacobs committed
                nb_icodecs++;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            }
        }
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        input_files[nb_input_files] = ic;
    
        input_files_ts_offset[nb_input_files] = input_ts_offset - (copy_ts ? 0 : timestamp);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        /* dump the file content */
    
        if (verbose >= 0)
            dump_format(ic, nb_input_files, filename, 0);
    
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        nb_input_files++;
    
        video_channel = 0;
    
        av_freep(&video_codec_name);
        av_freep(&audio_codec_name);
        av_freep(&subtitle_codec_name);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    }
    
    
    static void check_audio_video_sub_inputs(int *has_video_ptr, int *has_audio_ptr,
                                             int *has_subtitle_ptr)
    
        int has_video, has_audio, has_subtitle, i, j;
    
        for(j=0;j<nb_input_files;j++) {
            ic = input_files[j];
            for(i=0;i<ic->nb_streams;i++) {
    
                AVCodecContext *enc = ic->streams[i]->codec;
    
                case AVMEDIA_TYPE_DATA:
                case AVMEDIA_TYPE_ATTACHMENT:
                case AVMEDIA_TYPE_UNKNOWN:
    
                }
            }
        }
        *has_video_ptr = has_video;
        *has_audio_ptr = has_audio;
    
        *has_subtitle_ptr = has_subtitle;
    
    static void new_video_stream(AVFormatContext *oc)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
        AVStream *st;
    
        enum CodecID codec_id;
    
        st = av_new_stream(oc, oc->nb_streams);
        if (!st) {
            fprintf(stderr, "Could not alloc stream\n");
    
        avcodec_get_context_defaults2(st->codec, AVMEDIA_TYPE_VIDEO);
    
        bitstream_filters[nb_output_files][oc->nb_streams - 1]= video_bitstream_filters;
        video_bitstream_filters= NULL;
    
    
    Måns Rullgård's avatar
    Måns Rullgård committed
        avcodec_thread_init(st->codec, thread_count);
    
        if(video_codec_tag)
            video_enc->codec_tag= video_codec_tag;
    
           || (video_global_header==0 && (oc->oformat->flags & AVFMT_GLOBALHEADER))){
    
            video_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
    
            avcodec_opts[AVMEDIA_TYPE_VIDEO]->flags|= CODEC_FLAG_GLOBAL_HEADER;
    
        }
        if(video_global_header&2){
    
            video_enc->flags2 |= CODEC_FLAG2_LOCAL_HEADER;
    
            avcodec_opts[AVMEDIA_TYPE_VIDEO]->flags2|= CODEC_FLAG2_LOCAL_HEADER;
    
        if (video_stream_copy) {
            st->stream_copy = 1;
    
            video_enc->codec_type = AVMEDIA_TYPE_VIDEO;
    
            video_enc->sample_aspect_ratio =
    
            st->sample_aspect_ratio = av_d2q(frame_aspect_ratio*frame_height/frame_width, 255);
    
            const char *p;
    
            AVRational fps= frame_rate.num ? frame_rate : (AVRational){25,1};
    
    Aurelien Jacobs's avatar
    Aurelien Jacobs committed
            if (video_codec_name) {
    
                codec_id = find_codec_or_die(video_codec_name, AVMEDIA_TYPE_VIDEO, 1,
                                             video_enc->strict_std_compliance);
    
    Aurelien Jacobs's avatar
    Aurelien Jacobs committed
                codec = avcodec_find_encoder_by_name(video_codec_name);
                output_codecs[nb_ocodecs] = codec;
            } else {
    
                codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_VIDEO);
    
    Aurelien Jacobs's avatar
    Aurelien Jacobs committed
                codec = avcodec_find_encoder(codec_id);
            }
    
            set_context_opts(video_enc, avcodec_opts[AVMEDIA_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM);
    
            if (codec && codec->supported_framerates && !force_fps)
                fps = codec->supported_framerates[av_find_nearest_q_idx(fps, codec->supported_framerates)];
    
            video_enc->time_base.den = fps.num;
            video_enc->time_base.num = fps.den;
    
            video_enc->width = frame_width;
            video_enc->height = frame_height;
    
            video_enc->sample_aspect_ratio = av_d2q(frame_aspect_ratio*video_enc->height/video_enc->width, 255);
    
            st->sample_aspect_ratio = video_enc->sample_aspect_ratio;
    
                video_enc->gop_size = 0;
            if (video_qscale || same_quality) {
                video_enc->flags |= CODEC_FLAG_QSCALE;
    
                video_enc->global_quality=
    
                    st->quality = FF_QP2LAMBDA * video_qscale;
            }
    
            if(intra_matrix)
                video_enc->intra_matrix = intra_matrix;
            if(inter_matrix)
                video_enc->inter_matrix = inter_matrix;
    
            p= video_rc_override_string;
            for(i=0; p; i++){
                int start, end, q;
                int e=sscanf(p, "%d,%d,%d", &start, &end, &q);
                if(e!=3){
                    fprintf(stderr, "error parsing rc_override\n");
    
                video_enc->rc_override=
                    av_realloc(video_enc->rc_override,
    
                               sizeof(RcOverride)*(i+1));
                video_enc->rc_override[i].start_frame= start;
                video_enc->rc_override[i].end_frame  = end;
                if(q>0){
                    video_enc->rc_override[i].qscale= q;
                    video_enc->rc_override[i].quality_factor= 1.0;
                }
                else{
                    video_enc->rc_override[i].qscale= 0;
                    video_enc->rc_override[i].quality_factor= -q/100.0;
                }
                p= strchr(p, '/');
                if(p) p++;
            }
            video_enc->rc_override_count=i;
    
            if (!video_enc->rc_initial_buffer_occupancy)
                video_enc->rc_initial_buffer_occupancy = video_enc->rc_buffer_size*3/4;
    
            video_enc->me_threshold= me_threshold;
            video_enc->intra_dc_precision= intra_dc_precision - 8;
    
            if (do_psnr)
                video_enc->flags|= CODEC_FLAG_PSNR;
    
            /* two pass mode */
            if (do_pass) {
                if (do_pass == 1) {
                    video_enc->flags |= CODEC_FLAG_PASS1;
                } else {
                    video_enc->flags |= CODEC_FLAG_PASS2;
                }
            }
        }
    
    Aurelien Jacobs's avatar
    Aurelien Jacobs committed
        nb_ocodecs++;
    
            av_metadata_set2(&st->metadata, "language", video_language, 0);
    
    
        /* reset some key parameters */
        video_disable = 0;
    
        frame_pix_fmt = PIX_FMT_NONE;
    
    }
    
    static void new_audio_stream(AVFormatContext *oc)
    {
        AVStream *st;
        AVCodecContext *audio_enc;
    
        enum CodecID codec_id;
    
        st = av_new_stream(oc, oc->nb_streams);
        if (!st) {
            fprintf(stderr, "Could not alloc stream\n");
    
        avcodec_get_context_defaults2(st->codec, AVMEDIA_TYPE_AUDIO);
    
    
        bitstream_filters[nb_output_files][oc->nb_streams - 1]= audio_bitstream_filters;
        audio_bitstream_filters= NULL;
    
    
    Måns Rullgård's avatar
    Måns Rullgård committed
        avcodec_thread_init(st->codec, thread_count);
    
        audio_enc->codec_type = AVMEDIA_TYPE_AUDIO;
    
        if(audio_codec_tag)
            audio_enc->codec_tag= audio_codec_tag;
    
        if (oc->oformat->flags & AVFMT_GLOBALHEADER) {
    
            audio_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
    
            avcodec_opts[AVMEDIA_TYPE_AUDIO]->flags|= CODEC_FLAG_GLOBAL_HEADER;
    
        if (audio_stream_copy) {
            st->stream_copy = 1;
            audio_enc->channels = audio_channels;
    
            audio_enc->sample_rate = audio_sample_rate;
    
            set_context_opts(audio_enc, avcodec_opts[AVMEDIA_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM);
    
    Aurelien Jacobs's avatar
    Aurelien Jacobs committed
            if (audio_codec_name) {
    
                codec_id = find_codec_or_die(audio_codec_name, AVMEDIA_TYPE_AUDIO, 1,
                                             audio_enc->strict_std_compliance);
    
    Aurelien Jacobs's avatar
    Aurelien Jacobs committed
                codec = avcodec_find_encoder_by_name(audio_codec_name);
                output_codecs[nb_ocodecs] = codec;
            } else {
    
                codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_AUDIO);
    
    Aurelien Jacobs's avatar
    Aurelien Jacobs committed
                codec = avcodec_find_encoder(codec_id);
            }
    
            if (audio_qscale > QSCALE_NONE) {
                audio_enc->flags |= CODEC_FLAG_QSCALE;
                audio_enc->global_quality = st->quality = FF_QP2LAMBDA * audio_qscale;
            }
    
            audio_enc->channels = audio_channels;
    
            audio_enc->sample_fmt = audio_sample_fmt;
    
            audio_enc->sample_rate = audio_sample_rate;
    
            audio_enc->channel_layout = channel_layout;
    
            if (avcodec_channel_layout_num_channels(channel_layout) != audio_channels)
                audio_enc->channel_layout = 0;
    
    Aurelien Jacobs's avatar
    Aurelien Jacobs committed
        nb_ocodecs++;
    
        audio_enc->time_base= (AVRational){1, audio_sample_rate};
    
            av_metadata_set2(&st->metadata, "language", audio_language, 0);
    
    static void new_subtitle_stream(AVFormatContext *oc)
    
        st = av_new_stream(oc, oc->nb_streams);
        if (!st) {
            fprintf(stderr, "Could not alloc stream\n");
    
        avcodec_get_context_defaults2(st->codec, AVMEDIA_TYPE_SUBTITLE);
    
        bitstream_filters[nb_output_files][oc->nb_streams - 1]= subtitle_bitstream_filters;
        subtitle_bitstream_filters= NULL;
    
    
        subtitle_enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
    
    
        if(subtitle_codec_tag)
            subtitle_enc->codec_tag= subtitle_codec_tag;
    
    
        if (subtitle_stream_copy) {
            st->stream_copy = 1;
        } else {
    
            set_context_opts(avcodec_opts[AVMEDIA_TYPE_SUBTITLE], subtitle_enc, AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_ENCODING_PARAM);
    
            subtitle_enc->codec_id = find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 1,
                                                       subtitle_enc->strict_std_compliance);
    
    Aurelien Jacobs's avatar
    Aurelien Jacobs committed
            output_codecs[nb_ocodecs] = avcodec_find_encoder_by_name(subtitle_codec_name);
    
    Aurelien Jacobs's avatar
    Aurelien Jacobs committed
        nb_ocodecs++;
    
            av_metadata_set2(&st->metadata, "language", subtitle_language, 0);
    
            av_freep(&subtitle_language);
    
        subtitle_stream_copy = 0;
    }
    
    static void opt_new_audio_stream(void)
    {
        AVFormatContext *oc;
        if (nb_output_files <= 0) {
            fprintf(stderr, "At least one output file must be specified\n");
    
        }
        oc = output_files[nb_output_files - 1];
        new_audio_stream(oc);
    }
    
    static void opt_new_video_stream(void)
    {
        AVFormatContext *oc;
        if (nb_output_files <= 0) {
            fprintf(stderr, "At least one output file must be specified\n");
    
        }
        oc = output_files[nb_output_files - 1];
        new_video_stream(oc);
    }
    
    
    static void opt_new_subtitle_stream(void)
    {
        AVFormatContext *oc;
        if (nb_output_files <= 0) {
            fprintf(stderr, "At least one output file must be specified\n");
    
        }
        oc = output_files[nb_output_files - 1];
        new_subtitle_stream(oc);
    }
    
    
    static void opt_output_file(const char *filename)
    {
        AVFormatContext *oc;
    
        int err, use_video, use_audio, use_subtitle;
    
        int input_has_video, input_has_audio, input_has_subtitle;
    
        AVOutputFormat *file_oformat;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
        if (!strcmp(filename, "-"))
            filename = "pipe:";
    
    
        if (!oc) {
            print_error(filename, AVERROR(ENOMEM));
            av_exit(1);
        }
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
        if (last_asked_format) {
    
            file_oformat = av_guess_format(last_asked_format, NULL, NULL);
    
            if (!file_oformat) {
                fprintf(stderr, "Requested output format '%s' is not a suitable output format\n", last_asked_format);
                av_exit(1);
            }
            last_asked_format = NULL;
        } else {
    
            file_oformat = av_guess_format(NULL, filename, NULL);
    
                fprintf(stderr, "Unable to find a suitable output format for '%s'\n",
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        }
    
        av_strlcpy(oc->filename, filename, sizeof(oc->filename));
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
        if (!strcmp(file_oformat->name, "ffm") &&
    
            av_strstart(filename, "http:", NULL)) {
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            /* special case for files sent to ffserver: we get the stream
               parameters from ffserver */
    
            int err = read_ffserver_streams(oc, filename);
            if (err < 0) {
                print_error(filename, err);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            }
        } else {
    
            use_video = file_oformat->video_codec != CODEC_ID_NONE || video_stream_copy || video_codec_name;
            use_audio = file_oformat->audio_codec != CODEC_ID_NONE || audio_stream_copy || audio_codec_name;
            use_subtitle = file_oformat->subtitle_codec != CODEC_ID_NONE || subtitle_stream_copy || subtitle_codec_name;
    
            /* disable if no corresponding type found and at least one
               input file */
            if (nb_input_files > 0) {
    
                check_audio_video_sub_inputs(&input_has_video, &input_has_audio,
                                             &input_has_subtitle);
    
                if (!input_has_video)
                    use_video = 0;
                if (!input_has_audio)
                    use_audio = 0;
    
                if (!input_has_subtitle)
                    use_subtitle = 0;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            if (audio_disable) {
                use_audio = 0;
            }
            if (video_disable) {
                use_video = 0;
            }
    
            if (subtitle_disable) {
                use_subtitle = 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
            }
    
    
            if (use_subtitle) {
                new_subtitle_stream(oc);
            }
    
    
            for(; metadata_count>0; metadata_count--){
    
                av_metadata_set2(&oc->metadata, metadata[metadata_count-1].key,
                                                metadata[metadata_count-1].value, 0);
    
            }
            av_metadata_conv(oc, oc->oformat->metadata_conv, NULL);
    
    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 ||
    
                 av_strstart(filename, "file:", NULL))) {
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                if (url_exist(filename)) {
    
                        fprintf(stderr,"File '%s' already exists. Overwrite ? [y/N] ", filename);
                        fflush(stderr);
    
                        if (!read_yesno()) {
    
                            fprintf(stderr, "Not overwriting - exiting\n");
    
                        fprintf(stderr,"File '%s' already exists. Exiting.\n", filename);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                }
            }
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            /* open the file */
    
            if ((err = url_fopen(&oc->pb, filename, URL_WRONLY)) < 0) {
                print_error(filename, err);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            }
        }
    
    
        memset(ap, 0, sizeof(*ap));
        if (av_set_parameters(oc, ap) < 0) {
            fprintf(stderr, "%s: Invalid encoding parameters\n",
                    oc->filename);
    
        oc->preload= (int)(mux_preload*AV_TIME_BASE);
        oc->max_delay= (int)(mux_max_delay*AV_TIME_BASE);
    
        oc->loop_output = loop_output;
    
        oc->flags |= AVFMT_FLAG_NONBLOCK;
    
        set_context_opts(oc, avformat_opts, AV_OPT_FLAG_ENCODING_PARAM);
    
    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");
    
    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;
    
    #elif HAVE_GETPROCESSTIMES
    
        HANDLE proc;
        FILETIME c, e, k, u;
        proc = GetCurrentProcess();
        GetProcessTimes(proc, &c, &e, &k, &u);
        return ((int64_t) u.dwHighDateTime << 32 | u.dwLowDateTime) / 10;
    #else
    
    Ramiro Polla's avatar
    Ramiro Polla committed
        return av_gettime();
    
    Ramiro Polla's avatar
    Ramiro Polla committed
    #endif
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    }
    
    static int64_t getmaxrss(void)
    {
    #if HAVE_GETRUSAGE && HAVE_STRUCT_RUSAGE_RU_MAXRSS
        struct rusage rusage;
        getrusage(RUSAGE_SELF, &rusage);
        return (int64_t)rusage.ru_maxrss * 1024;
    #elif HAVE_GETPROCESSMEMORYINFO
        HANDLE proc;
        PROCESS_MEMORY_COUNTERS memcounters;
        proc = GetCurrentProcess();
        memcounters.cb = sizeof(memcounters);
        GetProcessMemoryInfo(proc, &memcounters, sizeof(memcounters));
        return memcounters.PeakPagefileUsage;
    #else
        return 0;
    #endif
    }
    
    
    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);
    
    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);
    }
    
    
    /**
     * 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_usage(void)
    
        printf("Hyper fast Audio and Video encoder\n");
    
        printf("usage: ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}...\n");
    
    }
    
    static void show_help(void)
    {
        av_log_set_callback(log_callback_help);
        show_usage();
    
        show_help_options(options, "Main options:\n",
    
                          OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE | OPT_GRAB, 0);
    
        show_help_options(options, "\nAdvanced options:\n",
                          OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE | OPT_GRAB,
                          OPT_EXPERT);
    
        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,
                          OPT_SUBTITLE);
        show_help_options(options, "\nAudio/Video grab options:\n",
                          OPT_GRAB,
                          OPT_GRAB);
    
        av_opt_show(avcodec_opts[0], NULL);
    
        av_opt_show(avformat_opts, NULL);
    
    static void opt_target(const char *arg)
    {
    
        enum { PAL, NTSC, FILM, UNKNOWN } norm = UNKNOWN;
    
        static const char *const frame_rates[] = {"25", "30000/1001", "24000/1001"};
    
            arg += 4;
        } else if(!strncmp(arg, "ntsc-", 5)) {
    
        } else if(!strncmp(arg, "film-", 5)) {
    
        } else {
            int fr;
            /* Calculate FR via float to avoid int overflow */
    
            fr = (int)(frame_rate.num * 1000.0 / frame_rate.den);
    
            } else if((fr == 29970) || (fr == 23976)) {
    
            } 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 != AVMEDIA_TYPE_VIDEO)
    
                            fr = c->time_base.den * 1000 / c->time_base.num;
    
                                break;
                            } else if((fr == 29970) || (fr == 23976)) {
    
                fprintf(stderr, "Assuming %s for target.\n", norm == PAL ? "PAL" : "NTSC");
    
            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");
    
        }
    
        if(!strcmp(arg, "vcd")) {
    
            opt_video_codec("mpeg1video");
            opt_audio_codec("mp2");
            opt_format("vcd");
    
    
            opt_frame_size(norm == PAL ? "352x288" : "352x240");
    
            opt_frame_rate(NULL, frame_rates[norm]);
    
            opt_default("g", norm == PAL ? "15" : "18");
    
            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 == PAL ? "480x576" : "480x480");
    
            opt_frame_rate(NULL, frame_rates[norm]);
    
            opt_default("g", norm == PAL ? "15" : "18");
    
            opt_default("maxrate", "2516000");
            opt_default("minrate", "0"); //1145000;
    
            opt_default("bufsize", "1835008"); //224*1024*8;
    
            opt_default("flags", "+scan_offset");