Exemplo n.º 1
0
int ff_xvid_rate_control_init(MpegEncContext *s){
    char *tmp_name;
    int fd, i;
    xvid_plg_create_t xvid_plg_create;
    xvid_plugin_2pass2_t xvid_2pass2;

//xvid_debug=-1;

    fd=ff_tempfile("xvidrc.", &tmp_name);
    if (fd == -1) {
        av_log(NULL, AV_LOG_ERROR, "Can't create temporary pass2 file.\n");
        return -1;
    }

    for(i=0; i<s->rc_context.num_entries; i++){
        static const char frame_types[] = " ipbs";
        char tmp[256];
        RateControlEntry *rce;

        rce= &s->rc_context.entry[i];

        snprintf(tmp, sizeof(tmp), "%c %d %d %d %d %d %d\n",
            frame_types[rce->pict_type], (int)lrintf(rce->qscale / FF_QP2LAMBDA), rce->i_count, s->mb_num - rce->i_count - rce->skip_count,
            rce->skip_count, (rce->i_tex_bits + rce->p_tex_bits + rce->misc_bits+7)/8, (rce->header_bits+rce->mv_bits+7)/8);

//av_log(NULL, AV_LOG_ERROR, "%s\n", tmp);
        write(fd, tmp, strlen(tmp));
    }

    close(fd);

    memset(&xvid_2pass2, 0, sizeof(xvid_2pass2));
    xvid_2pass2.version= XVID_MAKE_VERSION(1,1,0);
    xvid_2pass2.filename= tmp_name;
    xvid_2pass2.bitrate= s->avctx->bit_rate;
    xvid_2pass2.vbv_size= s->avctx->rc_buffer_size;
    xvid_2pass2.vbv_maxrate= s->avctx->rc_max_rate;
    xvid_2pass2.vbv_initial= s->avctx->rc_initial_buffer_occupancy;

    memset(&xvid_plg_create, 0, sizeof(xvid_plg_create));
    xvid_plg_create.version= XVID_MAKE_VERSION(1,1,0);
    xvid_plg_create.fbase= s->avctx->time_base.den;
    xvid_plg_create.fincr= s->avctx->time_base.num;
    xvid_plg_create.param= &xvid_2pass2;

    if(xvid_plugin_2pass2(NULL, XVID_PLG_CREATE, &xvid_plg_create, &s->rc_context.non_lavc_opaque)<0){
        av_log(NULL, AV_LOG_ERROR, "xvid_plugin_2pass2 failed\n");
        return -1;
    }
    return 0;
}
Exemplo n.º 2
0
/**
 * Create the private context for the encoder.
 * All buffers are allocated, settings are loaded from the user,
 * and the encoder context created.
 *
 * @param avctx AVCodecContext pointer to context
 * @return Returns 0 on success, -1 on failure
 */
