Skip to content
Snippets Groups Projects
ffmpeg.c 157 KiB
Newer Older
  • Learn to ignore specific revisions
  • static void opt_rec_timestamp(const char *arg)
    {
        rec_timestamp = parse_date(arg, 0) / 1000000;
    }
    
    
    static void opt_input_ts_offset(const char *arg)
    {
        input_ts_offset = 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;
    
        int64_t timestamp;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
        if (!strcmp(filename, "-"))
            filename = "pipe:";
    
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        using_stdin |= !strncmp(filename, "pipe:", 5) || 
    
    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->time_base.den = frame_rate;
        ap->time_base.num = frame_rate_base;
    
        ap->width = frame_width + frame_padleft + frame_padright;
        ap->height = frame_height + frame_padtop + frame_padbottom;
    
        ap->pix_fmt = frame_pix_fmt;
    
        ap->device  = grab_device;
        ap->channel = video_channel;
        ap->standard = video_standard;
    
        ap->video_codec_id = video_codec_id;
        ap->audio_codec_id = audio_codec_id;
        if(pgmyuv_compatibility_hack)
            ap->video_codec_id= CODEC_ID_PGMYUV;
    
    
        /* open the input file with generic libav function */
        err = av_open_input_file(&ic, filename, file_iformat, 0, ap);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        if (err < 0) {
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            exit(1);
        }
    
    
        if(genpts)
            ic->flags|= AVFMT_FLAG_GENPTS;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        
    
        /* 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);
            exit(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;
        }
    
    
    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(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;
    
                    ic->streams[i]->discard= AVDISCARD_ALL;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                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.num;
                rfps_base = ic->streams[i]->r_frame_rate.den;
    
                enc->error_resilience = error_resilience; 
    
                enc->error_concealment = error_concealment; 
    
                enc->idct_algo = idct_algo;
                enc->debug = debug;
                enc->debug_mv = debug_mv;            
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                enc->lowres= lowres;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                if(lowres) enc->flags |= CODEC_FLAG_EMU_EDGE;
    
                if(bitexact)
                    enc->flags|= CODEC_FLAG_BITEXACT;
    
                if(gray_only)
                    enc->flags |= CODEC_FLAG_GRAY;
    
                if (enc->time_base.den != rfps || enc->time_base.num != rfps_base) { 
    
                        fprintf(stderr,"\nSeems that stream %d comes from film source: %2.2f (%d/%d) -> %2.2f (%d/%d)\n",
    
                                i, (float)enc->time_base.den / enc->time_base.num, enc->time_base.den, enc->time_base.num,
    
                        (float)rfps / rfps_base, rfps, rfps_base);
    
                /* update the current frame rate to match the stream frame rate */
    
                    ic->streams[i]->discard= AVDISCARD_ALL;
                else if(video_discard)
                    ic->streams[i]->discard= video_discard;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                break;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            }
        }
        
        input_files[nb_input_files] = ic;
    
        input_files_ts_offset[nb_input_files] = input_ts_offset - (copy_ts ? 0 : timestamp);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        /* dump the file content */
    
        if (verbose >= 0)
            dump_format(ic, nb_input_files, filename, 0);
    
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        nb_input_files++;
    
        file_iformat = NULL;
        file_oformat = NULL;
    
        grab_device = NULL;
        video_channel = 0;
        
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    }
    
    
    static void opt_grab(const char *arg)
    {
        file_iformat = av_find_input_format(arg);
        opt_input_file("");
    }
    
    
    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 new_video_stream(AVFormatContext *oc)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
        AVStream *st;
    
        AVCodecContext *video_enc;
        int codec_id;
        
        st = av_new_stream(oc, oc->nb_streams);
        if (!st) {
            fprintf(stderr, "Could not alloc stream\n");
            exit(1);
        }
    #if defined(HAVE_THREADS)
        if(thread_count>1)
    
            avcodec_thread_init(st->codec, thread_count);
    
        
        if(video_codec_tag)
            video_enc->codec_tag= video_codec_tag;
        
    
        if(   (video_global_header&1)
           || (video_global_header==0 && (oc->oformat->flags & AVFMT_GLOBALHEADER)))
    
            video_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
    
        if(video_global_header&2)
            video_enc->flags2 |= CODEC_FLAG2_LOCAL_HEADER;
    
    
        if (video_stream_copy) {
            st->stream_copy = 1;
            video_enc->codec_type = CODEC_TYPE_VIDEO;
        } else {
            char *p;
            int i;
            AVCodec *codec;
            
            codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, CODEC_TYPE_VIDEO);
            if (video_codec_id != CODEC_ID_NONE)
                codec_id = video_codec_id;
                    
            video_enc->codec_id = codec_id;
            codec = avcodec_find_encoder(codec_id);
                    
            video_enc->bit_rate = video_bit_rate;
            video_enc->bit_rate_tolerance = video_bit_rate_tolerance;
            video_enc->time_base.den = frame_rate; 
            video_enc->time_base.num = frame_rate_base; 
            if(codec && codec->supported_framerates){
                const AVRational *p= codec->supported_framerates;
                AVRational req= (AVRational){frame_rate, frame_rate_base};
                const AVRational *best=NULL;
                AVRational best_error= (AVRational){INT_MAX, 1};
                for(; p->den!=0; p++){
                    AVRational error= av_sub_q(req, *p);
                    if(error.num <0) error.num *= -1;
                    if(av_cmp_q(error, best_error) < 0){
                        best_error= error;
                        best= p;
                    }
                }
                video_enc->time_base.den= best->num;
                video_enc->time_base.num= best->den;
            }
                    
            video_enc->width = frame_width + frame_padright + frame_padleft;
            video_enc->height = frame_height + frame_padtop + frame_padbottom;
            video_enc->sample_aspect_ratio = av_d2q(frame_aspect_ratio*frame_height/frame_width, 255);
            video_enc->pix_fmt = frame_pix_fmt;
    
            if(codec && codec->pix_fmts){
                const enum PixelFormat *p= codec->pix_fmts;
                for(; *p!=-1; p++){
                    if(*p == video_enc->pix_fmt)
                        break;
                }
                if(*p == -1)
                    video_enc->pix_fmt = codec->pix_fmts[0];
            }
    
            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;
                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;
    
            if(bitexact)
                video_enc->flags |= CODEC_FLAG_BITEXACT;
    
            video_enc->mb_decision = mb_decision;
            video_enc->mb_cmp = mb_cmp;
            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_ss) {
                video_enc->flags |= CODEC_FLAG_H263P_SLICE_STRUCT;
            }
            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;
            }
            if (use_loop) {
                video_enc->flags |= CODEC_FLAG_LOOP_FILTER;
            }
                
            if(use_part) {
                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_mv0) {
                video_enc->flags |= CODEC_FLAG_MV0;
            }
            if (do_normalize_aqp) {
                video_enc->flags |= CODEC_FLAG_NORMALIZE_AQP;
            }
            if (use_scan_offset) {
                video_enc->flags |= CODEC_FLAG_SVCD_SCAN_OFFSET;
            }
            if (closed_gop) {
                video_enc->flags |= CODEC_FLAG_CLOSED_GOP;
            }
            if (strict_gop) {
                video_enc->flags2 |= CODEC_FLAG2_STRICT_GOP;
            }
            if (use_qpel) {
                video_enc->flags |= CODEC_FLAG_QPEL;
            }
            if (use_qprd) {
                video_enc->flags |= CODEC_FLAG_QP_RD;
            }
            if (use_cbprd) {
                video_enc->flags |= CODEC_FLAG_CBP_RD;
            }
            if (b_frames) {
                video_enc->max_b_frames = b_frames;
                video_enc->b_frame_strategy = b_strategy;
                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;
            }
            if (no_output) {
                video_enc->flags2 |= CODEC_FLAG2_NO_OUTPUT;
            }
            if (gray_only) {
                video_enc->flags |= CODEC_FLAG_GRAY;
            }
            video_enc->qmin = video_qmin;
            video_enc->qmax = video_qmax;
            video_enc->lmin = video_lmin;
            video_enc->lmax = video_lmax;
            video_enc->rc_qsquish = video_qsquish;
            video_enc->luma_elim_threshold = video_lelim;
            video_enc->chroma_elim_threshold = video_celim;
            video_enc->mb_lmin = video_mb_lmin;
            video_enc->mb_lmax = video_mb_lmax;
            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 = debug;
            video_enc->debug_mv = debug_mv;
            video_enc->workaround_bugs = workaround_bugs;
            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= 
                    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_initial_buffer_occupancy = video_rc_buffer_size*3/4;
            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->me_threshold= me_threshold;
            video_enc->mb_threshold= mb_threshold;
            video_enc->intra_dc_precision= intra_dc_precision - 8;
            video_enc->strict_std_compliance = strict;
            video_enc->error_rate = error_rate;
            video_enc->noise_reduction= noise_reduction;
            video_enc->scenechange_threshold= sc_threshold;
            video_enc->me_range = me_range;
            video_enc->coder_type= coder;
            video_enc->context_model= context;
            video_enc->prediction_method= predictor;
            video_enc->profile= video_profile;
            video_enc->level= video_level;
            video_enc->nsse_weight= nsse_weight;
            video_enc->me_subpel_quality= subpel_quality;
            video_enc->me_penalty_compensation= me_penalty_compensation;
            video_enc->frame_skip_threshold= frame_skip_threshold;
            video_enc->frame_skip_factor= frame_skip_factor;
            video_enc->frame_skip_exp= frame_skip_exp;
            video_enc->frame_skip_cmp= frame_skip_cmp;
    
            if(packet_size){
                video_enc->rtp_mode= 1;
                video_enc->rtp_payload_size= packet_size;
            }
                
            if (do_psnr)
                video_enc->flags|= CODEC_FLAG_PSNR;
                
            video_enc->me_method = me_method;
    
            /* two pass mode */
            if (do_pass) {
                if (do_pass == 1) {
                    video_enc->flags |= CODEC_FLAG_PASS1;
                } else {
                    video_enc->flags |= CODEC_FLAG_PASS2;
                }
            }
        }
    
        /* reset some key parameters */
        video_disable = 0;
        video_codec_id = CODEC_ID_NONE;
        video_stream_copy = 0;
    }
    
    static void new_audio_stream(AVFormatContext *oc)
    {
        AVStream *st;
        AVCodecContext *audio_enc;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        int codec_id;
    
                
        st = av_new_stream(oc, oc->nb_streams);
        if (!st) {
            fprintf(stderr, "Could not alloc stream\n");
            exit(1);
        }
    #if defined(HAVE_THREADS)
        if(thread_count>1)
    
            avcodec_thread_init(st->codec, thread_count);
    
        audio_enc->codec_type = CODEC_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_stream_copy) {
            st->stream_copy = 1;
            audio_enc->channels = audio_channels;
        } else {
            codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, CODEC_TYPE_AUDIO);
            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;
    
            if (audio_qscale > QSCALE_NONE) {
                audio_enc->flags |= CODEC_FLAG_QSCALE;
                audio_enc->global_quality = st->quality = FF_QP2LAMBDA * audio_qscale;
            }
    
            audio_enc->strict_std_compliance = strict;
            audio_enc->thread_count = thread_count;
            /* For audio codecs other than AC3 or DTS we limit */
            /* the number of coded channels to stereo   */
            if (audio_channels > 2 && codec_id != CODEC_ID_AC3
                && codec_id != CODEC_ID_DTS) {
                audio_enc->channels = 2;
            } else
                audio_enc->channels = audio_channels;
        }
        audio_enc->sample_rate = audio_sample_rate;
        if (audio_language) {
            pstrcpy(st->language, sizeof(st->language), audio_language);
            av_free(audio_language);
            audio_language = NULL;
        }
    
        /* reset some key parameters */
        audio_disable = 0;
        audio_codec_id = CODEC_ID_NONE;
        audio_stream_copy = 0;
    }
    
    static void opt_new_subtitle_stream(void)
    {
        AVFormatContext *oc;
        AVStream *st;
        AVCodecContext *subtitle_enc;
                
        if (nb_output_files <= 0) {
            fprintf(stderr, "At least one output file must be specified\n");
            exit(1);
        }
        oc = output_files[nb_output_files - 1];
    
        st = av_new_stream(oc, oc->nb_streams);
        if (!st) {
            fprintf(stderr, "Could not alloc stream\n");
            exit(1);
        }
    
    
        subtitle_enc->codec_type = CODEC_TYPE_SUBTITLE;
        if (subtitle_stream_copy) {
            st->stream_copy = 1;
        } else {
            subtitle_enc->codec_id = subtitle_codec_id;
        }
    
        if (subtitle_language) {
            pstrcpy(st->language, sizeof(st->language), subtitle_language);
            av_free(subtitle_language);
            subtitle_language = NULL;
        }
    
        subtitle_codec_id = CODEC_ID_NONE;
        subtitle_stream_copy = 0;
    }
    
    static void opt_new_audio_stream(void)
    {
        AVFormatContext *oc;
        if (nb_output_files <= 0) {
            fprintf(stderr, "At least one output file must be specified\n");
            exit(1);
        }
        oc = output_files[nb_output_files - 1];
        new_audio_stream(oc);
    }
    
    static void opt_new_video_stream(void)
    {
        AVFormatContext *oc;
        if (nb_output_files <= 0) {
            fprintf(stderr, "At least one output file must be specified\n");
            exit(1);
        }
        oc = output_files[nb_output_files - 1];
        new_video_stream(oc);
    }
    
    static void opt_output_file(const char *filename)
    {
        AVFormatContext *oc;
        int use_video, use_audio, input_has_video, input_has_audio;
    
    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
        }
        
    
        pstrcpy(oc->filename, sizeof(oc->filename), filename);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
        if (!strcmp(file_oformat->name, "ffm") && 
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            strstart(filename, "http:", NULL)) {
            /* special case for files sent to ffserver: we get the stream
               parameters from ffserver */
            if (read_ffserver_streams(oc, filename) < 0) {
                fprintf(stderr, "Could not read stream parameters from '%s'\n", filename);
                exit(1);
            }
        } else {
    
            use_video = file_oformat->video_codec != CODEC_ID_NONE || video_stream_copy || video_codec_id != CODEC_ID_NONE;
            use_audio = file_oformat->audio_codec != CODEC_ID_NONE || audio_stream_copy || audio_codec_id != CODEC_ID_NONE;
    
            /* disable if no corresponding type found and at least one
               input file */
            if (nb_input_files > 0) {
                check_audio_video_inputs(&input_has_video, &input_has_audio);
                if (!input_has_video)
                    use_video = 0;
                if (!input_has_audio)
                    use_audio = 0;
            }
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            if (audio_disable) {
                use_audio = 0;
            }
            if (video_disable) {
                use_video = 0;
            }
            
            if (use_video) {
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            }
        
            if (use_audio) {
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            }
    
    
                fprintf(stderr, "No audio or video streams available\n");
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                exit(1);
            }
    
    
                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
    
    
        /* 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);
        }
    
    
        oc->packet_size= mux_packet_size;
        oc->mux_rate= mux_rate;
    
        oc->preload= (int)(mux_preload*AV_TIME_BASE);
        oc->max_delay= (int)(mux_max_delay*AV_TIME_BASE);
    
        oc->loop_output = loop_output;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        /* reset some options */
    
        file_oformat = NULL;
        file_iformat = NULL;
    
    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));
    
        vp->time_base.num= 1;
    
        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;
    
                    if (vp->time_base.num*(int64_t)enc->time_base.den > enc->time_base.num*(int64_t)vp->time_base.den){
                        vp->time_base = enc->time_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.num = vp->time_base.den;
            ic->streams[0]->r_frame_rate.den = vp->time_base.num;
    
    
            if (verbose >= 0)
                dump_format(ic, nb_input_files, "", 0);
    
    
        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");
    
    
            if (verbose >= 0)
                dump_format(ic, nb_input_files, "", 0);
    
    
    /* 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(
    
                decode ? "D":" ", 
                encode ? "E":" ", 
    
        printf("Image formats (filename extensions, if any, follow):\n");
    
        for(image_fmt = first_image_format; image_fmt != NULL; 
            image_fmt = image_fmt->next) {
    
                image_fmt->img_read  ? "D":" ",
                image_fmt->img_write ? "E":" ",
    
                image_fmt->name,
                image_fmt->extensions ? image_fmt->extensions:" ");
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        printf("Codecs:\n");
    
        last_name= "000";
        for(;;){
            int decode=0;
            int encode=0;
            int cap=0;
    
    
            p2=NULL;
            for(p = first_avcodec; p != NULL; p = p->next) {
                if((p2==NULL || strcmp(p->name, p2->name)<0) &&
                    strcmp(p->name, last_name)>0){
                    p2= p;
                    decode= encode= cap=0;
                }
                if(p2 && strcmp(p->name, p2->name)==0){
                    if(p->decode) decode=1;
                    if(p->encode) encode=1;
                    cap |= p->capabilities;
                }
            }
            if(p2==NULL)
                break;
            last_name= p2->name;
            
    
            switch(p2->type) {
            case CODEC_TYPE_VIDEO:
                type_str = "V";
                break;
            case CODEC_TYPE_AUDIO:
                type_str = "A";
                break;
            case CODEC_TYPE_SUBTITLE:
                type_str = "S";
                break;
            default:
                type_str = "?";
                break;
            }
    
            printf(
                " %s%s%s%s%s%s %s", 
                decode ? "D": (/*p2->decoder ? "d":*/" "), 
                encode ? "E":" ", 
    
                cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S":" ",
                cap & CODEC_CAP_DR1 ? "D":" ",
                cap & CODEC_CAP_TRUNCATED ? "T":" ",
                p2->name);
           /* if(p2->decoder && decode==0)
                printf(" use %s for decoding", p2->decoder->name);*/
            printf("\n");
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        }
        printf("\n");
    
    
        printf("Supported file protocols:\n");
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        for(up = first_protocol; up != NULL; up = up->next)
            printf(" %s:", up->name);
        printf("\n");
        
    
        printf("Frame size, frame rate abbreviations:\n ntsc pal qntsc qpal sntsc spal film ntsc-film sqcif qcif cif 4cif\n");
        printf("Motion estimation methods:\n");
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        pp = motion_str;
        while (*pp) {
            printf(" %s", *pp);
    
            if ((pp - motion_str + 1) == ME_ZERO) 
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                printf("(fastest)");
    
            else if ((pp - motion_str + 1) == ME_FULL) 
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                printf("(slowest)");
    
            else if ((pp - motion_str + 1) == ME_EPZS) 
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                printf("(default)");