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; }
/** * 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; }