static av_cold int xvid_encode_init(AVCodecContext *avctx)  {
    int xerr, i;
    int xvid_flags = avctx->flags;
    struct xvid_context *x = avctx->priv_data;
    uint16_t *intra, *inter;
    int fd;

    xvid_plugin_single_t single;
    struct xvid_ff_pass1 rc2pass1;
    xvid_plugin_2pass2_t rc2pass2;
    xvid_gbl_init_t xvid_gbl_init;
    xvid_enc_create_t xvid_enc_create;
    xvid_enc_plugin_t plugins[7];

    /* Bring in VOP flags from ffmpeg command-line */
    x->vop_flags = XVID_VOP_HALFPEL; /* Bare minimum quality */
    if( xvid_flags & CODEC_FLAG_4MV )
        x->vop_flags |= XVID_VOP_INTER4V; /* Level 3 */
    if( avctx->trellis
        )
        x->vop_flags |= XVID_VOP_TRELLISQUANT; /* Level 5 */
    if( xvid_flags & CODEC_FLAG_AC_PRED )
        x->vop_flags |= XVID_VOP_HQACPRED; /* Level 6 */
    if( xvid_flags & CODEC_FLAG_GRAY )
        x->vop_flags |= XVID_VOP_GREYSCALE;

    /* Decide which ME quality setting to use */
    x->me_flags = 0;
    switch( avctx->me_method ) {
       case ME_FULL:   /* Quality 6 */
           x->me_flags |=  XVID_ME_EXTSEARCH16
                       |   XVID_ME_EXTSEARCH8;

       case ME_EPZS:   /* Quality 4 */
           x->me_flags |=  XVID_ME_ADVANCEDDIAMOND8
                       |   XVID_ME_HALFPELREFINE8
                       |   XVID_ME_CHROMA_PVOP
                       |   XVID_ME_CHROMA_BVOP;

       case ME_LOG:    /* Quality 2 */
       case ME_PHODS:
       case ME_X1:
           x->me_flags |=  XVID_ME_ADVANCEDDIAMOND16
                       |   XVID_ME_HALFPELREFINE16;

       case ME_ZERO:   /* Quality 0 */
       default:
           break;
    }

    /* Decide how we should decide blocks */
    switch( avctx->mb_decision ) {
       case 2:
           x->vop_flags |= XVID_VOP_MODEDECISION_RD;
           x->me_flags |=  XVID_ME_HALFPELREFINE8_RD
                       |   XVID_ME_QUARTERPELREFINE8_RD
                       |   XVID_ME_EXTSEARCH_RD
                       |   XVID_ME_CHECKPREDICTION_RD;
       case 1:
           if( !(x->vop_flags & XVID_VOP_MODEDECISION_RD) )
               x->vop_flags |= XVID_VOP_FAST_MODEDECISION_RD;
           x->me_flags |=  XVID_ME_HALFPELREFINE16_RD
                       |   XVID_ME_QUARTERPELREFINE16_RD;

       default:
           break;
    }

    /* Bring in VOL flags from ffmpeg command-line */
    x->vol_flags = 0;
    if( xvid_flags & CODEC_FLAG_GMC ) {
        x->vol_flags |= XVID_VOL_GMC;
        x->me_flags |= XVID_ME_GME_REFINE;
    }
    if( xvid_flags & CODEC_FLAG_QPEL ) {
        x->vol_flags |= XVID_VOL_QUARTERPEL;
        x->me_flags |= XVID_ME_QUARTERPELREFINE16;
        if( x->vop_flags & XVID_VOP_INTER4V )
            x->me_flags |= XVID_ME_QUARTERPELREFINE8;
    }

    memset(&xvid_gbl_init, 0, sizeof(xvid_gbl_init));
    xvid_gbl_init.version = XVID_VERSION;
    xvid_gbl_init.debug = 0;

#if ARCH_PPC
    /* Xvid's PPC support is borked, use libavcodec to detect */
#if HAVE_ALTIVEC
    if (av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) {
        xvid_gbl_init.cpu_flags = XVID_CPU_FORCE | XVID_CPU_ALTIVEC;
    } else
#endif
        xvid_gbl_init.cpu_flags = XVID_CPU_FORCE;
#else
    /* Xvid can detect on x86 */
    xvid_gbl_init.cpu_flags = 0;
#endif

    /* Initialize */
    xvid_global(NULL, XVID_GBL_INIT, &xvid_gbl_init, NULL);

    /* Create the encoder reference */
    memset(&xvid_enc_create, 0, sizeof(xvid_enc_create));
    xvid_enc_create.version = XVID_VERSION;

    /* Store the desired frame size */
    xvid_enc_create.width = x->xsize = avctx->width;
    xvid_enc_create.height = x->ysize = avctx->height;

    /* Xvid can determine the proper profile to use */
    /* xvid_enc_create.profile = XVID_PROFILE_S_L3; */

    /* We don't use zones */
    xvid_enc_create.zones = NULL;
    xvid_enc_create.num_zones = 0;

    xvid_enc_create.num_threads = avctx->thread_count;

    xvid_enc_create.plugins = plugins;
    xvid_enc_create.num_plugins = 0;

    /* Initialize Buffers */
    x->twopassbuffer = NULL;
    x->old_twopassbuffer = NULL;
    x->twopassfile = NULL;

    if( xvid_flags & CODEC_FLAG_PASS1 ) {
        memset(&rc2pass1, 0, sizeof(struct xvid_ff_pass1));
        rc2pass1.version = XVID_VERSION;
        rc2pass1.context = x;
        x->twopassbuffer = av_malloc(BUFFER_SIZE);
        x->old_twopassbuffer = av_malloc(BUFFER_SIZE);
        if( x->twopassbuffer == NULL || x->old_twopassbuffer == NULL ) {
            av_log(avctx, AV_LOG_ERROR,
                "Xvid: Cannot allocate 2-pass log buffers\n");
            return -1;
        }
        x->twopassbuffer[0] = x->old_twopassbuffer[0] = 0;

        plugins[xvid_enc_create.num_plugins].func = xvid_ff_2pass;
        plugins[xvid_enc_create.num_plugins].param = &rc2pass1;
        xvid_enc_create.num_plugins++;
    } else if( xvid_flags & CODEC_FLAG_PASS2 ) {
        memset(&rc2pass2, 0, sizeof(xvid_plugin_2pass2_t));
        rc2pass2.version = XVID_VERSION;
        rc2pass2.bitrate = avctx->bit_rate;

        fd = ff_tempfile("xvidff.", &(x->twopassfile));
        if( fd == -1 ) {
            av_log(avctx, AV_LOG_ERROR,
                "Xvid: Cannot write 2-pass pipe\n");
            return -1;
        }

        if( avctx->stats_in == NULL ) {
            av_log(avctx, AV_LOG_ERROR,
                "Xvid: No 2-pass information loaded for second pass\n");
            return -1;
        }

        if( strlen(avctx->stats_in) >
              write(fd, avctx->stats_in, strlen(avctx->stats_in)) ) {
            close(fd);
            av_log(avctx, AV_LOG_ERROR,
                "Xvid: Cannot write to 2-pass pipe\n");
            return -1;
        }

        close(fd);
        rc2pass2.filename = x->twopassfile;
        plugins[xvid_enc_create.num_plugins].func = xvid_plugin_2pass2;
        plugins[xvid_enc_create.num_plugins].param = &rc2pass2;
        xvid_enc_create.num_plugins++;
    } else if( !(xvid_flags & CODEC_FLAG_QSCALE) ) {
        /* Single Pass Bitrate Control! */
        memset(&single, 0, sizeof(xvid_plugin_single_t));
        single.version = XVID_VERSION;
        single.bitrate = avctx->bit_rate;

        plugins[xvid_enc_create.num_plugins].func = xvid_plugin_single;
        plugins[xvid_enc_create.num_plugins].param = &single;
        xvid_enc_create.num_plugins++;
    }

    /* Luminance Masking */
    if( 0.0 != avctx->lumi_masking ) {
        plugins[xvid_enc_create.num_plugins].func = xvid_plugin_lumimasking;
        plugins[xvid_enc_create.num_plugins].param = NULL;
        xvid_enc_create.num_plugins++;
    }

    /* Frame Rate and Key Frames */
    xvid_correct_framerate(avctx);
    xvid_enc_create.fincr = avctx->time_base.num;
    xvid_enc_create.fbase = avctx->time_base.den;
    if( avctx->gop_size > 0 )
        xvid_enc_create.max_key_interval = avctx->gop_size;
    else
        xvid_enc_create.max_key_interval = 240; /* Xvid's best default */

    /* Quants */
    if( xvid_flags & CODEC_FLAG_QSCALE ) x->qscale = 1;
    else x->qscale = 0;

    xvid_enc_create.min_quant[0] = avctx->qmin;
    xvid_enc_create.min_quant[1] = avctx->qmin;
    xvid_enc_create.min_quant[2] = avctx->qmin;
    xvid_enc_create.max_quant[0] = avctx->qmax;
    xvid_enc_create.max_quant[1] = avctx->qmax;
    xvid_enc_create.max_quant[2] = avctx->qmax;

    /* Quant Matrices */
    x->intra_matrix = x->inter_matrix = NULL;
    if( avctx->mpeg_quant )
       x->vol_flags |= XVID_VOL_MPEGQUANT;
    if( (avctx->intra_matrix || avctx->inter_matrix) ) {
       x->vol_flags |= XVID_VOL_MPEGQUANT;

       if( avctx->intra_matrix ) {
           intra = avctx->intra_matrix;
           x->intra_matrix = av_malloc(sizeof(unsigned char) * 64);
       } else
           intra = NULL;
       if( avctx->inter_matrix ) {
           inter = avctx->inter_matrix;
           x->inter_matrix = av_malloc(sizeof(unsigned char) * 64);
       } else
           inter = NULL;

       for( i = 0; i < 64; i++ ) {
           if( intra )
               x->intra_matrix[i] = (unsigned char)intra[i];
           if( inter )
               x->inter_matrix[i] = (unsigned char)inter[i];
       }
    }

    /* Misc Settings */
    xvid_enc_create.frame_drop_ratio = 0;
    xvid_enc_create.global = 0;
    if( xvid_flags & CODEC_FLAG_CLOSED_GOP )
        xvid_enc_create.global |= XVID_GLOBAL_CLOSED_GOP;

    /* Determines which codec mode we are operating in */
    avctx->extradata = NULL;
    avctx->extradata_size = 0;
    if( xvid_flags & CODEC_FLAG_GLOBAL_HEADER ) {
        /* In this case, we are claiming to be MPEG4 */
        x->quicktime_format = 1;
        avctx->codec_id = CODEC_ID_MPEG4;
    } else {
        /* We are claiming to be Xvid */
        x->quicktime_format = 0;
        if(!avctx->codec_tag)
            avctx->codec_tag = AV_RL32("xvid");
    }

    /* Bframes */
    xvid_enc_create.max_bframes = avctx->max_b_frames;
    xvid_enc_create.bquant_offset = 100 * avctx->b_quant_offset;
    xvid_enc_create.bquant_ratio = 100 * avctx->b_quant_factor;
    if( avctx->max_b_frames > 0  && !x->quicktime_format ) xvid_enc_create.global |= XVID_GLOBAL_PACKED;

    /* Create encoder context */
    xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL);
    if( xerr ) {
        av_log(avctx, AV_LOG_ERROR, "Xvid: Could not create encoder reference\n");
        return -1;
    }

    x->encoder_handle = xvid_enc_create.handle;
    avctx->coded_frame = &x->encoded_picture;

    return 0;
}