summaryrefslogtreecommitdiffstats
path: root/core/XvidEnc.c
diff options
context:
space:
mode:
Diffstat (limited to 'core/XvidEnc.c')
-rw-r--r--core/XvidEnc.c118
1 files changed, 86 insertions, 32 deletions
diff --git a/core/XvidEnc.c b/core/XvidEnc.c
index 8f16ad4ba..2ca6bca6f 100644
--- a/core/XvidEnc.c
+++ b/core/XvidEnc.c
@@ -1,12 +1,13 @@
-/* $Id: XvidEnc.c,v 1.5 2003/11/05 19:14:37 titer Exp $
+/* $Id: XvidEnc.c,v 1.7 2003/11/09 21:26:52 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://handbrake.m0k.org/>.
It may be used under the terms of the GNU General Public License. */
-#include "XvidEnc.h"
#include "Fifo.h"
#include "Work.h"
+#include "XvidEnc.h"
+#include "XvidVbr.h"
#include <xvid.h>
@@ -20,9 +21,11 @@ struct HBXvidEnc
HBHandle * handle;
HBTitle * title;
- void * xvid;
- HBBuffer * mpeg4Buffer;
- int pass;
+ void * xvid;
+ vbr_control_t xvidVbr;
+ XVID_ENC_FRAME frame;
+ HBBuffer * mpeg4Buffer;
+ int pass;
};
HBXvidEnc * HBXvidEncInit( HBHandle * handle, HBTitle * title )
@@ -41,6 +44,18 @@ HBXvidEnc * HBXvidEncInit( HBHandle * handle, HBTitle * title )
x->title = title;
x->xvid = NULL;
+
+ x->frame.general = XVID_H263QUANT | XVID_HALFPEL | XVID_INTER4V;
+ x->frame.motion = PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 |
+ PMV_EXTSEARCH16 | PMV_EARLYSTOP8 |
+ PMV_HALFPELREFINE8 | PMV_HALFPELDIAMOND8 |
+ PMV_USESQUARES16;
+
+ x->frame.colorspace = XVID_CSP_I420;
+
+ x->frame.quant_intra_matrix = NULL;
+ x->frame.quant_inter_matrix = NULL;
+
x->mpeg4Buffer = NULL;
x->pass = 42;
@@ -50,7 +65,18 @@ HBXvidEnc * HBXvidEncInit( HBHandle * handle, HBTitle * title )
void HBXvidEncClose( HBXvidEnc ** _x )
{
HBXvidEnc * x = *_x;
+
+ if( x->xvid )
+ {
+ HBLog( "HBXvidEnc: closing libxvidcore (pass %d)",
+ x->pass );
+
+ xvid_encore( x->xvid, XVID_ENC_DESTROY, NULL, NULL);
+ vbrFinish( &x->xvidVbr );
+ }
+
free( x );
+
*_x = NULL;
}
@@ -60,7 +86,7 @@ static int XvidEncWork( HBWork * w )
HBTitle * title = x->title;
HBBuffer * scaledBuffer;
HBBuffer * mpeg4Buffer;
- XVID_ENC_FRAME xframe;
+ XVID_ENC_STATS stats;
int didSomething = 0;
@@ -91,6 +117,15 @@ static int XvidEncWork( HBWork * w )
XVID_INIT_PARAM xinit;
XVID_ENC_PARAM xparam;
+ if( x->xvid )
+ {
+ HBLog( "HBXvidEnc: closing libxvidcore (pass %d)",
+ x->pass );
+
+ xvid_encore( x->xvid, XVID_ENC_DESTROY, NULL, NULL);
+ vbrFinish( &x->xvidVbr );
+ }
+
x->pass = scaledBuffer->pass;;
HBLog( "HBXvidEnc: opening libxvidcore (pass %d)", x->pass );
@@ -100,11 +135,11 @@ static int XvidEncWork( HBWork * w )
xparam.width = title->outWidth;
xparam.height = title->outHeight;
-
+
xparam.fincr = title->rateBase;
xparam.fbase = title->rate;
- xparam.rc_bitrate = title->bitrate * 1000;
+ xparam.rc_bitrate = title->bitrate * 1024;
/* Default values should be ok */
xparam.rc_reaction_delay_factor = -1;
@@ -120,51 +155,70 @@ static int XvidEncWork( HBWork * w )
}
x->xvid = xparam.handle;
- }
- /* TODO implement 2-pass encoding */
- if( x->pass == 1 )
- {
- HBPosition( x->handle, scaledBuffer->position );
- HBBufferClose( &scaledBuffer );
- return didSomething;
+ /* Init VBR engine */
+ vbrSetDefaults( &x->xvidVbr );
+ if( !x->pass )
+ {
+ x->xvidVbr.mode = VBR_MODE_1PASS;
+ }
+ else if( x->pass == 1 )
+ {
+ x->xvidVbr.mode = VBR_MODE_2PASS_1;
+ }
+ else
+ {
+ x->xvidVbr.mode = VBR_MODE_2PASS_2;
+ }
+ x->xvidVbr.fps = (double) title->rate / title->rateBase;
+ x->xvidVbr.debug = 0;
+ x->xvidVbr.filename = malloc( 1024 );
+ memset( x->xvidVbr.filename, 0, 1024 );
+ snprintf( x->xvidVbr.filename, 1023, "/tmp/HB.%d.xvid.log",
+ HBGetPid( x->handle ) );
+ x->xvidVbr.desired_bitrate = title->bitrate * 1024;
+ x->xvidVbr.max_key_interval = 10 * title->rate / title->rateBase;
+
+ vbrInit( &x->xvidVbr );
}
mpeg4Buffer = HBBufferInit( title->outWidth *
title->outHeight * 3 / 2 );
mpeg4Buffer->position = scaledBuffer->position;
- xframe.general = XVID_H263QUANT | XVID_HALFPEL | XVID_INTER4V;
- xframe.motion = PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 |
- PMV_EXTSEARCH16 | PMV_EARLYSTOP8 |
- PMV_HALFPELREFINE8 | PMV_HALFPELDIAMOND8 |
- PMV_USESQUARES16;
- xframe.bitstream = mpeg4Buffer->data;
+ x->frame.bitstream = mpeg4Buffer->data;
+ x->frame.length = -1;
- xframe.image = scaledBuffer->data;
- xframe.colorspace = XVID_CSP_I420;
+ x->frame.image = scaledBuffer->data;
- xframe.quant_intra_matrix = NULL;
- xframe.quant_inter_matrix = NULL;
- xframe.quant = 0;
- xframe.intra = -1;
+ x->frame.quant = vbrGetQuant( &x->xvidVbr );
+ x->frame.intra = vbrGetIntra( &x->xvidVbr );
- xframe.hint.hintstream = NULL;
+ x->frame.hint.hintstream = NULL;
- if( xvid_encore( x->xvid, XVID_ENC_ENCODE, &xframe, NULL ) )
+ if( xvid_encore( x->xvid, XVID_ENC_ENCODE, &x->frame, &stats ) )
{
HBLog( "HBXvidEnc: xvid_encore() failed" );
}
- mpeg4Buffer->size = xframe.length;
- mpeg4Buffer->keyFrame = xframe.intra;
+ vbrUpdate( &x->xvidVbr, stats.quant, x->frame.intra, stats.hlength,
+ x->frame.length, stats.kblks, stats.mblks, stats.ublks );
+
+ mpeg4Buffer->size = x->frame.length;
+ mpeg4Buffer->keyFrame = x->frame.intra;
/* Inform the GUI about the current position */
HBPosition( x->handle, scaledBuffer->position );
HBBufferClose( &scaledBuffer );
- x->mpeg4Buffer = mpeg4Buffer;
+ if( x->pass == 1 )
+ {
+ HBBufferClose( &mpeg4Buffer );
+ return didSomething;
+ }
+
+ x->mpeg4Buffer = mpeg4Buffer;
return didSomething;
}