Skip to content
Snippets Groups Projects
ffmpeg.c 159 KiB
Newer Older
  • Learn to ignore specific revisions
  • 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)
    
            ffmpeg_exit(1);
    
        input_files_ts_scale[nb_input_files] = grow_array(input_files_ts_scale[nb_input_files], sizeof(*input_files_ts_scale[nb_input_files]), &nb_input_files_ts_scale[nb_input_files], stream + 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_recording_timestamp(const char *opt, const char *arg)
    
        recording_timestamp = parse_time_or_die(opt, arg, 0) / 1000000;
    
    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);
    
            ffmpeg_exit(1);
    
            fprintf(stderr, "Invalid %s type '%s'\n", codec_string, name);
    
            ffmpeg_exit(1);
    
        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);
    
            codec = encoder ?
                avcodec_find_encoder(codec->id) :
                avcodec_find_decoder(codec->id);
            if (!(codec->capabilities & CODEC_CAP_EXPERIMENTAL))
                fprintf(stderr, "Or use the non experimental %s '%s'.\n",
                        codec_string, codec->name);
    
            ffmpeg_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);
    
                ffmpeg_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));
    
            ffmpeg_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, NULL);
    
        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;
    
        /* 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) {
    
            ffmpeg_exit(1);
    
    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");
    
                ffmpeg_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);
    
            av_close_input_file(ic);
    
            ffmpeg_exit(1);
    
    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 *dec = st->codec;
    
            dec->thread_count = thread_count;
    
            input_codecs = grow_array(input_codecs, sizeof(*input_codecs), &nb_input_codecs, nb_input_codecs + 1);
    
            switch (dec->codec_type) {
    
                input_codecs[nb_input_codecs-1] = avcodec_find_decoder_by_name(audio_codec_name);
                set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM, input_codecs[nb_input_codecs-1]);
    
                //fprintf(stderr, "\nInput Audio channels: %d", dec->channels);
                channel_layout    = dec->channel_layout;
                audio_channels    = dec->channels;
                audio_sample_rate = dec->sample_rate;
                audio_sample_fmt  = dec->sample_fmt;
    
                    st->discard= AVDISCARD_ALL;
    
                /* Note that av_find_stream_info can add more streams, and we
                 * currently have no chance of setting up lowres decoding
                 * early enough for them. */
                if (dec->lowres)
                    audio_sample_rate >>= dec->lowres;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                break;
    
                input_codecs[nb_input_codecs-1] = avcodec_find_decoder_by_name(video_codec_name);
                set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM, input_codecs[nb_input_codecs-1]);
    
                frame_height = dec->height;
                frame_width  = dec->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(dec->sample_aspect_ratio);
                frame_aspect_ratio *= (float) dec->width / dec->height;
                frame_pix_fmt = dec->pix_fmt;
    
                rfps      = ic->streams[i]->r_frame_rate.num;
                rfps_base = ic->streams[i]->r_frame_rate.den;
    
                if (dec->lowres) {
                    dec->flags |= CODEC_FLAG_EMU_EDGE;
                    frame_height >>= dec->lowres;
                    frame_width  >>= dec->lowres;
    
                    dec->height = frame_height;
                    dec->width  = frame_width;
    
                    dec->debug |= FF_DEBUG_MV;
    
                if (dec->time_base.den != rfps*dec->ticks_per_frame || dec->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)dec->time_base.den / dec->time_base.num, dec->time_base.den, dec->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;
    
                    st->discard= AVDISCARD_ALL;
    
                else if(video_discard)
    
                    st->discard= video_discard;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                break;
    
                input_codecs[nb_input_codecs-1] = avcodec_find_decoder_by_name(subtitle_codec_name);
    
                    st->discard = AVDISCARD_ALL;
    
            case AVMEDIA_TYPE_ATTACHMENT:
            case AVMEDIA_TYPE_UNKNOWN:
    
    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 */
    
            av_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, int file_idx)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
        AVStream *st;
    
    Baptiste Coudurier's avatar
    Baptiste Coudurier committed
        enum CodecID codec_id = CODEC_ID_NONE;
    
        st = av_new_stream(oc, oc->nb_streams < nb_streamid_map ? streamid_map[oc->nb_streams] : 0);
    
        if (!st) {
            fprintf(stderr, "Could not alloc stream\n");
    
            ffmpeg_exit(1);
    
        ost = new_output_stream(oc, file_idx);
    
        output_codecs = grow_array(output_codecs, sizeof(*output_codecs), &nb_output_codecs, nb_output_codecs + 1);
    
        if(!video_stream_copy){
            if (video_codec_name) {
                codec_id = find_codec_or_die(video_codec_name, AVMEDIA_TYPE_VIDEO, 1,
                                             avcodec_opts[AVMEDIA_TYPE_VIDEO]->strict_std_compliance);
                codec = avcodec_find_encoder_by_name(video_codec_name);
    
                output_codecs[nb_output_codecs-1] = codec;
    
            } else {
                codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_VIDEO);
                codec = avcodec_find_encoder(codec_id);
            }
        }
    
        avcodec_get_context_defaults3(st->codec, codec);
    
        ost->bitstream_filters = video_bitstream_filters;
    
        st->codec->thread_count= 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};
    
            set_context_opts(video_enc, avcodec_opts[AVMEDIA_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM, codec);
    
            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");
    
                    ffmpeg_exit(1);
    
                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;
                }
            }
    
    
            if (forced_key_frames)
                parse_forced_key_frames(forced_key_frames, ost, video_enc);
    
            av_metadata_set2(&st->metadata, "language", video_language, 0);
    
    
        /* reset some key parameters */
        video_disable = 0;
    
        av_freep(&forced_key_frames);
    
        frame_pix_fmt = PIX_FMT_NONE;
    
    static void new_audio_stream(AVFormatContext *oc, int file_idx)
    
    Baptiste Coudurier's avatar
    Baptiste Coudurier committed
        enum CodecID codec_id = CODEC_ID_NONE;
    
        st = av_new_stream(oc, oc->nb_streams < nb_streamid_map ? streamid_map[oc->nb_streams] : 0);
    
        if (!st) {
            fprintf(stderr, "Could not alloc stream\n");
    
            ffmpeg_exit(1);
    
        ost = new_output_stream(oc, file_idx);
    
        output_codecs = grow_array(output_codecs, sizeof(*output_codecs), &nb_output_codecs, nb_output_codecs + 1);
    
        if(!audio_stream_copy){
            if (audio_codec_name) {
                codec_id = find_codec_or_die(audio_codec_name, AVMEDIA_TYPE_AUDIO, 1,
                                             avcodec_opts[AVMEDIA_TYPE_AUDIO]->strict_std_compliance);
                codec = avcodec_find_encoder_by_name(audio_codec_name);
    
                output_codecs[nb_output_codecs-1] = codec;
    
            } else {
                codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_AUDIO);
                codec = avcodec_find_encoder(codec_id);
            }
        }
    
        avcodec_get_context_defaults3(st->codec, codec);
    
        ost->bitstream_filters = audio_bitstream_filters;
    
        st->codec->thread_count= 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, codec);
    
            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 (av_get_channel_layout_nb_channels(channel_layout) != audio_channels)
    
        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, int file_idx)
    
    Baptiste Coudurier's avatar
    Baptiste Coudurier committed
        enum CodecID codec_id = CODEC_ID_NONE;
    
        st = av_new_stream(oc, oc->nb_streams < nb_streamid_map ? streamid_map[oc->nb_streams] : 0);
    
        if (!st) {
            fprintf(stderr, "Could not alloc stream\n");
    
            ffmpeg_exit(1);
    
        ost = new_output_stream(oc, file_idx);
    
        subtitle_enc = st->codec;
    
        output_codecs = grow_array(output_codecs, sizeof(*output_codecs), &nb_output_codecs, nb_output_codecs + 1);
    
        if(!subtitle_stream_copy){
    
            if (subtitle_codec_name) {
                codec_id = find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 1,
    
    Aurelien Jacobs's avatar
    Aurelien Jacobs committed
                                             avcodec_opts[AVMEDIA_TYPE_SUBTITLE]->strict_std_compliance);
                codec= output_codecs[nb_output_codecs-1] = avcodec_find_encoder_by_name(subtitle_codec_name);
    
            } else {
                codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_SUBTITLE);
                codec = avcodec_find_encoder(codec_id);
            }
    
        }
        avcodec_get_context_defaults3(st->codec, codec);
    
        ost->bitstream_filters = 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 (oc->oformat->flags & AVFMT_GLOBALHEADER) {
            subtitle_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
            avcodec_opts[AVMEDIA_TYPE_SUBTITLE]->flags |= CODEC_FLAG_GLOBAL_HEADER;
        }
    
        if (subtitle_stream_copy) {
            st->stream_copy = 1;
        } else {
    
            subtitle_enc->codec_id = codec_id;
    
            set_context_opts(avcodec_opts[AVMEDIA_TYPE_SUBTITLE], subtitle_enc, AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_ENCODING_PARAM, codec);
    
            av_metadata_set2(&st->metadata, "language", subtitle_language, 0);
    
            av_freep(&subtitle_language);
    
    static int opt_new_stream(const char *opt, const char *arg)
    
        int file_idx = nb_output_files - 1;
    
        if (nb_output_files <= 0) {
            fprintf(stderr, "At least one output file must be specified\n");
    
            ffmpeg_exit(1);
    
        if      (!strcmp(opt, "newvideo"   )) new_video_stream   (oc, file_idx);
        else if (!strcmp(opt, "newaudio"   )) new_audio_stream   (oc, file_idx);
        else if (!strcmp(opt, "newsubtitle")) new_subtitle_stream(oc, file_idx);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        else av_assert0(0);
    
    /* arg format is "output-stream-index:streamid-value". */
    
    static int opt_streamid(const char *opt, const char *arg)
    
    {
        int idx;
        char *p;
        char idx_str[16];
    
        strncpy(idx_str, arg, sizeof(idx_str));
        idx_str[sizeof(idx_str)-1] = '\0';
        p = strchr(idx_str, ':');
        if (!p) {
            fprintf(stderr,
                    "Invalid value '%s' for option '%s', required syntax is 'index:value'\n",
                    arg, opt);
    
            ffmpeg_exit(1);
    
        }
        *p++ = '\0';
        idx = parse_number_or_die(opt, idx_str, OPT_INT, 0, MAX_STREAMS-1);
    
        streamid_map = grow_array(streamid_map, sizeof(*streamid_map), &nb_streamid_map, idx+1);
    
        streamid_map[idx] = parse_number_or_die(opt, p, OPT_INT, 0, INT_MAX);
    
    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));
    
            ffmpeg_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);
    
                ffmpeg_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",
    
                ffmpeg_exit(1);
    
    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);
    
                ffmpeg_exit(1);
    
    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;
    
            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)    new_video_stream(oc, nb_output_files);
            if (use_audio)    new_audio_stream(oc, nb_output_files);
            if (use_subtitle) new_subtitle_stream(oc, nb_output_files);
    
            oc->timestamp = recording_timestamp;
    
            av_metadata_copy(&oc->metadata, metadata, 0);
    
    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);
    
                ffmpeg_exit(1);
    
        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");
    
                            ffmpeg_exit(1);
    
                        fprintf(stderr,"File '%s' already exists. Exiting.\n", filename);
    
                        ffmpeg_exit(1);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                }
            }
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            /* open the file */
    
            if ((err = avio_open(&oc->pb, filename, URL_WRONLY)) < 0) {
    
                ffmpeg_exit(1);
    
    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);
    
            ffmpeg_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;
    
        oc->flags |= AVFMT_FLAG_NONBLOCK;
    
        set_context_opts(oc, avformat_opts, AV_OPT_FLAG_ENCODING_PARAM, NULL);
    
        av_freep(&forced_key_frames);
    
    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");
    
            ffmpeg_exit(1);
    
    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);
    
                ffmpeg_exit(1);
    
    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 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)
    {
    
        AVOutputFormat *oformat = NULL;
    
        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_show2(avcodec_opts[0], NULL, AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM, 0);
    
    
        /* individual codec options */
        c = NULL;
        while ((c = av_codec_next(c))) {
            if (c->priv_class) {
                av_opt_show2(&c->priv_class, NULL, AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM, 0);
                printf("\n");
            }
        }
    
    
        av_opt_show2(avformat_opts, NULL, AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM, 0);
    
    
        /* individual muxer options */
        while ((oformat = av_oformat_next(oformat))) {
            if (oformat->priv_class) {
                av_opt_show2(&oformat->priv_class, NULL, AV_OPT_FLAG_ENCODING_PARAM, 0);
                printf("\n");
            }
        }
    
    
        av_opt_show2(sws_opts, NULL, AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM, 0);
    
    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");
    
            ffmpeg_exit(1);
    
        }
    
        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