Skip to content
Snippets Groups Projects
ffmpeg.c 111 KiB
Newer Older
  • Learn to ignore specific revisions
  • static void opt_packet_size(const char *arg)
    
    static void opt_error_rate(const char *arg)
    {
        error_rate= atoi(arg);
    }
    
    
    static void opt_strict(const char *arg)
    
    {
        strict= atoi(arg);
    }
    
    
    static void opt_top_field_first(const char *arg)
    {
        top_field_first= atoi(arg);
    }
    
    static void opt_noise_reduction(const char *arg)
    {
        noise_reduction= atoi(arg);
    }
    
    
    static void opt_qns(const char *arg)
    {
        qns= atoi(arg);
    }
    
    
    static void opt_sc_threshold(const char *arg)
    {
        sc_threshold= atoi(arg);
    }
    
    
    static void opt_thread_count(const char *arg)
    {
        thread_count= atoi(arg);
    
    #if !defined(HAVE_PTHREADS) && !defined(HAVE_W32THREADS)
    
        fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
    #endif
    
    static void opt_audio_bitrate(const char *arg)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
        audio_bit_rate = atoi(arg) * 1000;
    }
    
    
    static void opt_audio_rate(const char *arg)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
        audio_sample_rate = atoi(arg);
    }
    
    
    static void opt_audio_channels(const char *arg)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
        audio_channels = atoi(arg);
    }
    
    
    static void opt_video_device(const char *arg)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        video_device = av_strdup(arg);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    }
    
    
    static void opt_video_channel(const char *arg)
    
    static void opt_video_standard(const char *arg)
    {
        video_standard = av_strdup(arg);
    }
    
    
    static void opt_audio_device(const char *arg)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        audio_device = av_strdup(arg);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    }
    
    
    static void opt_dv1394(const char *arg)
    
    {
        video_grab_format = "dv1394";
    
        audio_grab_format = NULL;
    
    static void opt_audio_codec(const char *arg)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
        AVCodec *p;
    
    
        if (!strcmp(arg, "copy")) {
            audio_stream_copy = 1;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        } else {
    
            p = first_avcodec;
            while (p) {
                if (!strcmp(p->name, arg) && p->type == CODEC_TYPE_AUDIO)
                    break;
                p = p->next;
            }
            if (p == NULL) {
                fprintf(stderr, "Unknown audio codec '%s'\n", arg);
                exit(1);
            } else {
                audio_codec_id = p->id;
            }
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        }
    }
    
    
    static void add_frame_hooker(const char *arg)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        char *args = av_strdup(arg);
    
        argv[0] = strtok(args, " ");
        while (argc < 62 && (argv[++argc] = strtok(NULL, " "))) {
        }
    
        i = frame_hook_add(argc, argv);
    
        if (i != 0) {
            fprintf(stderr, "Failed to add video hook function: %s\n", arg);
            exit(1);
        }
    }
    
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    const char *motion_str[] = {
        "zero",
        "full",
        "log",
        "phods",
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        "epzs",
        "x1",
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        NULL,
    };
    
    
    static void opt_motion_estimation(const char *arg)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
        const char **p;
        p = motion_str;
        for(;;) {
            if (!*p) {
                fprintf(stderr, "Unknown motion estimation method '%s'\n", arg);
                exit(1);
            }
            if (!strcmp(*p, arg))
                break;
            p++;
        }
    
        me_method = (p - motion_str) + 1;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    }
    
    
    static void opt_video_codec(const char *arg)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
        AVCodec *p;
    
    
        if (!strcmp(arg, "copy")) {
            video_stream_copy = 1;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        } else {
    
            p = first_avcodec;
            while (p) {
                if (!strcmp(p->name, arg) && p->type == CODEC_TYPE_VIDEO)
                    break;
                p = p->next;
            }
            if (p == NULL) {
                fprintf(stderr, "Unknown video codec '%s'\n", arg);
                exit(1);
            } else {
                video_codec_id = p->id;
            }
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        }
    }
    
    
    static void opt_map(const char *arg)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
        AVStreamMap *m;
        const char *p;
    
        p = arg;
        m = &stream_maps[nb_stream_maps++];
    
        m->file_index = strtol(arg, (char **)&p, 0);
        if (*p)
            p++;
    
    Juanjo's avatar
    Juanjo committed
    
        m->stream_index = strtol(p, (char **)&p, 0);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    }
    
    
    static void opt_recording_time(const char *arg)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
        recording_time = parse_date(arg, 1);
    }
    
    
    static void opt_start_time(const char *arg)
    {
        start_time = parse_date(arg, 1);
    }
    
    
    static void opt_input_file(const char *filename)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
        AVFormatContext *ic;
        AVFormatParameters params, *ap = &params;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
        if (!strcmp(filename, "-"))
            filename = "pipe:";
    
    
        using_stdin |= !strcmp(filename, "pipe:" ) || 
                       !strcmp( filename, "/dev/stdin" );
    
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        /* get default parameters from command line */
    
        memset(ap, 0, sizeof(*ap));
        ap->sample_rate = audio_sample_rate;
        ap->channels = audio_channels;
        ap->frame_rate = frame_rate;
    
        ap->width = frame_width;
        ap->height = frame_height;
    
        ap->pix_fmt = frame_pix_fmt;
    
    
        /* 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
            exit(1);
        }
        
    
        /* 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);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        if (ret < 0) {
            fprintf(stderr, "%s: could not find codec parameters\n", filename);
            exit(1);
        }
    
    
        /* if seeking requested, we execute it */
        if (start_time != 0) {
            int64_t timestamp;
    
            timestamp = start_time;
            /* add the stream start time */
            if (ic->start_time != AV_NOPTS_VALUE)
                timestamp += ic->start_time;
            ret = av_seek_frame(ic, -1, timestamp);
            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;
        }
    
    
    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++) {
            AVCodecContext *enc = &ic->streams[i]->codec;
    
    #if defined(HAVE_PTHREADS) || defined(HAVE_W32THREADS)
            if(thread_count>1)
                avcodec_thread_init(enc, thread_count);
    #endif
            enc->thread_count= thread_count;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            switch(enc->codec_type) {
            case CODEC_TYPE_AUDIO:
    
                //fprintf(stderr, "\nInput Audio channels: %d", enc->channels);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                audio_channels = enc->channels;
                audio_sample_rate = enc->sample_rate;
                break;
            case CODEC_TYPE_VIDEO:
                frame_height = enc->height;
                frame_width = enc->width;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    	    frame_aspect_ratio = av_q2d(enc->sample_aspect_ratio) * enc->width / enc->height;
    
    	    frame_pix_fmt = enc->pix_fmt;
    
                rfps      = ic->streams[i]->r_frame_rate;
                rfps_base = ic->streams[i]->r_frame_rate_base;
    
                enc->error_resilience = error_resilience; 
    
                enc->error_concealment = error_concealment; 
    
                enc->idct_algo = idct_algo;
                enc->debug = debug;
                enc->debug_mv = debug_mv;            
    
                if(bitexact)
                    enc->flags|= CODEC_FLAG_BITEXACT;
    
                assert(enc->frame_rate_base == rfps_base); // should be true for now
                if (enc->frame_rate != rfps) { 
    
                    fprintf(stderr,"\nSeems that stream %d comes from film source: %2.2f->%2.2f\n",
    
                        i, (float)enc->frame_rate / enc->frame_rate_base,
                        (float)rfps / rfps_base);
    
                /* update the current frame rate to match the stream frame rate */
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                break;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            }
        }
        
        input_files[nb_input_files] = ic;
        /* dump the file content */
        dump_format(ic, nb_input_files, filename, 0);
        nb_input_files++;
    
        file_iformat = NULL;
        file_oformat = NULL;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    }
    
    
    static void check_audio_video_inputs(int *has_video_ptr, int *has_audio_ptr)
    
    {
        int has_video, has_audio, i, j;
        AVFormatContext *ic;
    
        has_video = 0;
        has_audio = 0;
        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;
                switch(enc->codec_type) {
                case CODEC_TYPE_AUDIO:
                    has_audio = 1;
                    break;
                case CODEC_TYPE_VIDEO:
                    has_video = 1;
                    break;
    
    static void opt_output_file(const char *filename)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
        AVStream *st;
        AVFormatContext *oc;
    
        int use_video, use_audio, nb_streams, input_has_video, input_has_audio;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        int codec_id;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
        if (!strcmp(filename, "-"))
            filename = "pipe:";
    
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
        if (!file_oformat) {
            file_oformat = guess_format(NULL, filename, NULL);
            if (!file_oformat) {
                fprintf(stderr, "Unable for find a suitable output format for '%s'\n",
                        filename);
                exit(1);
            }
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        }
        
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
        if (!strcmp(file_oformat->name, "ffm") && 
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            strstart(filename, "http:", NULL)) {
            /* special case for files sent to ffserver: we get the stream
               parameters from ffserver */
            if (read_ffserver_streams(oc, filename) < 0) {
                fprintf(stderr, "Could not read stream parameters from '%s'\n", filename);
                exit(1);
            }
        } else {
    
            use_video = file_oformat->video_codec != CODEC_ID_NONE;
            use_audio = file_oformat->audio_codec != CODEC_ID_NONE;
    
            /* disable if no corresponding type found and at least one
               input file */
            if (nb_input_files > 0) {
                check_audio_video_inputs(&input_has_video, &input_has_audio);
                if (!input_has_video)
                    use_video = 0;
                if (!input_has_audio)
                    use_audio = 0;
            }
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            if (audio_disable) {
                use_audio = 0;
            }
            if (video_disable) {
                use_video = 0;
            }
            
            nb_streams = 0;
            if (use_video) {
                AVCodecContext *video_enc;
                
                st = av_mallocz(sizeof(AVStream));
                if (!st) {
                    fprintf(stderr, "Could not alloc stream\n");
                    exit(1);
                }
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                avcodec_get_context_defaults(&st->codec);
    
    #if defined(HAVE_PTHREADS) || defined(HAVE_W32THREADS)
    
                if(thread_count>1)
    
                    avcodec_thread_init(&st->codec, thread_count);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
                
                if(!strcmp(file_oformat->name, "mp4") || !strcmp(file_oformat->name, "mov") || !strcmp(file_oformat->name, "3gp"))
                    video_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
    
                if (video_stream_copy) {
                    st->stream_copy = 1;
                    video_enc->codec_type = CODEC_TYPE_VIDEO;
                } else {
    
                    codec_id = file_oformat->video_codec;
                    if (video_codec_id != CODEC_ID_NONE)
                        codec_id = video_codec_id;
                    
                    video_enc->codec_id = codec_id;
                    
                    video_enc->bit_rate = video_bit_rate;
                    video_enc->bit_rate_tolerance = video_bit_rate_tolerance;
                    video_enc->frame_rate = frame_rate; 
    
                    
                    video_enc->width = frame_width;
                    video_enc->height = frame_height;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    		video_enc->sample_aspect_ratio = av_d2q(frame_aspect_ratio*frame_height/frame_width, 255);
    
    		video_enc->pix_fmt = frame_pix_fmt;
    
    
                    if (!intra_only)
                        video_enc->gop_size = gop_size;
                    else
                        video_enc->gop_size = 0;
                    if (video_qscale || same_quality) {
                        video_enc->flags |= CODEC_FLAG_QSCALE;
    
                        st->quality = FF_QP2LAMBDA * video_qscale;
    
    
                    if(intra_matrix)
                        video_enc->intra_matrix = intra_matrix;
                    if(inter_matrix)
                        video_enc->inter_matrix = inter_matrix;
    
    
                    if(bitexact)
                        video_enc->flags |= CODEC_FLAG_BITEXACT;
    
    
                    video_enc->mb_decision = mb_decision;
    
                    video_enc->ildct_cmp = ildct_cmp;
    
                    video_enc->me_sub_cmp = sub_cmp;
                    video_enc->me_cmp = cmp;
    
                    video_enc->me_pre_cmp = pre_cmp;
                    video_enc->pre_me = pre_me;
                    video_enc->lumi_masking = lumi_mask;
                    video_enc->dark_masking = dark_mask;
                    video_enc->spatial_cplx_masking = scplx_mask;
                    video_enc->temporal_cplx_masking = tcplx_mask;
                    video_enc->p_masking = p_mask;
    
                    video_enc->quantizer_noise_shaping= qns;
    
                    if (use_umv) {
                        video_enc->flags |= CODEC_FLAG_H263P_UMV;
                    }
               	if (use_aic) {
                        video_enc->flags |= CODEC_FLAG_H263P_AIC;
                    }
    
               	if (use_aiv) {
                        video_enc->flags |= CODEC_FLAG_H263P_AIV;
                    }
    
                    if (use_4mv) {
                        video_enc->flags |= CODEC_FLAG_4MV;
                    }
    
                    if (use_obmc) {
                        video_enc->flags |= CODEC_FLAG_OBMC;
                    }
                
    
                        video_enc->flags |= CODEC_FLAG_PART;
    
               	if (use_alt_scan) {
                        video_enc->flags |= CODEC_FLAG_ALT_SCAN;
                    }
    
               	if (use_trell) {
                        video_enc->flags |= CODEC_FLAG_TRELLIS_QUANT;
                    }
    
               	if (use_scan_offset) {
                        video_enc->flags |= CODEC_FLAG_SVCD_SCAN_OFFSET;
                    }
    
               	if (closed_gop) {
                        video_enc->flags |= CODEC_FLAG_CLOSED_GOP;
                    }
    
                    if (b_frames) {
                        video_enc->max_b_frames = b_frames;
                        video_enc->b_frame_strategy = 0;
                        video_enc->b_quant_factor = 2.0;
    
                    if (do_interlace_dct) {
    
                        video_enc->flags |= CODEC_FLAG_INTERLACED_DCT;
                    }
    
                    if (do_interlace_me) {
                        video_enc->flags |= CODEC_FLAG_INTERLACED_ME;
                    }
    
                    video_enc->qmin = video_qmin;
                    video_enc->qmax = video_qmax;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                    video_enc->mb_qmin = video_mb_qmin;
                    video_enc->mb_qmax = video_mb_qmax;
    
                    video_enc->max_qdiff = video_qdiff;
                    video_enc->qblur = video_qblur;
                    video_enc->qcompress = video_qcomp;
                    video_enc->rc_eq = video_rc_eq;
    
                    video_enc->debug_mv = debug_mv;
                    video_enc->thread_count = thread_count;
    
                    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(1);
                        }
                        video_enc->rc_override= 
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                            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;
    
    
                    video_enc->rc_max_rate = video_rc_max_rate;
                    video_enc->rc_min_rate = video_rc_min_rate;
                    video_enc->rc_buffer_size = video_rc_buffer_size;
                    video_enc->rc_buffer_aggressivity= video_rc_buffer_aggressivity;
    
                    video_enc->rc_initial_cplx= video_rc_initial_cplx;
    
                    video_enc->i_quant_factor = video_i_qfactor;
                    video_enc->b_quant_factor = video_b_qfactor;
                    video_enc->i_quant_offset = video_i_qoffset;
                    video_enc->b_quant_offset = video_b_qoffset;
    
                    video_enc->intra_quant_bias = video_intra_quant_bias;
                    video_enc->inter_quant_bias = video_inter_quant_bias;
    
                    video_enc->dct_algo = dct_algo;
                    video_enc->idct_algo = idct_algo;
    
                    video_enc->strict_std_compliance = strict;
    
                    video_enc->error_rate = error_rate;
    
                    video_enc->noise_reduction= noise_reduction;
    
                    video_enc->scenechange_threshold= sc_threshold;
    
                    if(packet_size){
                        video_enc->rtp_mode= 1;
                        video_enc->rtp_payload_size= packet_size;
                    }
    
                        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;
                        }
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                oc->streams[nb_streams] = st;
                nb_streams++;
            }
        
            if (use_audio) {
                AVCodecContext *audio_enc;
    
                st = av_mallocz(sizeof(AVStream));
                if (!st) {
                    fprintf(stderr, "Could not alloc stream\n");
                    exit(1);
                }
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                avcodec_get_context_defaults(&st->codec);
    
    #if defined(HAVE_PTHREADS) || defined(HAVE_W32THREADS)
    
                if(thread_count>1)
    
                    avcodec_thread_init(&st->codec, thread_count);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                audio_enc = &st->codec;
                audio_enc->codec_type = CODEC_TYPE_AUDIO;
    
    
                if(!strcmp(file_oformat->name, "mp4") || !strcmp(file_oformat->name, "mov") || !strcmp(file_oformat->name, "3gp"))
                    audio_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
    
                if (audio_stream_copy) {
                    st->stream_copy = 1;
                } else {
                    codec_id = file_oformat->audio_codec;
                    if (audio_codec_id != CODEC_ID_NONE)
                        codec_id = audio_codec_id;
                    audio_enc->codec_id = codec_id;
                    
                    audio_enc->bit_rate = audio_bit_rate;
                    audio_enc->sample_rate = audio_sample_rate;
    
                    audio_enc->strict_std_compliance = strict;
    
                    audio_enc->thread_count = thread_count;
    
                    /* For audio codecs other than AC3 we limit */
                    /* the number of coded channels to stereo   */
                    if (audio_channels > 2 && codec_id != CODEC_ID_AC3) {
                        audio_enc->channels = 2;
                    } else
                        audio_enc->channels = audio_channels;
                }
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                oc->streams[nb_streams] = st;
                nb_streams++;
            }
    
            oc->nb_streams = nb_streams;
    
            if (!nb_streams) {
    
                fprintf(stderr, "No audio or video streams available\n");
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                exit(1);
            }
    
            if (str_title)
    
                pstrcpy(oc->title, sizeof(oc->title), str_title);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            if (str_author)
    
                pstrcpy(oc->author, sizeof(oc->author), str_author);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            if (str_copyright)
    
                pstrcpy(oc->copyright, sizeof(oc->copyright), str_copyright);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            if (str_comment)
    
                pstrcpy(oc->comment, sizeof(oc->comment), str_comment);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        }
    
    
        output_files[nb_output_files++] = oc;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
        strcpy(oc->filename, filename);
    
    
        /* check filename in case of an image number is expected */
    
        if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
            if (filename_number_test(oc->filename) < 0) {
                print_error(oc->filename, AVERROR_NUMEXPECTED);
    
        if (!(oc->oformat->flags & AVFMT_NOFILE)) {
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            /* test if it already exists to avoid loosing precious files */
            if (!file_overwrite && 
                (strchr(filename, ':') == NULL ||
                 strstart(filename, "file:", NULL))) {
                if (url_exist(filename)) {
                    int c;
                    
    
                    if ( !using_stdin ) {
                        fprintf(stderr,"File '%s' already exists. Overwrite ? [y/N] ", filename);
                        fflush(stderr);
                        c = getchar();
                        if (toupper(c) != 'Y') {
                            fprintf(stderr, "Not overwriting - exiting\n");
                            exit(1);
                        }
    				}
    				else {
                        fprintf(stderr,"File '%s' already exists. Exiting.\n", filename);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                        exit(1);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                }
            }
            
            /* open the file */
            if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0) {
                fprintf(stderr, "Could not open '%s'\n", filename);
                exit(1);
            }
        }
    
    
        memset(ap, 0, sizeof(*ap));
        ap->image_format = image_format;
        if (av_set_parameters(oc, ap) < 0) {
            fprintf(stderr, "%s: Invalid encoding parameters\n",
                    oc->filename);
            exit(1);
        }
    
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        /* reset some options */
    
        file_oformat = NULL;
        file_iformat = NULL;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        audio_disable = 0;
        video_disable = 0;
        audio_codec_id = CODEC_ID_NONE;
        video_codec_id = CODEC_ID_NONE;
    
        audio_stream_copy = 0;
        video_stream_copy = 0;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    }
    
    
    /* prepare dummy protocols for grab */
    
    static void prepare_grab(void)
    
    {
        int has_video, has_audio, i, j;
        AVFormatContext *oc;
        AVFormatContext *ic;
    
        /* see if audio/video inputs are needed */
        has_video = 0;
        has_audio = 0;
        memset(ap, 0, sizeof(*ap));
    
        for(j=0;j<nb_output_files;j++) {
            oc = output_files[j];
            for(i=0;i<oc->nb_streams;i++) {
                AVCodecContext *enc = &oc->streams[i]->codec;
                switch(enc->codec_type) {
                case CODEC_TYPE_AUDIO:
                    if (enc->sample_rate > ap->sample_rate)
                        ap->sample_rate = enc->sample_rate;
                    if (enc->channels > ap->channels)
                        ap->channels = enc->channels;
                    has_audio = 1;
                    break;
                case CODEC_TYPE_VIDEO:
    
                    if (enc->width > vp->width)
                        vp->width = enc->width;
                    if (enc->height > vp->height)
                        vp->height = enc->height;
    
                    
                    assert(enc->frame_rate_base == DEFAULT_FRAME_RATE_BASE);
                    if (enc->frame_rate > vp->frame_rate){
                        vp->frame_rate      = enc->frame_rate;
                        vp->frame_rate_base = enc->frame_rate_base;
                    }
    
                }
            }
        }
        
        if (has_video == 0 && has_audio == 0) {
            fprintf(stderr, "Output file must have at least one audio or video stream\n");
            exit(1);
        }
        
        if (has_video) {
    
            fmt1 = av_find_input_format(video_grab_format);
    
    	vp->standard = video_standard;
    
            if (av_open_input_file(&ic, "", fmt1, 0, vp) < 0) {
    
                fprintf(stderr, "Could not find video grab device\n");
    
            /* If not enough info to get the stream parameters, we decode the
               first frames to get it. */
    	if ((ic->ctx_flags & AVFMTCTX_NOHEADER) && av_find_stream_info(ic) < 0) {
                fprintf(stderr, "Could not find video grab parameters\n");
                exit(1);
            }
    
            /* by now video grab has one stream */
    
            ic->streams[0]->r_frame_rate      = vp->frame_rate;
            ic->streams[0]->r_frame_rate_base = vp->frame_rate_base;
    
        if (has_audio && audio_grab_format) {
    
            fmt1 = av_find_input_format(audio_grab_format);
    
            if (av_open_input_file(&ic, "", fmt1, 0, ap) < 0) {
    
                fprintf(stderr, "Could not find audio grab device\n");
    
    /* same option as mencoder */
    
    static void opt_pass(const char *pass_str)
    
    {
        int pass;
        pass = atoi(pass_str);
        if (pass != 1 && pass != 2) {
            fprintf(stderr, "pass number can be only 1 or 2\n");
            exit(1);
        }
        do_pass = pass;
    }
    
    #if defined(CONFIG_WIN32) || defined(CONFIG_OS2)
    
    static int64_t getutime(void)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    #else
    
    static int64_t getutime(void)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
    
        struct rusage rusage;
    
        getrusage(RUSAGE_SELF, &rusage);
        return (rusage.ru_utime.tv_sec * 1000000LL) + rusage.ru_utime.tv_usec;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    }
    #endif
    
    static void opt_bitexact(void)
    
        /* disable generate of real time pts in ffm (need to be supressed anyway) */
        ffm_nopts = 1;
    }
    
    
    static void show_formats(void)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
    
        AVInputFormat *ifmt;
        AVOutputFormat *ofmt;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        URLProtocol *up;
    
        AVCodec *p, *p2;
        const char **pp, *last_name;
    
        printf("File formats:\n");
        last_name= "000";
        for(;;){
            int decode=0;
            int encode=0;
            const char *name=NULL;
    
            for(ofmt = first_oformat; ofmt != NULL; ofmt = ofmt->next) {
                if((name == NULL || strcmp(ofmt->name, name)<0) &&
                    strcmp(ofmt->name, last_name)>0){
                    name= ofmt->name;
                    encode=1;
                }
            }
            for(ifmt = first_iformat; ifmt != NULL; ifmt = ifmt->next) {
                if((name == NULL || strcmp(ifmt->name, name)<0) &&
                    strcmp(ifmt->name, last_name)>0){
                    name= ifmt->name;
                    encode=0;
                }
                if(name && strcmp(ifmt->name, name)==0)
                    decode=1;
            }
            if(name==NULL)
                break;
            last_name= name;
            
            printf(
                " %s%s %s\n", 
                decode ? "D":" ", 
                encode ? "E":" ", 
                name);
    
        printf("Image formats:\n");
    
        for(image_fmt = first_image_format; image_fmt != NULL; 
            image_fmt = image_fmt->next) {
    
            printf(
                " %s%s %s\n",
                image_fmt->img_read  ? "D":" ",
                image_fmt->img_write ? "E":" ",
                image_fmt->name);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        printf("Codecs:\n");
    
        last_name= "000";
        for(;;){
            int decode=0;
            int encode=0;
            int cap=0;
    
            p2=NULL;
            for(p = first_avcodec; p != NULL; p = p->next) {
                if((p2==NULL || strcmp(p->name, p2->name)<0) &&
                    strcmp(p->name, last_name)>0){
                    p2= p;
                    decode= encode= cap=0;
                }
                if(p2 && strcmp(p->name, p2->name)==0){
                    if(p->decode) decode=1;
                    if(p->encode) encode=1;
                    cap |= p->capabilities;
                }
            }
            if(p2==NULL)
                break;
            last_name= p2->name;
            
            printf(
                " %s%s%s%s%s%s %s", 
                decode ? "D": (/*p2->decoder ? "d":*/" "), 
                encode ? "E":" ", 
                p2->type == CODEC_TYPE_AUDIO ? "A":"V",
                cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S":" ",
                cap & CODEC_CAP_DR1 ? "D":" ",
                cap & CODEC_CAP_TRUNCATED ? "T":" ",
                p2->name);
           /* if(p2->decoder && decode==0)
                printf(" use %s for decoding", p2->decoder->name);*/
            printf("\n");
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        }
        printf("\n");
    
    
        printf("Supported file protocols:\n");
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        for(up = first_protocol; up != NULL; up = up->next)
            printf(" %s:", up->name);
        printf("\n");
        
    
        printf("Frame size, frame rate abbreviations:\n ntsc pal qntsc qpal sntsc spal film ntsc-film sqcif qcif cif 4cif\n");
        printf("Motion estimation methods:\n");
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        pp = motion_str;
        while (*pp) {
            printf(" %s", *pp);
    
            if ((pp - motion_str + 1) == ME_ZERO) 
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                printf("(fastest)");
    
            else if ((pp - motion_str + 1) == ME_FULL) 
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                printf("(slowest)");
    
            else if ((pp - motion_str + 1) == ME_EPZS) 
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                printf("(default)");
            pp++;
        }
    
        printf("\n\n");
        printf(
    "Note, the names of encoders and decoders dont always match, so there are\n"
    "several cases where the above table shows encoder only or decoder only entries\n"
    "even though both encoding and decoding are supported for example, the h263\n"
    "decoder corresponds to the h263 and h263p encoders, for file formats its even\n"
    "worse\n");
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        exit(1);
    }
    
    
    void parse_matrix_coeffs(uint16_t *dest, const char *str)
    {
        int i;
        const char *p = str;
        for(i = 0;; i++) {
            dest[i] = atoi(p);
            if(i == 63)
                break;
            p = strchr(p, ',');
            if(!p) {
                fprintf(stderr, "Syntax error in matrix \"%s\" at coeff %d\n", str, i);
                exit(1);
            }
            p++;
        }
    }
    
    void opt_inter_matrix(const char *arg)
    {
        inter_matrix = av_mallocz(sizeof(uint16_t) * 64);
        parse_matrix_coeffs(inter_matrix, arg);
    }
    
    void opt_intra_matrix(const char *arg)
    {
        intra_matrix = av_mallocz(sizeof(uint16_t) * 64);
        parse_matrix_coeffs(intra_matrix, arg);
    }
    
    
    static void opt_target(const char *arg)
    {
        int norm = -1;
    
        if(!strncmp(arg, "pal-", 4)) {
            norm = 0;
            arg += 4;
        } else if(!strncmp(arg, "ntsc-", 5)) {
            norm = 1;
            arg += 5;
        } else {
            int fr;
            /* Calculate FR via float to avoid int overflow */
            fr = (int)(frame_rate * 1000.0 / frame_rate_base);
            if(fr == 25000) {