|
|
|
@ -41,14 +41,14 @@
|
|
|
|
|
extern int has_altivec(void);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Structure for the private XviD context.
|
|
|
|
|
* 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 */
|
|
|
|
|
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 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? */
|
|
|
|
@ -64,7 +64,7 @@ typedef struct xvid_context {
|
|
|
|
|
* Structure for the private first-pass plugin.
|
|
|
|
|
*/
|
|
|
|
|
typedef struct xvid_ff_pass1 {
|
|
|
|
|
int version; /** XviD version */
|
|
|
|
|
int version; /** Xvid version */
|
|
|
|
|
xvid_context_t *context; /** Pointer to private context */
|
|
|
|
|
} xvid_ff_pass1_t;
|
|
|
|
|
|
|
|
|
@ -166,7 +166,7 @@ av_cold int ff_xvid_encode_init(AVCodecContext *avctx) {
|
|
|
|
|
xvid_gbl_init.debug = 0;
|
|
|
|
|
|
|
|
|
|
#ifdef ARCH_POWERPC
|
|
|
|
|
/* XviD's PPC support is borked, use libavcodec to detect */
|
|
|
|
|
/* Xvid's PPC support is borked, use libavcodec to detect */
|
|
|
|
|
#ifdef HAVE_ALTIVEC
|
|
|
|
|
if( has_altivec() ) {
|
|
|
|
|
xvid_gbl_init.cpu_flags = XVID_CPU_FORCE | XVID_CPU_ALTIVEC;
|
|
|
|
@ -174,7 +174,7 @@ av_cold int ff_xvid_encode_init(AVCodecContext *avctx) {
|
|
|
|
|
#endif
|
|
|
|
|
xvid_gbl_init.cpu_flags = XVID_CPU_FORCE;
|
|
|
|
|
#else
|
|
|
|
|
/* XviD can detect on x86 */
|
|
|
|
|
/* Xvid can detect on x86 */
|
|
|
|
|
xvid_gbl_init.cpu_flags = 0;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
@ -189,7 +189,7 @@ av_cold int ff_xvid_encode_init(AVCodecContext *avctx) {
|
|
|
|
|
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 can determine the proper profile to use */
|
|
|
|
|
/* xvid_enc_create.profile = XVID_PROFILE_S_L3; */
|
|
|
|
|
|
|
|
|
|
/* We don't use zones */
|
|
|
|
@ -214,7 +214,7 @@ av_cold int ff_xvid_encode_init(AVCodecContext *avctx) {
|
|
|
|
|
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");
|
|
|
|
|
"Xvid: Cannot allocate 2-pass log buffers\n");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
x->twopassbuffer[0] = x->old_twopassbuffer[0] = 0;
|
|
|
|
@ -230,13 +230,13 @@ av_cold int ff_xvid_encode_init(AVCodecContext *avctx) {
|
|
|
|
|
fd = av_tempfile("xvidff.", &(x->twopassfile));
|
|
|
|
|
if( fd == -1 ) {
|
|
|
|
|
av_log(avctx, AV_LOG_ERROR,
|
|
|
|
|
"XviD: Cannot write 2-pass pipe\n");
|
|
|
|
|
"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");
|
|
|
|
|
"Xvid: No 2-pass information loaded for second pass\n");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -244,7 +244,7 @@ av_cold int ff_xvid_encode_init(AVCodecContext *avctx) {
|
|
|
|
|
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");
|
|
|
|
|
"Xvid: Cannot write to 2-pass pipe\n");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -278,7 +278,7 @@ av_cold int ff_xvid_encode_init(AVCodecContext *avctx) {
|
|
|
|
|
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 */
|
|
|
|
|
xvid_enc_create.max_key_interval = 240; /* Xvid's best default */
|
|
|
|
|
|
|
|
|
|
/* Quants */
|
|
|
|
|
if( xvid_flags & CODEC_FLAG_QSCALE ) x->qscale = 1;
|
|
|
|
@ -331,7 +331,7 @@ av_cold int ff_xvid_encode_init(AVCodecContext *avctx) {
|
|
|
|
|
x->quicktime_format = 1;
|
|
|
|
|
avctx->codec_id = CODEC_ID_MPEG4;
|
|
|
|
|
} else {
|
|
|
|
|
/* We are claiming to be XviD */
|
|
|
|
|
/* We are claiming to be Xvid */
|
|
|
|
|
x->quicktime_format = 0;
|
|
|
|
|
if(!avctx->codec_tag)
|
|
|
|
|
avctx->codec_tag = ff_get_fourcc("xvid");
|
|
|
|
@ -346,7 +346,7 @@ av_cold int ff_xvid_encode_init(AVCodecContext *avctx) {
|
|
|
|
|
/* 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");
|
|
|
|
|
av_log(avctx, AV_LOG_ERROR, "Xvid: Could not create encoder reference\n");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -383,13 +383,13 @@ int ff_xvid_encode_frame(AVCodecContext *avctx,
|
|
|
|
|
xvid_enc_stats.version = XVID_VERSION;
|
|
|
|
|
*p = *picture;
|
|
|
|
|
|
|
|
|
|
/* Let XviD know where to put the frame. */
|
|
|
|
|
/* 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");
|
|
|
|
|
av_log(avctx, AV_LOG_ERROR, "Xvid: Color spaces other than 420p not supported\n");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -461,14 +461,14 @@ int ff_xvid_encode_frame(AVCodecContext *avctx,
|
|
|
|
|
|
|
|
|
|
return xerr;
|
|
|
|
|
} else {
|
|
|
|
|
av_log(avctx, AV_LOG_ERROR, "XviD: Encoding Error Occurred: %i\n", xerr);
|
|
|
|
|
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.
|
|
|
|
|
* All buffers are freed, and the Xvid encoder context is destroyed.
|
|
|
|
|
*
|
|
|
|
|
* @param avctx AVCodecContext pointer to context
|
|
|
|
|
* @return Returns 0, success guaranteed
|
|
|
|
@ -496,7 +496,7 @@ av_cold int ff_xvid_encode_close(AVCodecContext *avctx) {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Routine to create a global VO/VOL header for MP4 container.
|
|
|
|
|
* What we do here is extract the header from the XviD bitstream
|
|
|
|
|
* 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.
|
|
|
|
@ -540,7 +540,7 @@ int xvid_strip_vol_header(AVCodecContext *avctx,
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Routine to correct a possibly erroneous framerate being fed to us.
|
|
|
|
|
* XviD currently chokes on framerates where the ticks per frame is
|
|
|
|
|
* 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.
|
|
|
|
@ -588,7 +588,7 @@ void xvid_correct_framerate(AVCodecContext *avctx) {
|
|
|
|
|
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",
|
|
|
|
|
"Xvid: framerate re-estimated: %.2f, %.3f%% correction\n",
|
|
|
|
|
est_fps, (((est_fps - fps)/fps) * 100.0));
|
|
|
|
|
} else {
|
|
|
|
|
avctx->time_base.den = frate;
|
|
|
|
@ -597,12 +597,12 @@ void xvid_correct_framerate(AVCodecContext *avctx) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* XviD 2-Pass Kludge Section
|
|
|
|
|
* Xvid 2-Pass Kludge Section
|
|
|
|
|
*
|
|
|
|
|
* XviD's default 2-pass doesn't allow us to create data as we need to, so
|
|
|
|
|
* 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
|
|
|
|
|
* that allows us to pass data to the second pass in Xvid without a custom
|
|
|
|
|
* rate-control plugin.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
@ -730,7 +730,7 @@ static int xvid_ff_2pass_after(xvid_context_t *ref,
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Dispatch function for our custom plugin.
|
|
|
|
|
* This handles the dispatch for the XviD plugin. It passes data
|
|
|
|
|
* 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
|
|
|
|
@ -763,7 +763,7 @@ int xvid_ff_2pass(void *ref, int cmd, void *p1, void *p2) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* XviD codec definition for libavcodec.
|
|
|
|
|
* Xvid codec definition for libavcodec.
|
|
|
|
|
*/
|
|
|
|
|
AVCodec libxvid_encoder = {
|
|
|
|
|
"libxvid",
|
|
|
|
|