Skip to content
Snippets Groups Projects
avconv.c 152 KiB
Newer Older
  • Learn to ignore specific revisions
  •             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");
                exit_program(1);
            }
            opt_programid=0;
        }
    
    
        /* apply forced codec ids */
        for (i = 0; i < ic->nb_streams; i++)
            choose_codec(ic, ic->streams[i], ic->streams[i]->codec->codec_type, codec_names);
    
    
        /* Set AVCodecContext options for avformat_find_stream_info */
        opts = setup_find_stream_info_opts(ic, codec_opts);
        orig_nb_streams = ic->nb_streams;
    
        /* If not enough info to get the stream parameters, we decode the
           first frames to get it. (used in mpeg case for example) */
        ret = avformat_find_stream_info(ic, opts);
        if (ret < 0 && verbose >= 0) {
            fprintf(stderr, "%s: could not find codec parameters\n", filename);
            av_close_input_file(ic);
            exit_program(1);
        }
    
        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);
            if (ret < 0) {
                fprintf(stderr, "%s: could not seek to position %0.3f\n",
                        filename, (double)timestamp / AV_TIME_BASE);
            }
            /* reset seek info */
            start_time = 0;
        }
    
        /* update the current parameters so that they match the one of the input stream */
    
        add_input_streams(ic);
    
    
        /* dump the file content */
        if (verbose >= 0)
            av_dump_format(ic, nb_input_files, filename, 0);
    
        input_files = grow_array(input_files, sizeof(*input_files), &nb_input_files, nb_input_files + 1);
        input_files[nb_input_files - 1].ctx        = ic;
        input_files[nb_input_files - 1].ist_index  = nb_input_streams - ic->nb_streams;
        input_files[nb_input_files - 1].ts_offset  = input_ts_offset - (copy_ts ? 0 : timestamp);
    
        frame_rate    = (AVRational){0, 0};
        frame_pix_fmt = PIX_FMT_NONE;
        frame_height = 0;
        frame_width  = 0;
        audio_sample_rate = 0;
        audio_channels    = 0;
        audio_sample_fmt  = AV_SAMPLE_FMT_NONE;
    
    
        for (i = 0; i < orig_nb_streams; i++)
            av_dict_free(&opts[i]);
        av_freep(&opts);
    
    static void parse_forced_key_frames(char *kf, OutputStream *ost,
                                        AVCodecContext *avctx)
    {
        char *p;
        int n = 1, i;
        int64_t t;
    
        for (p = kf; *p; p++)
            if (*p == ',')
                n++;
        ost->forced_kf_count = n;
        ost->forced_kf_pts = av_malloc(sizeof(*ost->forced_kf_pts) * n);
        if (!ost->forced_kf_pts) {
            av_log(NULL, AV_LOG_FATAL, "Could not allocate forced key frames array.\n");
            exit_program(1);
        }
        for (i = 0; i < n; i++) {
            p = i ? strchr(p, ',') + 1 : kf;
            t = parse_time_or_die("force_key_frames", p, 1);
            ost->forced_kf_pts[i] = av_rescale_q(t, AV_TIME_BASE_Q, avctx->time_base);
        }
    }
    
    
    static OutputStream *new_output_stream(AVFormatContext *oc, enum AVMediaType type)
    
    {
        OutputStream *ost;
        AVStream *st = av_new_stream(oc, oc->nb_streams < nb_streamid_map ? streamid_map[oc->nb_streams] : 0);
        int idx      = oc->nb_streams - 1;
    
        if (!st) {
            av_log(NULL, AV_LOG_ERROR, "Could not alloc stream.\n");
            exit_program(1);
        }
    
    
        output_streams_for_file[nb_output_files] =
            grow_array(output_streams_for_file[nb_output_files],
                       sizeof(*output_streams_for_file[nb_output_files]),
                       &nb_output_streams_for_file[nb_output_files],
    
                       oc->nb_streams);
    
        ost = output_streams_for_file[nb_output_files][idx] =
    
            av_mallocz(sizeof(OutputStream));
        if (!ost) {
            fprintf(stderr, "Could not alloc output stream\n");
            exit_program(1);
        }
    
        ost->file_index = nb_output_files;
    
        ost->index = idx;
        ost->st    = st;
        st->codec->codec_type = type;
        ost->enc = choose_codec(oc, st, type, codec_names);
        if (ost->enc) {
            ost->opts  = filter_codec_opts(codec_opts, ost->enc->id, oc, st);
        }
    
        avcodec_get_context_defaults3(st->codec, ost->enc);
        st->codec->codec_type = type; // XXX hack, avcodec_get_context_defaults2() sets type to unknown for stream copy
    
        ost->sws_flags = av_get_int(sws_opts, "sws_flags", NULL);
        return ost;
    }
    
    
    static OutputStream *new_video_stream(AVFormatContext *oc)
    
    {
        AVStream *st;
        OutputStream *ost;
        AVCodecContext *video_enc;
    
    
        ost = new_output_stream(oc, AVMEDIA_TYPE_VIDEO);
    
            ost->frame_aspect_ratio = frame_aspect_ratio;
            frame_aspect_ratio = 0;
    #if CONFIG_AVFILTER
            ost->avfilter= vfilters;
            vfilters = NULL;
    #endif
        }
    
        ost->bitstream_filters = video_bitstream_filters;
        video_bitstream_filters= NULL;
    
        st->codec->thread_count= thread_count;
    
        video_enc = st->codec;
    
        if(video_codec_tag)
            video_enc->codec_tag= video_codec_tag;
    
        if(oc->oformat->flags & AVFMT_GLOBALHEADER) {
            video_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
        }
    
    
            video_enc->sample_aspect_ratio =
            st->sample_aspect_ratio = av_d2q(frame_aspect_ratio*frame_height/frame_width, 255);
        } else {
            const char *p;
            int i;
    
            if (frame_rate.num)
                ost->frame_rate = frame_rate;
    
            video_enc->width = frame_width;
            video_enc->height = frame_height;
            video_enc->pix_fmt = frame_pix_fmt;
            st->sample_aspect_ratio = video_enc->sample_aspect_ratio;
    
            if (intra_only)
                video_enc->gop_size = 0;
    
            if (video_qscale || same_quant) {
    
                video_enc->flags |= CODEC_FLAG_QSCALE;
                video_enc->global_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");
                    exit_program(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);
        }
        if (video_language) {
            av_dict_set(&st->metadata, "language", video_language, 0);
            av_freep(&video_language);
        }
    
        /* reset some key parameters */
        video_disable = 0;
        av_freep(&forced_key_frames);
        frame_pix_fmt = PIX_FMT_NONE;
    
        return ost;
    
    static OutputStream *new_audio_stream(AVFormatContext *oc)
    
    {
        AVStream *st;
        OutputStream *ost;
        AVCodecContext *audio_enc;
    
    
        ost = new_output_stream(oc, AVMEDIA_TYPE_AUDIO);
    
        st  = ost->st;
    
        ost->bitstream_filters = audio_bitstream_filters;
        audio_bitstream_filters= NULL;
    
        st->codec->thread_count= thread_count;
    
        audio_enc = st->codec;
        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;
        }
    
            if (audio_qscale > QSCALE_NONE) {
                audio_enc->flags |= CODEC_FLAG_QSCALE;
                audio_enc->global_quality = FF_QP2LAMBDA * audio_qscale;
            }
            if (audio_channels)
                audio_enc->channels = audio_channels;
            if (audio_sample_fmt != AV_SAMPLE_FMT_NONE)
                audio_enc->sample_fmt = audio_sample_fmt;
            if (audio_sample_rate)
                audio_enc->sample_rate = audio_sample_rate;
        }
        if (audio_language) {
            av_dict_set(&st->metadata, "language", audio_language, 0);
            av_freep(&audio_language);
        }
    
        /* reset some key parameters */
        audio_disable = 0;
    
    static OutputStream *new_data_stream(AVFormatContext *oc)
    
    {
        AVStream *st;
        OutputStream *ost;
        AVCodecContext *data_enc;
    
    
        ost = new_output_stream(oc, AVMEDIA_TYPE_DATA);
    
        st  = ost->st;
        data_enc = st->codec;
    
            fprintf(stderr, "Data stream encoding not supported yet (only streamcopy)\n");
            exit_program(1);
        }
    
        if (data_codec_tag)
            data_enc->codec_tag= data_codec_tag;
    
        if (oc->oformat->flags & AVFMT_GLOBALHEADER) {
            data_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
        }
    
        data_disable = 0;
    
        return ost;
    
    static OutputStream *new_subtitle_stream(AVFormatContext *oc)
    
    {
        AVStream *st;
        OutputStream *ost;
        AVCodecContext *subtitle_enc;
    
    
        ost = new_output_stream(oc, AVMEDIA_TYPE_SUBTITLE);
    
        st  = ost->st;
        subtitle_enc = st->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;
        }
    
        if (subtitle_language) {
            av_dict_set(&st->metadata, "language", subtitle_language, 0);
            av_freep(&subtitle_language);
        }
    
        subtitle_disable = 0;
    
        return ost;
    
    }
    
    /* 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];
    
        av_strlcpy(idx_str, arg, sizeof(idx_str));
        p = strchr(idx_str, ':');
        if (!p) {
            fprintf(stderr,
                    "Invalid value '%s' for option '%s', required syntax is 'index:value'\n",
                    arg, opt);
            exit_program(1);
        }
        *p++ = '\0';
        idx = parse_number_or_die(opt, idx_str, OPT_INT, 0, INT_MAX);
        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);
        return 0;
    }
    
    
    static int copy_chapters(int infile, int outfile)
    {
        AVFormatContext *is = input_files[infile].ctx;
        AVFormatContext *os = output_files[outfile];
        int i;
    
        for (i = 0; i < is->nb_chapters; i++) {
            AVChapter *in_ch = is->chapters[i], *out_ch;
            int64_t ts_off   = av_rescale_q(start_time - input_files[infile].ts_offset,
                                          AV_TIME_BASE_Q, in_ch->time_base);
            int64_t rt       = (recording_time == INT64_MAX) ? INT64_MAX :
                               av_rescale_q(recording_time, AV_TIME_BASE_Q, in_ch->time_base);
    
    
            if (in_ch->end < ts_off)
                continue;
            if (rt != INT64_MAX && in_ch->start > rt + ts_off)
                break;
    
            out_ch = av_mallocz(sizeof(AVChapter));
            if (!out_ch)
                return AVERROR(ENOMEM);
    
            out_ch->id        = in_ch->id;
            out_ch->time_base = in_ch->time_base;
            out_ch->start     = FFMAX(0,  in_ch->start - ts_off);
            out_ch->end       = FFMIN(rt, in_ch->end   - ts_off);
    
            if (metadata_chapters_autocopy)
                av_dict_copy(&out_ch->metadata, in_ch->metadata, 0);
    
            os->nb_chapters++;
            os->chapters = av_realloc(os->chapters, sizeof(AVChapter)*os->nb_chapters);
            if (!os->chapters)
                return AVERROR(ENOMEM);
            os->chapters[os->nb_chapters - 1] = out_ch;
        }
        return 0;
    }
    
    
    static int read_avserver_streams(AVFormatContext *s, const char *filename)
    {
        int i, err;
        AVFormatContext *ic = NULL;
    
        err = avformat_open_input(&ic, filename, NULL, NULL);
        if (err < 0)
            return err;
        /* copy stream format */
        for(i=0;i<ic->nb_streams;i++) {
            AVStream *st;
            OutputStream *ost;
            AVCodec *codec;
    
            codec = avcodec_find_encoder(ic->streams[i]->codec->codec_id);
    
            ost   = new_output_stream(s, codec->type);
    
            st    = ost->st;
    
            // FIXME: a more elegant solution is needed
            memcpy(st, ic->streams[i], sizeof(AVStream));
            st->info = NULL;
            avcodec_copy_context(st->codec, ic->streams[i]->codec);
    
            if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && !st->stream_copy)
                choose_sample_fmt(st, codec);
            else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && !st->stream_copy)
                choose_pixel_fmt(st, codec);
        }
    
        av_close_input_file(ic);
        return 0;
    }
    
    
    static void opt_output_file(const char *filename)
    {
        AVFormatContext *oc;
    
        int i, err;
    
        AVOutputFormat *file_oformat;
    
        OutputStream *ost;
        InputStream  *ist;
    
    
        if (!strcmp(filename, "-"))
            filename = "pipe:";
    
        oc = avformat_alloc_context();
        if (!oc) {
            print_error(filename, AVERROR(ENOMEM));
            exit_program(1);
        }
    
        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);
                exit_program(1);
            }
            last_asked_format = NULL;
        } else {
            file_oformat = av_guess_format(NULL, filename, NULL);
            if (!file_oformat) {
                fprintf(stderr, "Unable to find a suitable output format for '%s'\n",
                        filename);
                exit_program(1);
            }
        }
    
        oc->oformat = file_oformat;
        av_strlcpy(oc->filename, filename, sizeof(oc->filename));
    
        if (!strcmp(file_oformat->name, "ffm") &&
            av_strstart(filename, "http:", NULL)) {
            /* special case for files sent to avserver: we get the stream
               parameters from avserver */
            int err = read_avserver_streams(oc, filename);
            if (err < 0) {
                print_error(filename, err);
                exit_program(1);
            }
    
        } else if (!nb_stream_maps) {
            /* pick the "best" stream of each type */
    #define NEW_STREAM(type, index)\
            if (index >= 0) {\
    
                ost = new_ ## type ## _stream(oc);\
    
                ost->source_index = index;\
                ost->sync_ist     = &input_streams[index];\
                input_streams[index].discard = 0;\
            }
    
            /* video: highest resolution */
            if (!video_disable && oc->oformat->video_codec != CODEC_ID_NONE) {
                int area = 0, idx = -1;
                for (i = 0; i < nb_input_streams; i++) {
                    ist = &input_streams[i];
                    if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
                        ist->st->codec->width * ist->st->codec->height > area) {
                        area = ist->st->codec->width * ist->st->codec->height;
                        idx = i;
                    }
                }
                NEW_STREAM(video, idx);
            }
    
            /* audio: most channels */
            if (!audio_disable && oc->oformat->audio_codec != CODEC_ID_NONE) {
                int channels = 0, idx = -1;
                for (i = 0; i < nb_input_streams; i++) {
                    ist = &input_streams[i];
                    if (ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
                        ist->st->codec->channels > channels) {
                        channels = ist->st->codec->channels;
                        idx = i;
                    }
                }
                NEW_STREAM(audio, idx);
            }
    
            /* subtitles: pick first */
            if (!subtitle_disable && oc->oformat->subtitle_codec != CODEC_ID_NONE) {
                for (i = 0; i < nb_input_streams; i++)
                    if (input_streams[i].st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
                        NEW_STREAM(subtitle, i);
                        break;
                    }
            }
            /* do something with data? */
    
            for (i = 0; i < nb_stream_maps; i++) {
                StreamMap *map = &stream_maps[i];
    
    
                if (map->disabled)
                    continue;
    
                ist = &input_streams[input_files[map->file_index].ist_index + map->stream_index];
    
                switch (ist->st->codec->codec_type) {
    
                case AVMEDIA_TYPE_VIDEO:    ost = new_video_stream(oc);    break;
                case AVMEDIA_TYPE_AUDIO:    ost = new_audio_stream(oc);    break;
                case AVMEDIA_TYPE_SUBTITLE: ost = new_subtitle_stream(oc); break;
                case AVMEDIA_TYPE_DATA:     ost = new_data_stream(oc);     break;
    
                default:
                    av_log(NULL, AV_LOG_ERROR, "Cannot map stream #%d.%d - unsupported type.\n",
                           map->file_index, map->stream_index);
                    exit_program(1);
                }
    
    
                ost->source_index = input_files[map->file_index].ist_index + map->stream_index;
    
                ost->sync_ist = &input_streams[input_files[map->sync_file_index].ist_index +
                                               map->sync_stream_index];
                ist->discard = 0;
            }
    
        av_dict_copy(&oc->metadata, metadata, 0);
        av_dict_free(&metadata);
    
    
        av_dict_copy(&output_opts[nb_output_files], format_opts, 0);
        output_files[nb_output_files++] = oc;
    
        /* check filename in case of an image number is expected */
        if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
            if (!av_filename_number_test(oc->filename)) {
                print_error(oc->filename, AVERROR(EINVAL));
                exit_program(1);
            }
        }
    
        if (!(oc->oformat->flags & AVFMT_NOFILE)) {
            /* test if it already exists to avoid loosing precious files */
            if (!file_overwrite &&
                (strchr(filename, ':') == NULL ||
                 filename[1] == ':' ||
                 av_strstart(filename, "file:", NULL))) {
                if (avio_check(filename, 0) == 0) {
                    if (!using_stdin) {
                        fprintf(stderr,"File '%s' already exists. Overwrite ? [y/N] ", filename);
                        fflush(stderr);
                        if (!read_yesno()) {
                            fprintf(stderr, "Not overwriting - exiting\n");
                            exit_program(1);
                        }
                    }
                    else {
                        fprintf(stderr,"File '%s' already exists. Exiting.\n", filename);
                        exit_program(1);
                    }
                }
            }
    
            /* open the file */
            if ((err = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE)) < 0) {
                print_error(filename, err);
                exit_program(1);
            }
        }
    
        oc->preload= (int)(mux_preload*AV_TIME_BASE);
        oc->max_delay= (int)(mux_max_delay*AV_TIME_BASE);
        oc->flags |= AVFMT_FLAG_NONBLOCK;
    
    
        /* copy chapters */
        if (chapters_input_file >= nb_input_files) {
            if (chapters_input_file == INT_MAX) {
                /* copy chapters from the first input file that has them*/
                chapters_input_file = -1;
                for (i = 0; i < nb_input_files; i++)
                    if (input_files[i].ctx->nb_chapters) {
                        chapters_input_file = i;
                        break;
                    }
            } else {
                av_log(NULL, AV_LOG_ERROR, "Invalid input file index %d in chapter mapping.\n",
                       chapters_input_file);
                exit_program(1);
            }
        }
        if (chapters_input_file >= 0)
            copy_chapters(chapters_input_file, nb_output_files - 1);
    
    
        /* copy metadata */
        for (i = 0; i < nb_meta_data_maps; i++) {
            AVFormatContext *files[2];
            AVDictionary    **meta[2];
            int j;
    
    #define METADATA_CHECK_INDEX(index, nb_elems, desc)\
            if ((index) < 0 || (index) >= (nb_elems)) {\
                av_log(NULL, AV_LOG_ERROR, "Invalid %s index %d while processing metadata maps\n",\
                         (desc), (index));\
                exit_program(1);\
            }
    
            int in_file_index = meta_data_maps[i][1].file;
            if (in_file_index < 0)
                continue;
            METADATA_CHECK_INDEX(in_file_index, nb_input_files, "input file")
    
            files[0] = oc;
            files[1] = input_files[in_file_index].ctx;
    
            for (j = 0; j < 2; j++) {
                MetadataMap *map = &meta_data_maps[i][j];
    
                switch (map->type) {
                case 'g':
                    meta[j] = &files[j]->metadata;
                    break;
                case 's':
                    METADATA_CHECK_INDEX(map->index, files[j]->nb_streams, "stream")
                    meta[j] = &files[j]->streams[map->index]->metadata;
                    break;
                case 'c':
                    METADATA_CHECK_INDEX(map->index, files[j]->nb_chapters, "chapter")
                    meta[j] = &files[j]->chapters[map->index]->metadata;
                    break;
                case 'p':
                    METADATA_CHECK_INDEX(map->index, files[j]->nb_programs, "program")
                    meta[j] = &files[j]->programs[map->index]->metadata;
                    break;
                }
            }
    
            av_dict_copy(meta[0], *meta[1], AV_DICT_DONT_OVERWRITE);
        }
    
        /* copy global metadata by default */
    
        if (metadata_global_autocopy && nb_input_files)
    
            av_dict_copy(&oc->metadata, input_files[0].ctx->metadata,
                         AV_DICT_DONT_OVERWRITE);
        if (metadata_streams_autocopy)
            for (i = 0; i < oc->nb_streams; i++) {
                InputStream *ist = &input_streams[output_streams_for_file[nb_output_files-1][i]->source_index];
                av_dict_copy(&oc->streams[i]->metadata, ist->st->metadata, AV_DICT_DONT_OVERWRITE);
            }
    
    
        frame_rate    = (AVRational){0, 0};
        frame_width   = 0;
        frame_height  = 0;
        audio_sample_rate = 0;
        audio_channels    = 0;
        audio_sample_fmt  = AV_SAMPLE_FMT_NONE;
    
        chapters_input_file = INT_MAX;
    
        av_freep(&meta_data_maps);
        nb_meta_data_maps = 0;
        metadata_global_autocopy   = 1;
        metadata_streams_autocopy  = 1;
        metadata_chapters_autocopy = 1;
    
        av_freep(&stream_maps);
        nb_stream_maps = 0;
    
        av_freep(&forced_key_frames);
        uninit_opts();
        init_opts();
    }
    
    /* same option as mencoder */
    static int opt_pass(const char *opt, const char *arg)
    {
        do_pass = parse_number_or_die(opt, arg, OPT_INT, 1, 2);
        return 0;
    }
    
    static int64_t getutime(void)
    {
    #if HAVE_GETRUSAGE
        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
        return av_gettime();
    #endif
    }
    
    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);
                exit_program(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 show_usage(void)
    {
        printf("Hyper fast Audio and Video encoder\n");
        printf("usage: %s [options] [[infile options] -i infile]... {[outfile options] outfile}...\n", program_name);
        printf("\n");
    }
    
    static void show_help(void)
    {
        AVCodec *c;
        AVOutputFormat *oformat = NULL;
        AVInputFormat  *iformat = 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);
        printf("\n");
        av_opt_show2(avcodec_opts[0], NULL, AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM, 0);
        printf("\n");
    
        /* 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);
        printf("\n");
    
        /* 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");
            }
        }
    
        /* individual demuxer options */
        while ((iformat = av_iformat_next(iformat))) {
            if (iformat->priv_class) {
                av_opt_show2(&iformat->priv_class, NULL, AV_OPT_FLAG_DECODING_PARAM, 0);
                printf("\n");
            }
        }
    
        av_opt_show2(sws_opts, NULL, AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM, 0);
    }
    
    static int opt_target(const char *opt, const char *arg)
    {
        enum { PAL, NTSC, FILM, UNKNOWN } norm = UNKNOWN;
        static const char *const frame_rates[] = {"25", "30000/1001", "24000/1001"};
    
        if(!strncmp(arg, "pal-", 4)) {
            norm = PAL;
            arg += 4;
        } else if(!strncmp(arg, "ntsc-", 5)) {
            norm = NTSC;
            arg += 5;
        } else if(!strncmp(arg, "film-", 5)) {
            norm = FILM;
            arg += 5;
        } else {
            int fr;
            /* Calculate FR via float to avoid int overflow */
            fr = (int)(frame_rate.num * 1000.0 / frame_rate.den);
            if(fr == 25000) {
                norm = PAL;
            } else if((fr == 29970) || (fr == 23976)) {
                norm = NTSC;
            } 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].ctx->nb_streams; i++) {
                            AVCodecContext *c = input_files[j].ctx->streams[i]->codec;
                            if(c->codec_type != AVMEDIA_TYPE_VIDEO)
                                continue;
                            fr = c->time_base.den * 1000 / c->time_base.num;
                            if(fr == 25000) {
                                norm = PAL;
                                break;
                            } else if((fr == 29970) || (fr == 23976)) {
                                norm = NTSC;
                                break;
                            }
                        }
                        if(norm != UNKNOWN)
                            break;
                    }
                }
            }
            if(verbose > 0 && norm != UNKNOWN)
                fprintf(stderr, "Assuming %s for target.\n", norm == PAL ? "PAL" : "NTSC");
        }
    
        if(norm == UNKNOWN) {
            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_program(1);
        }
    
        if(!strcmp(arg, "vcd")) {
    
            opt_codec("c:v", "mpeg1video");
            opt_codec("c:a", "mp2");
    
            opt_format("f", "vcd");
    
            opt_frame_size("s", norm == PAL ? "352x288" : "352x240");
            opt_frame_rate("r", frame_rates[norm]);
            opt_default("g", norm == PAL ? "15" : "18");
    
            opt_default("b", "1150000");
            opt_default("maxrate", "1150000");
            opt_default("minrate", "1150000");
            opt_default("bufsize", "327680"); // 40*1024*8;
    
    
            opt_default("b:a", "224000");
    
            audio_sample_rate = 44100;
            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_codec("c:v", "mpeg2video");
            opt_codec("c:a", "mp2");
    
            opt_format("f", "svcd");
    
            opt_frame_size("s", norm == PAL ? "480x576" : "480x480");
            opt_frame_rate("r", frame_rates[norm]);
            opt_default("g", norm == PAL ? "15" : "18");
    
            opt_default("b", "2040000");
            opt_default("maxrate", "2516000");
            opt_default("minrate", "0"); //1145000;
            opt_default("bufsize", "1835008"); //224*1024*8;
            opt_default("flags", "+scan_offset");
    
    
    
            opt_default("b:a", "224000");
    
            audio_sample_rate = 44100;
    
            opt_default("packetsize", "2324");
    
        } else if(!strcmp(arg, "dvd")) {
    
    
            opt_codec("c:v", "mpeg2video");
            opt_codec("c:a", "ac3");
    
            opt_format("f", "dvd");
    
            opt_frame_size("vcodec", norm == PAL ? "720x576" : "720x480");
            opt_frame_rate("r", frame_rates[norm]);
            opt_default("g", norm == PAL ? "15" : "18");
    
            opt_default("b", "6000000");
            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_default("b:a", "448000");
    
            audio_sample_rate = 48000;
    
        } else if(!strncmp(arg, "dv", 2)) {
    
            opt_format("f", "dv");
    
            opt_frame_size("s", norm == PAL ? "720x576" : "720x480");
            opt_frame_pix_fmt("pix_fmt", !strncmp(arg, "dv50", 4) ? "yuv422p" :
                              norm == PAL ? "yuv420p" : "yuv411p");
            opt_frame_rate("r", frame_rates[norm]);
    
            audio_sample_rate = 48000;
            audio_channels = 2;
    
        } else {
            fprintf(stderr, "Unknown target: %s\n", arg);