diff options
Diffstat (limited to 'contrib/ffmpeg/libavcodec/xvidff.c')
-rw-r--r-- | contrib/ffmpeg/libavcodec/xvidff.c | 768 |
1 files changed, 0 insertions, 768 deletions
diff --git a/contrib/ffmpeg/libavcodec/xvidff.c b/contrib/ffmpeg/libavcodec/xvidff.c deleted file mode 100644 index 590fe4b30..000000000 --- a/contrib/ffmpeg/libavcodec/xvidff.c +++ /dev/null @@ -1,768 +0,0 @@ -/* - * Interface to xvidcore for mpeg4 encoding - * Copyright (c) 2004 Adam Thayer <krevnik@comcast.net> - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file xvidmpeg4.c - * Interface to xvidcore for MPEG-4 compliant encoding. - * @author Adam Thayer (krevnik@comcast.net) - */ - -#include <xvid.h> -#include <unistd.h> -#include "common.h" -#include "avcodec.h" -#include "xvid_internal.h" - -/** - * Buffer management macros. - */ -#define BUFFER_SIZE 1024 -#define BUFFER_REMAINING(x) (BUFFER_SIZE - strlen(x)) -#define BUFFER_CAT(x) (&((x)[strlen(x)])) - -/* For PPC Use */ -#if HAVE_ALTIVEC==1 -extern int has_altivec(void); -#endif - -/** - * Structure for the private XviD context. - * This stores all the private context for the codec. - */ -typedef struct xvid_context { - void *encoder_handle; /** Handle for XviD Encoder */ - int xsize, ysize; /** Frame size */ - int vop_flags; /** VOP flags for XviD Encoder */ - int vol_flags; /** VOL flags for XviD Encoder */ - int me_flags; /** Motion Estimation flags */ - int qscale; /** Do we use constant scale? */ - int quicktime_format; /** Are we in a QT-based format? */ - AVFrame encoded_picture; /** Encoded frame information */ - char *twopassbuffer; /** Character buffer for two-pass */ - char *old_twopassbuffer; /** Old character buffer (two-pass) */ - char *twopassfile; /** second pass temp file name */ - unsigned char *intra_matrix; /** P-Frame Quant Matrix */ - unsigned char *inter_matrix; /** I-Frame Quant Matrix */ -} xvid_context_t; - -/** - * Structure for the private first-pass plugin. - */ -typedef struct xvid_ff_pass1 { - int version; /** XviD version */ - xvid_context_t *context; /** Pointer to private context */ -} xvid_ff_pass1_t; - -/* Prototypes - See function implementation for details */ -int xvid_strip_vol_header(AVCodecContext *avctx, unsigned char *frame, unsigned int header_len, unsigned int frame_len); -int xvid_ff_2pass(void *ref, int opt, void *p1, void *p2); -void xvid_correct_framerate(AVCodecContext *avctx); - -/** - * Creates 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 - */ -int ff_xvid_encode_init(AVCodecContext *avctx) { - int xerr, i; - int xvid_flags = avctx->flags; - xvid_context_t *x = avctx->priv_data; - uint16_t *intra, *inter; - int fd; - - xvid_plugin_single_t single; - xvid_ff_pass1_t 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( xvid_flags & CODEC_FLAG_TRELLIS_QUANT) - 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; - -#ifdef ARCH_POWERPC - /* XviD's PPC support is borked, use libavcodec to detect */ -#if HAVE_ALTIVEC==1 - if( has_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 or threads */ - xvid_enc_create.zones = NULL; - xvid_enc_create.num_zones = 0; - xvid_enc_create.num_threads = 0; - - 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(xvid_ff_pass1_t)); - 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 = av_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 = ff_get_fourcc("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; -} - -/** - * Encodes a single frame. - * - * @param avctx AVCodecContext pointer to context - * @param frame Pointer to encoded frame buffer - * @param buf_size Size of encoded frame buffer - * @param data Pointer to AVFrame of unencoded frame - * @return Returns 0 on success, -1 on failure - */ -int ff_xvid_encode_frame(AVCodecContext *avctx, - unsigned char *frame, int buf_size, void *data) { - int xerr, i; - char *tmp; - xvid_context_t *x = avctx->priv_data; - AVFrame *picture = data; - AVFrame *p = &(x->encoded_picture); - - xvid_enc_frame_t xvid_enc_frame; - xvid_enc_stats_t xvid_enc_stats; - - /* Start setting up the frame */ - memset(&xvid_enc_frame, 0, sizeof(xvid_enc_frame)); - xvid_enc_frame.version = XVID_VERSION; - memset(&xvid_enc_stats, 0, sizeof(xvid_enc_stats)); - xvid_enc_stats.version = XVID_VERSION; - *p = *picture; - - /* Let XviD know where to put the frame. */ - xvid_enc_frame.bitstream = frame; - xvid_enc_frame.length = buf_size; - - /* Initialize input image fields */ - if( avctx->pix_fmt != PIX_FMT_YUV420P ) { - av_log(avctx, AV_LOG_ERROR, "XviD: Color spaces other than 420p not supported\n"); - return -1; - } - - xvid_enc_frame.input.csp = XVID_CSP_PLANAR; /* YUV420P */ - - for( i = 0; i < 4; i++ ) { - xvid_enc_frame.input.plane[i] = picture->data[i]; - xvid_enc_frame.input.stride[i] = picture->linesize[i]; - } - - /* Encoder Flags */ - xvid_enc_frame.vop_flags = x->vop_flags; - xvid_enc_frame.vol_flags = x->vol_flags; - xvid_enc_frame.motion = x->me_flags; - xvid_enc_frame.type = XVID_TYPE_AUTO; - - /* Quant Setting */ - if( x->qscale ) xvid_enc_frame.quant = picture->quality / FF_QP2LAMBDA; - else xvid_enc_frame.quant = 0; - - /* Matrices */ - xvid_enc_frame.quant_intra_matrix = x->intra_matrix; - xvid_enc_frame.quant_inter_matrix = x->inter_matrix; - - /* Encode */ - xerr = xvid_encore(x->encoder_handle, XVID_ENC_ENCODE, - &xvid_enc_frame, &xvid_enc_stats); - - /* Two-pass log buffer swapping */ - avctx->stats_out = NULL; - if( x->twopassbuffer ) { - tmp = x->old_twopassbuffer; - x->old_twopassbuffer = x->twopassbuffer; - x->twopassbuffer = tmp; - x->twopassbuffer[0] = 0; - if( x->old_twopassbuffer[0] != 0 ) { - avctx->stats_out = x->old_twopassbuffer; - } - } - - if( 0 <= xerr ) { - p->quality = xvid_enc_stats.quant * FF_QP2LAMBDA; - if( xvid_enc_stats.type == XVID_TYPE_PVOP ) - p->pict_type = FF_P_TYPE; - else if( xvid_enc_stats.type == XVID_TYPE_BVOP ) - p->pict_type = FF_B_TYPE; - else if( xvid_enc_stats.type == XVID_TYPE_SVOP ) - p->pict_type = FF_S_TYPE; - else - p->pict_type = FF_I_TYPE; - if( xvid_enc_frame.out_flags & XVID_KEYFRAME ) { - p->key_frame = 1; - if( x->quicktime_format ) - return xvid_strip_vol_header(avctx, frame, - xvid_enc_stats.hlength, xerr); - } else - p->key_frame = 0; - - return xerr; - } else { - av_log(avctx, AV_LOG_ERROR, "XviD: Encoding Error Occurred: %i\n", xerr); - return -1; - } -} - -/** - * Destroys the private context for the encoder. - * All buffers are freed, and the XviD encoder context is destroyed. - * - * @param avctx AVCodecContext pointer to context - * @return Returns 0, success guaranteed - */ -int ff_xvid_encode_close(AVCodecContext *avctx) { - xvid_context_t *x = avctx->priv_data; - - xvid_encore(x->encoder_handle, XVID_ENC_DESTROY, NULL, NULL); - - if( avctx->extradata != NULL ) - av_free(avctx->extradata); - if( x->twopassbuffer != NULL ) { - av_free(x->twopassbuffer); - av_free(x->old_twopassbuffer); - } - if( x->twopassfile != NULL ) - av_free(x->twopassfile); - if( x->intra_matrix != NULL ) - av_free(x->intra_matrix); - if( x->inter_matrix != NULL ) - av_free(x->inter_matrix); - - return 0; -} - -/** - * Routine to create a global VO/VOL header for MP4 container. - * What we do here is extract the header from the XviD bitstream - * as it is encoded. We also strip the repeated headers from the - * bitstream when a global header is requested for MPEG-4 ISO - * compliance. - * - * @param avctx AVCodecContext pointer to context - * @param frame Pointer to encoded frame data - * @param header_len Length of header to search - * @param frame_len Length of encoded frame data - * @return Returns new length of frame data - */ -int xvid_strip_vol_header(AVCodecContext *avctx, - unsigned char *frame, - unsigned int header_len, - unsigned int frame_len) { - int vo_len = 0, i; - - for( i = 0; i < header_len - 3; i++ ) { - if( frame[i] == 0x00 && - frame[i+1] == 0x00 && - frame[i+2] == 0x01 && - frame[i+3] == 0xB6 ) { - vo_len = i; - break; - } - } - - if( vo_len > 0 ) { - /* We need to store the header, so extract it */ - if( avctx->extradata == NULL ) { - avctx->extradata = av_malloc(vo_len); - memcpy(avctx->extradata, frame, vo_len); - avctx->extradata_size = vo_len; - } - /* Less dangerous now, memmove properly copies the two - chunks of overlapping data */ - memmove(frame, &(frame[vo_len]), frame_len - vo_len); - return frame_len - vo_len; - } else - return frame_len; -} - -/** - * Routine to correct a possibly erroneous framerate being fed to us. - * XviD currently chokes on framerates where the ticks per frame is - * extremely large. This function works to correct problems in this area - * by estimating a new framerate and taking the simpler fraction of - * the two presented. - * - * @param avctx Context that contains the framerate to correct. - */ -void xvid_correct_framerate(AVCodecContext *avctx) { - int frate, fbase; - int est_frate, est_fbase; - int gcd; - float est_fps, fps; - - frate = avctx->time_base.den; - fbase = avctx->time_base.num; - - gcd = ff_gcd(frate, fbase); - if( gcd > 1 ) { - frate /= gcd; - fbase /= gcd; - } - - if( frate <= 65000 && fbase <= 65000 ) { - avctx->time_base.den = frate; - avctx->time_base.num = fbase; - return; - } - - fps = (float)frate / (float)fbase; - est_fps = roundf(fps * 1000.0) / 1000.0; - - est_frate = (int)est_fps; - if( est_fps > (int)est_fps ) { - est_frate = (est_frate + 1) * 1000; - est_fbase = (int)roundf((float)est_frate / est_fps); - } else - est_fbase = 1; - - gcd = ff_gcd(est_frate, est_fbase); - if( gcd > 1 ) { - est_frate /= gcd; - est_fbase /= gcd; - } - - if( fbase > est_fbase ) { - avctx->time_base.den = est_frate; - avctx->time_base.num = est_fbase; - av_log(avctx, AV_LOG_DEBUG, - "XviD: framerate re-estimated: %.2f, %.3f%% correction\n", - est_fps, (((est_fps - fps)/fps) * 100.0)); - } else { - avctx->time_base.den = frate; - avctx->time_base.num = fbase; - } -} - -/* - * XviD 2-Pass Kludge Section - * - * XviD's default 2-pass doesn't allow us to create data as we need to, so - * this section spends time replacing the first pass plugin so we can write - * statistic information as libavcodec requests in. We have another kludge - * that allows us to pass data to the second pass in XviD without a custom - * rate-control plugin. - */ - -/** - * Initializes the two-pass plugin and context. - * - * @param param Input construction parameter structure - * @param handle Private context handle - * @return Returns XVID_ERR_xxxx on failure, or 0 on success. - */ -static int xvid_ff_2pass_create(xvid_plg_create_t * param, - void ** handle) { - xvid_ff_pass1_t *x = (xvid_ff_pass1_t *)param->param; - char *log = x->context->twopassbuffer; - - /* Do a quick bounds check */ - if( log == NULL ) - return XVID_ERR_FAIL; - - /* We use snprintf() */ - /* This is because we can safely prevent a buffer overflow */ - log[0] = 0; - snprintf(log, BUFFER_REMAINING(log), - "# ffmpeg 2-pass log file, using xvid codec\n"); - snprintf(BUFFER_CAT(log), BUFFER_REMAINING(log), - "# Do not modify. libxvidcore version: %d.%d.%d\n\n", - XVID_VERSION_MAJOR(XVID_VERSION), - XVID_VERSION_MINOR(XVID_VERSION), - XVID_VERSION_PATCH(XVID_VERSION)); - - *handle = x->context; - return 0; -} - -/** - * Destroys the two-pass plugin context. - * - * @param ref Context pointer for the plugin - * @param param Destrooy context - * @return Returns 0, success guaranteed - */ -static int xvid_ff_2pass_destroy(xvid_context_t *ref, - xvid_plg_destroy_t *param) { - /* Currently cannot think of anything to do on destruction */ - /* Still, the framework should be here for reference/use */ - if( ref->twopassbuffer != NULL ) - ref->twopassbuffer[0] = 0; - return 0; -} - -/** - * Enables fast encode mode during the first pass. - * - * @param ref Context pointer for the plugin - * @param param Frame data - * @return Returns 0, success guaranteed - */ -static int xvid_ff_2pass_before(xvid_context_t *ref, - xvid_plg_data_t *param) { - int motion_remove; - int motion_replacements; - int vop_remove; - - /* Nothing to do here, result is changed too much */ - if( param->zone && param->zone->mode == XVID_ZONE_QUANT ) - return 0; - - /* We can implement a 'turbo' first pass mode here */ - param->quant = 2; - - /* Init values */ - motion_remove = ~XVID_ME_CHROMA_PVOP & - ~XVID_ME_CHROMA_BVOP & - ~XVID_ME_EXTSEARCH16 & - ~XVID_ME_ADVANCEDDIAMOND16; - motion_replacements = XVID_ME_FAST_MODEINTERPOLATE | - XVID_ME_SKIP_DELTASEARCH | - XVID_ME_FASTREFINE16 | - XVID_ME_BFRAME_EARLYSTOP; - vop_remove = ~XVID_VOP_MODEDECISION_RD & - ~XVID_VOP_FAST_MODEDECISION_RD & - ~XVID_VOP_TRELLISQUANT & - ~XVID_VOP_INTER4V & - ~XVID_VOP_HQACPRED; - - param->vol_flags &= ~XVID_VOL_GMC; - param->vop_flags &= vop_remove; - param->motion_flags &= motion_remove; - param->motion_flags |= motion_replacements; - - return 0; -} - -/** - * Captures statistic data and writes it during first pass. - * - * @param ref Context pointer for the plugin - * @param param Statistic data - * @return Returns XVID_ERR_xxxx on failure, or 0 on success - */ -static int xvid_ff_2pass_after(xvid_context_t *ref, - xvid_plg_data_t *param) { - char *log = ref->twopassbuffer; - char *frame_types = " ipbs"; - char frame_type; - - /* Quick bounds check */ - if( log == NULL ) - return XVID_ERR_FAIL; - - /* Convert the type given to us into a character */ - if( param->type < 5 && param->type > 0 ) { - frame_type = frame_types[param->type]; - } else { - return XVID_ERR_FAIL; - } - - snprintf(BUFFER_CAT(log), BUFFER_REMAINING(log), - "%c %d %d %d %d %d %d\n", - frame_type, param->stats.quant, param->stats.kblks, param->stats.mblks, - param->stats.ublks, param->stats.length, param->stats.hlength); - - return 0; -} - -/** - * Dispatch function for our custom plugin. - * This handles the dispatch for the XviD plugin. It passes data - * on to other functions for actual processing. - * - * @param ref Context pointer for the plugin - * @param cmd The task given for us to complete - * @param p1 First parameter (varies) - * @param p2 Second parameter (varies) - * @return Returns XVID_ERR_xxxx on failure, or 0 on success - */ -int xvid_ff_2pass(void *ref, int cmd, void *p1, void *p2) { - switch( cmd ) { - case XVID_PLG_INFO: - case XVID_PLG_FRAME: - return 0; - - case XVID_PLG_BEFORE: - return xvid_ff_2pass_before(ref, p1); - - case XVID_PLG_CREATE: - return xvid_ff_2pass_create(p1, p2); - - case XVID_PLG_AFTER: - return xvid_ff_2pass_after(ref, p1); - - case XVID_PLG_DESTROY: - return xvid_ff_2pass_destroy(ref, p1); - - default: - return XVID_ERR_FAIL; - } -} - -/** - * XviD codec definition for libavcodec. - */ -AVCodec xvid_encoder = { - "xvid", - CODEC_TYPE_VIDEO, - CODEC_ID_XVID, - sizeof(xvid_context_t), - ff_xvid_encode_init, - ff_xvid_encode_frame, - ff_xvid_encode_close, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, -}; |