summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/Ac3Dec.c186
-rw-r--r--core/AviMux.c571
-rw-r--r--core/DVDRead.c45
-rw-r--r--core/FaacEnc.c180
-rw-r--r--core/FfmpegEnc.c175
-rw-r--r--core/Fifo.c15
-rw-r--r--core/Fifo.h84
-rw-r--r--core/HBInternal.h25
-rw-r--r--core/HandBrake.c108
-rw-r--r--core/Jamfile15
-rw-r--r--core/LpcmDec.c139
-rw-r--r--core/MadDec.c8
-rw-r--r--core/Mp3Enc.c251
-rw-r--r--core/Mp4Mux.c270
-rw-r--r--core/Mpeg2Dec.c128
-rw-r--r--core/MpgaDec.c132
-rw-r--r--core/Mux.c228
-rw-r--r--core/Mux.h21
-rw-r--r--core/OgmMux.c531
-rw-r--r--core/Resample.c159
-rw-r--r--core/Scale.c194
-rw-r--r--core/Scan.c327
-rw-r--r--core/Thread.c12
-rw-r--r--core/Utils.c31
-rw-r--r--core/Utils.h70
-rw-r--r--core/VorbisEnc.c222
-rw-r--r--core/Work.c7
-rw-r--r--core/X264Enc.c126
-rw-r--r--core/XvidEnc.c234
29 files changed, 2207 insertions, 2287 deletions
diff --git a/core/Ac3Dec.c b/core/Ac3Dec.c
index 3fb4cc0ae..ef805588c 100644
--- a/core/Ac3Dec.c
+++ b/core/Ac3Dec.c
@@ -1,4 +1,4 @@
-/* $Id: Ac3Dec.c,v 1.13 2004/03/08 11:32:48 titer Exp $
+/* $Id: Ac3Dec.c,v 1.17 2004/05/02 16:25:00 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://handbrake.m0k.org/>.
@@ -9,7 +9,7 @@
/* liba52 */
#include "a52dec/a52.h"
-typedef struct HBAc3Dec
+struct HBWork
{
HB_WORK_COMMON_MEMBERS
@@ -24,195 +24,131 @@ typedef struct HBAc3Dec
/* Buffers */
uint8_t ac3Frame[3840]; /* Max size of a A52 frame */
- int ac3FrameSize; /* In bytes */
- HBBuffer * ac3Buffer;
- int ac3BufferPos; /* In bytes */
- int nextFrameSize; /* In bytes */
- float position;
- HBBuffer * rawBuffer;
-} HBAc3Dec;
+ int hasSync;
+ int nextFrameSize;
+};
/* Local prototypes */
static int Ac3DecWork( HBWork * );
-static int GetBytes( HBAc3Dec *, int );
HBWork * HBAc3DecInit( HBHandle * handle, HBAudio * audio )
{
- HBAc3Dec * a;
- if( !( a = malloc( sizeof( HBAc3Dec ) ) ) )
+ HBWork * w;
+ if( !( w = calloc( sizeof( HBWork ), 1 ) ) )
{
HBLog( "HBAc3DecInit: malloc() failed, gonna crash" );
return NULL;
}
- a->name = strdup( "Ac3Dec" );
- a->work = Ac3DecWork;
+ w->name = strdup( "Ac3Dec" );
+ w->work = Ac3DecWork;
- a->handle = handle;
- a->audio = audio;
+ w->handle = handle;
+ w->audio = audio;
/* Init liba52 */
- a->state = a52_init( 0 );
- a->inFlags = 0;
+ w->state = a52_init( 0 );
/* Let it do the downmixing */
- a->outFlags = A52_STEREO;
-
- if( audio->outCodec == HB_CODEC_MP3 )
- /* Lame wants 16 bits samples */
- a->sampleLevel = 32768.0;
- else if( audio->outCodec == HB_CODEC_AAC )
- /* Faac wants 24 bits samples */
- a->sampleLevel = 8388608.0;
- else if( audio->outCodec == HB_CODEC_VORBIS )
- /* Vorbis wants FIXME bits samples */
- a->sampleLevel = 32768.0;
-
- a->ac3FrameSize = 0;
- a->ac3Buffer = NULL;
- a->ac3BufferPos = 0;
- a->nextFrameSize = 0;
- a->position = 0.0;
- a->rawBuffer = NULL;
-
- return (HBWork*) a;
+ w->outFlags = A52_STEREO;
+
+ /* 16 bits samples */
+ w->sampleLevel = 32768.0;
+
+ return w;
}
-void HBAc3DecClose( HBWork ** _a )
+void HBAc3DecClose( HBWork ** _w )
{
- HBAc3Dec * a = (HBAc3Dec*) *_a;
+ HBWork * w = *_w;
- if( a->ac3Buffer ) HBBufferClose( &a->ac3Buffer );
- if( a->rawBuffer ) HBBufferClose( &a->rawBuffer );
- a52_free( a->state );
- free( a->name );
- free( a );
+ a52_free( w->state );
+ free( w->name );
+ free( w );
- *_a = NULL;
+ *_w = NULL;
}
static int Ac3DecWork( HBWork * w )
{
- HBAc3Dec * a = (HBAc3Dec*) w;
- HBAudio * audio = a->audio;
+ HBAudio * audio = w->audio;
- int didSomething = 0;
+ float position;
- /* Push decoded buffer */
- if( a->rawBuffer )
+ if( HBFifoIsHalfFull( audio->rawFifo ) )
{
- if( HBFifoPush( audio->rawFifo, &a->rawBuffer ) )
- {
- didSomething = 1;
- }
- else
- {
- return didSomething;
- }
+ return 0;
}
/* Get a frame header (7 bytes) */
- if( a->ac3FrameSize < 7 )
+ if( !w->hasSync )
{
- if( GetBytes( a, 7 ) )
+ if( !HBFifoGetBytes( audio->inFifo, w->ac3Frame, 7,
+ &position ) )
{
- didSomething = 1;
- }
- else
- {
- return didSomething;
+ return 0;
}
- a->nextFrameSize = a52_syncinfo( a->ac3Frame, &a->inFlags,
+ /* Check the header */
+ w->nextFrameSize = a52_syncinfo( w->ac3Frame, &w->inFlags,
&audio->inSampleRate,
&audio->inBitrate );
- if( !a->nextFrameSize )
+ if( !w->nextFrameSize )
{
HBLog( "HBAc3Dec: a52_syncinfo() failed" );
- HBErrorOccured( a->handle, HB_ERROR_A52_SYNC );
- return didSomething;
+ HBErrorOccured( w->handle, HB_ERROR_A52_SYNC );
+ return 0;
}
+
+ w->hasSync = 1;
}
/* Get the whole frame */
- if( a->ac3FrameSize >= 7 )
+ if( w->hasSync )
{
sample_t * samples;
HBBuffer * rawBuffer;
int i;
- if( GetBytes( a, a->nextFrameSize ) )
- {
- didSomething = 1;
- }
- else
+ if( !HBFifoGetBytes( audio->inFifo, w->ac3Frame + 7,
+ w->nextFrameSize - 7, &position ) )
{
- return didSomething;
+ return 0;
}
+ w->hasSync = 0;
+
/* Feed liba52 */
- a52_frame( a->state, a->ac3Frame, &a->outFlags,
- &a->sampleLevel, 0 );
- a->ac3FrameSize = 0;
+ a52_frame( w->state, w->ac3Frame, &w->outFlags,
+ &w->sampleLevel, 0 );
/* 6 blocks per frame, 256 samples per block, 2 channels */
- rawBuffer = HBBufferInit( 12 * 256 * sizeof( float ) );
- rawBuffer->position = a->position;
- rawBuffer->samples = 6 * 256;
- rawBuffer->left = (float*) rawBuffer->data;
- rawBuffer->right = rawBuffer->left + 6 * 256;
+ rawBuffer = HBBufferInit( 3072 * sizeof( float ) );
+ rawBuffer->position = position;
for( i = 0; i < 6; i++ )
{
- /* Decode a block */
- a52_block( a->state );
+ int j;
- /* Get a pointer to the raw data */
- samples = a52_samples( a->state );
-
- /* Copy left channel data */
- memcpy( rawBuffer->left + i * 256, samples,
- 256 * sizeof( float ) );
-
- /* Copy right channel data */
- memcpy( rawBuffer->right + i * 256, samples + 256,
- 256 * sizeof( float ) );
- }
-
- a->rawBuffer = rawBuffer;
- }
-
- return didSomething;
-}
+ /* Decode a block */
+ a52_block( w->state );
-static int GetBytes( HBAc3Dec * a, int size )
-{
- int i;
+ /* Get a pointer to the float samples */
+ samples = a52_samples( w->state );
- while( a->ac3FrameSize < size )
- {
- if( !a->ac3Buffer )
- {
- if( !( a->ac3Buffer = HBFifoPop( a->audio->inFifo ) ) )
+ /* Interleave samples */
+ for( j = 0; j < 256; j++ )
{
- return 0;
+ rawBuffer->dataf[512*i+2*j] = samples[j];
+ rawBuffer->dataf[512*i+2*j+1] = samples[256+j];
}
- a->ac3BufferPos = 0;
- a->position = a->ac3Buffer->position;
}
- i = MIN( size - a->ac3FrameSize,
- a->ac3Buffer->size - a->ac3BufferPos );
- memcpy( a->ac3Frame + a->ac3FrameSize,
- a->ac3Buffer->data + a->ac3BufferPos,
- i );
- a->ac3FrameSize += i;
- a->ac3BufferPos += i;
-
- if( a->ac3BufferPos == a->ac3Buffer->size )
+ /* Send decoded data to the resampler */
+ if( !HBFifoPush( audio->rawFifo, &rawBuffer ) )
{
- HBBufferClose( &a->ac3Buffer );
+ HBLog( "HBAc3Dec: HBFifoPush failed" );
}
}
diff --git a/core/AviMux.c b/core/AviMux.c
index 444d77adc..c0209dd49 100644
--- a/core/AviMux.c
+++ b/core/AviMux.c
@@ -1,4 +1,4 @@
-/* $Id: AviMux.c,v 1.17 2004/03/16 16:11:29 titer Exp $
+/* $Id: AviMux.c,v 1.24 2004/05/12 18:02:35 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://handbrake.m0k.org/>.
@@ -6,33 +6,12 @@
#include "HBInternal.h"
-int64_t videoFrames;
-int64_t videoBytes;
-int64_t audioFrames;
-int64_t audioBytes;
-
-/* Local prototypes */
-static void AviMuxThread( void * );
-static void InitAviHeaders( HBAviMux * );
-static void AddChunk( HBAviMux *, HBBuffer *, uint32_t,
- HBAviStreamHeader * );
-static void AddIndex( HBAviMux * );
-static void WriteInt8( FILE *, uint8_t );
-static void WriteInt16( FILE *, uint16_t );
-static void WriteInt32( FILE *, uint32_t );
-static void WriteBuffer( FILE *, HBBuffer * );
-static void WriteMainHeader( FILE *, HBAviMainHeader * );
-static void WriteStreamHeader( FILE *, HBAviStreamHeader * );
-static void WriteHBBitmapInfo( FILE *, HBBitmapInfo * );
-static void WriteHBWaveFormatEx( FILE *, HBWaveFormatEx * );
-static void IndexAddInt32( HBBuffer * buffer, uint32_t );
-
#define AVIF_HASINDEX 0x10
#define AVIIF_KEYFRAME 0x10
#define FOURCC(a) ((a[3]<<24)|(a[2]<<16)|(a[1]<<8)|a[0])
/* Structures definitions */
-struct __attribute__((__packed__)) HBAviMainHeader
+typedef struct __attribute__((__packed__))
{
uint32_t FourCC;
uint32_t BytesCount;
@@ -47,9 +26,10 @@ struct __attribute__((__packed__)) HBAviMainHeader
uint32_t Width;
uint32_t Height;
uint32_t Reserved[4];
-};
-struct __attribute__((__packed__)) HBAviStreamHeader
+} HBAviMainHeader;
+
+typedef struct __attribute__((__packed__))
{
uint32_t FourCC;
uint32_t BytesCount;
@@ -70,9 +50,10 @@ struct __attribute__((__packed__)) HBAviStreamHeader
int16_t Top;
int16_t Right;
int16_t Bottom;
-};
-struct __attribute__((__packed__)) HBBitmapInfo
+} HBAviStreamHeader;
+
+typedef struct __attribute__((__packed__))
{
uint32_t FourCC;
uint32_t BytesCount;
@@ -87,9 +68,10 @@ struct __attribute__((__packed__)) HBBitmapInfo
uint32_t YPelsPerMeter;
uint32_t ClrUsed;
uint32_t ClrImportant;
-};
-struct __attribute__((__packed__)) HBWaveFormatEx
+} HBBitmapInfo;
+
+typedef struct __attribute__((__packed__))
{
uint32_t FourCC;
uint32_t BytesCount;
@@ -107,10 +89,13 @@ struct __attribute__((__packed__)) HBWaveFormatEx
uint16_t BlockSize;
uint16_t FramesPerBlock;
uint16_t CodecDelay;
-};
-struct HBAviMux
+} HBWaveFormatEx;
+
+struct HBMux
{
+ HB_MUX_COMMON_MEMBERS
+
HBHandle * handle;
HBTitle * title;
@@ -119,284 +104,191 @@ struct HBAviMux
FILE * file;
HBBuffer * index;
-
- volatile int die;
- HBThread * thread;
};
-HBAviMux * HBAviMuxInit( HBHandle * handle, HBTitle * title )
+typedef struct
{
- HBAviMux * a;
- if( !( a = malloc( sizeof( HBAviMux ) ) ) )
- {
- HBLog( "HBAviMuxInit: malloc() failed, gonna crash" );
- return NULL;
- }
-
- a->handle = handle;
- a->title = title;
-
- videoFrames = 0;
- videoBytes = 0;
- audioFrames = 0;
- audioBytes = 0;
+ HBAviMainHeader mainHeader;
+ HBAviStreamHeader videoHeader;
+ HBBitmapInfo videoFormat;
- a->size = 0;
- a->file = NULL;
- a->index = HBBufferInit( 1024 * 1024 );
- a->index->size = 0;
+} AviVideoMuxData;
- a->die = 0;
- a->thread = HBThreadInit( "avi muxer", AviMuxThread, a,
- HB_NORMAL_PRIORITY );
- return a;
-}
-
-void HBAviMuxClose( HBAviMux ** _a )
+typedef struct
{
- HBAviMux * a = *_a;
- FILE * file;
- long size;
-
- a->die = 1;
- HBThreadClose( &a->thread );
-
-#ifndef HB_CYGWIN
- file = fopen( a->title->file, "r" );
-#else
- file = fopen( a->title->file, "rb" );
-#endif
- if( file )
- {
- fseek( file, 0, SEEK_END );
- size = ftell( file );
- fclose( file );
-
- HBLog( "HBAviMux: videoFrames=%lld, %lld bytes",
- videoFrames, videoBytes );
- HBLog( "HBAviMux: audioFrames=%lld, %lld bytes",
- audioFrames, audioBytes );
- HBLog( "HBAviMux: overhead=%.2f bytes / frame",
- ( (float) size - videoBytes - audioBytes ) /
- ( videoFrames + audioFrames ) );
- }
+ uint32_t fourCC;
+ HBAviStreamHeader audioHeader;
+ HBWaveFormatEx audioFormat;
- free( a );
+} AviAudioMuxData;
- *_a = NULL;
-}
-
-static void AviMuxThread( void * _a )
+/* Local prototypes */
+static int AviStart( HBMux * );
+static int AviMuxVideo( HBMux *, void *, HBBuffer *);
+static int AviMuxAudio( HBMux *, void *, HBBuffer *);
+static int AviEnd( HBMux * );
+
+static void AddChunk( HBMux *, HBBuffer *, uint32_t,
+ HBAviStreamHeader * );
+static void AddIndex( HBMux * );
+static void WriteInt8( FILE *, uint8_t );
+static void WriteInt16( FILE *, uint16_t );
+static void WriteInt32( FILE *, uint32_t );
+static void WriteBuffer( FILE *, HBBuffer * );
+static void WriteMainHeader( FILE *, HBAviMainHeader * );
+static void WriteStreamHeader( FILE *, HBAviStreamHeader * );
+static void WriteHBBitmapInfo( FILE *, HBBitmapInfo * );
+static void WriteHBWaveFormatEx( FILE *, HBWaveFormatEx * );
+static void IndexAddInt32( HBBuffer * buffer, uint32_t );
+
+HBMux * HBAviMuxInit( HBHandle * handle, HBTitle * title )
{
- HBAviMux * a = (HBAviMux*) _a;
- HBTitle * title = a->title;
- int audioCount = HBListCount( title->ripAudioList );
-
- HBAudio * audio;
- HBBuffer * buffer;
+ HBMux * m;
+ HBAudio * audio;
int i;
- /* Open destination file */
- HBLog( "HBAviMux: opening %s", title->file );
-#ifndef HB_CYGWIN
- if( !( a->file = fopen( title->file, "w" ) ) )
-#else
- if( !( a->file = fopen( title->file, "wb" ) ) )
-#endif
- {
- HBLog( "HBAviMux: fopen() failed" );
- HBErrorOccured( a->handle, HB_ERROR_AVI_WRITE );
- return;
- }
-
- /* Wait until we have one encoded frame for each track */
- while( !a->die && !HBFifoSize( title->outFifo ) )
+ if( !( m = calloc( sizeof( HBMux ), 1 ) ) )
{
- HBSnooze( 10000 );
+ HBLog( "HBAviMux: malloc() failed, gonna crash" );
+ return NULL;
}
- for( i = 0; i < audioCount; i++ )
+ m->start = AviStart;
+ m->muxVideo = AviMuxVideo;
+ m->muxAudio = AviMuxAudio;
+ m->end = AviEnd;
+ m->handle = handle;
+ m->title = title;
+
+ m->file = NULL;
+ m->index = HBBufferInit( 1024 * 1024 );
+ m->index->size = 0;
+
+ /* Alloc muxer data */
+ title->muxData = calloc( sizeof( AviVideoMuxData ), 1 );
+ for( i = 0; i < HBListCount( title->ripAudioList ); i++ )
{
- audio = HBListItemAt( title->ripAudioList, i );
- while( !a->die && !HBFifoSize( audio->outFifo ) )
- {
- HBSnooze( 10000 );
- }
+ audio = (HBAudio *) HBListItemAt( title->ripAudioList, i );
+ audio->muxData = calloc( sizeof( AviAudioMuxData ), 1 );
}
- if( a->die )
- {
- fclose( a->file );
- a->file = NULL;
-
- HBLog( "HBAviMux: deleting %s", title->file );
- unlink( title->file );
- return;
- }
+ return m;
+}
- InitAviHeaders( a );
+void HBAviMuxClose( HBMux ** _m )
+{
+ HBMux * m = *_m;
+ HBTitle * title = m->title;
+ HBAudio * audio;
+ int i;
- for( ;; )
+ /* Free muxer data */
+ free( title->muxData );
+ for( i = 0; i < HBListCount( title->ripAudioList ); i++ )
{
- /* Wait until we have one encoded frame for each track */
- if( !HBFifoWait( title->outFifo ) )
- {
- a->die = 1;
- }
- for( i = 0; i < audioCount; i++ )
- {
- audio = HBListItemAt( title->ripAudioList, i );
- if( !HBFifoWait( audio->outFifo ) )
- {
- a->die = 1;
- break;
- }
- }
-
- if( a->die )
- {
- break;
- }
-
- /* Interleave frames in the same order than they were in the
- original MPEG stream */
- audio = NULL;
- for( i = 0; i < audioCount; i++ )
- {
- HBAudio * otherAudio;
- otherAudio = HBListItemAt( title->ripAudioList, i );
- if( !audio || HBFifoPosition( otherAudio->outFifo ) <
- HBFifoPosition( audio->outFifo ) )
- {
- audio = otherAudio;
- }
- }
-
- if( audio == NULL ||
- HBFifoPosition( title->outFifo ) < HBFifoPosition( audio->outFifo ) )
- {
- buffer = HBFifoPop( title->outFifo );
- AddChunk( a, buffer, FOURCC( "00dc" ), title->aviVideoHeader );
- videoFrames++;
- videoBytes += buffer->size;
- HBBufferClose( &buffer );
- }
- else
- {
- buffer = HBFifoPop( audio->outFifo );
- AddChunk( a, buffer, audio->aviFourCC, audio->aviAudioHeader );
- audioFrames++;
- audioBytes += buffer->size;
- HBBufferClose( &buffer );
- }
+ audio = (HBAudio *) HBListItemAt( title->ripAudioList, i );
+ free( audio->muxData );
}
- AddIndex( a );
+ HBBufferClose( &m->index );
- HBLog( "HBAviMux: closing %s", title->file );
- fclose( a->file );
+ free( m );
+
+ *_m = NULL;
}
-static void InitAviHeaders( HBAviMux * a )
+#define mh videoMuxData->mainHeader
+#define vh videoMuxData->videoHeader
+#define vf videoMuxData->videoFormat
+#define ah audioMuxData->audioHeader
+#define af audioMuxData->audioFormat
+static int AviStart( HBMux * m )
{
- HBTitle * title = a->title;
- FILE * file = a->file;
- int audioCount = HBListCount( title->ripAudioList );
-
- HBAudio * audio;
- HBAviMainHeader * mainHeader;
- HBAviStreamHeader * videoHeader;
- HBBitmapInfo * videoFormat;
- HBAviStreamHeader * audioHeader;
- HBWaveFormatEx * audioFormat;
- int hdrlBytes;
- int i;
-
- /* AVI main header */
- mainHeader = calloc( sizeof( HBAviMainHeader ), 1 );
+ HBTitle * title = m->title;
+ int audioCount = HBListCount( title->ripAudioList );
+ AviVideoMuxData * videoMuxData = (AviVideoMuxData *) title->muxData;
+ AviAudioMuxData * audioMuxData;
+ HBAudio * audio;
+ int hdrlBytes;
+ int i;
- mainHeader->FourCC = FOURCC( "avih" );
- mainHeader->BytesCount = sizeof( HBAviMainHeader ) - 8;
- mainHeader->MicroSecPerFrame = (uint64_t) 1000000 *
- title->rateBase / title->rate;
- mainHeader->Streams = 1 + audioCount;
- mainHeader->Width = title->outWidth;
- mainHeader->Height = title->outHeight;
+ /* Open destination file */
+ HBLog( "HBAviMux: opening %s", title->file );
+ if( !( m->file = fopen( title->file, "wb" ) ) )
+ {
+ HBLog( "HBAviMux: fopen() failed" );
+ HBErrorOccured( m->handle, HB_ERROR_AVI_WRITE );
+ return 1;
+ }
- title->aviMainHeader = mainHeader;
+ /* AVI main header */
+ mh.FourCC = FOURCC( "avih" );
+ mh.BytesCount = sizeof( HBAviMainHeader ) - 8;
+ mh.MicroSecPerFrame = (uint64_t) 1000000 * title->rateBase /
+ title->rate;
+ mh.Streams = 1 + audioCount;
+ mh.Width = title->outWidth;
+ mh.Height = title->outHeight;
/* Video stream header */
- videoHeader = calloc( sizeof( HBAviStreamHeader ), 1 );
-
- videoHeader->FourCC = FOURCC( "strh" );
- videoHeader->BytesCount = sizeof( HBAviStreamHeader ) - 8;
- videoHeader->Type = FOURCC( "vids" );
+ vh.FourCC = FOURCC( "strh" );
+ vh.BytesCount = sizeof( HBAviStreamHeader ) - 8;
+ vh.Type = FOURCC( "vids" );
if( title->codec == HB_CODEC_FFMPEG )
- videoHeader->Handler = FOURCC( "divx" );
+ vh.Handler = FOURCC( "divx" );
else if( title->codec == HB_CODEC_XVID )
- videoHeader->Handler = FOURCC( "xvid" );
+ vh.Handler = FOURCC( "xvid" );
else if( title->codec == HB_CODEC_X264 )
- videoHeader->Handler = FOURCC( "H264" );
-
- videoHeader->Scale = title->rateBase;
- videoHeader->Rate = title->rate;
+ vh.Handler = FOURCC( "h264" );
- title->aviVideoHeader = videoHeader;
+ vh.Scale = title->rateBase;
+ vh.Rate = title->rate;
/* Video stream format */
- videoFormat = calloc( sizeof( HBBitmapInfo ), 1 );
-
- videoFormat->FourCC = FOURCC( "strf" );
- videoFormat->BytesCount = sizeof( HBBitmapInfo ) - 8;
- videoFormat->Size = sizeof( HBBitmapInfo ) - 8;
- videoFormat->Width = title->outWidth;
- videoFormat->Height = title->outHeight;
- videoFormat->Planes = 1;
- videoFormat->BitCount = 24;
+ vf.FourCC = FOURCC( "strf" );
+ vf.BytesCount = sizeof( HBBitmapInfo ) - 8;
+ vf.Size = sizeof( HBBitmapInfo ) - 8;
+ vf.Width = title->outWidth;
+ vf.Height = title->outHeight;
+ vf.Planes = 1;
+ vf.BitCount = 24;
if( title->codec == HB_CODEC_FFMPEG )
- videoFormat->Compression = FOURCC( "DX50" );
+ vf.Compression = FOURCC( "DX50" );
else if( title->codec == HB_CODEC_XVID )
- videoFormat->Compression = FOURCC( "XVID" );
+ vf.Compression = FOURCC( "XVID" );
else if( title->codec == HB_CODEC_X264 )
- videoFormat->Compression = FOURCC( "H264" );
-
- title->aviVideoFormat = videoFormat;
+ vf.Compression = FOURCC( "H264" );
for( i = 0; i < audioCount; i++ )
{
- audio = HBListItemAt( title->ripAudioList, i );
+ audio = HBListItemAt( title->ripAudioList, i );
+ audioMuxData = (AviAudioMuxData *) audio->muxData;
/* Audio stream header */
- audioHeader = calloc( sizeof( HBAviStreamHeader ), 1 );
-
- audioHeader->FourCC = FOURCC( "strh" );
- audioHeader->BytesCount = sizeof( HBAviStreamHeader ) - 8;
- audioHeader->Type = FOURCC( "auds" );
- audioHeader->InitialFrames = 1;
- audioHeader->Scale = 1152;
- audioHeader->Rate = audio->outSampleRate;
- audioHeader->Quality = 0xFFFFFFFF;
-
- audio->aviAudioHeader = audioHeader;
+ ah.FourCC = FOURCC( "strh" );
+ ah.BytesCount = sizeof( HBAviStreamHeader ) - 8;
+ ah.Type = FOURCC( "auds" );
+ ah.InitialFrames = 1;
+ ah.Scale = 1;
+ ah.Rate = audio->outBitrate * 1000 / 8;
+ ah.SampleSize = 1;
+ ah.Quality = 0xFFFFFFFF;
/* Audio stream format */
- audioFormat = calloc( sizeof( HBWaveFormatEx ), 1 );
-
- audioFormat->FourCC = FOURCC( "strf" );
- audioFormat->BytesCount = sizeof( HBWaveFormatEx ) - 8;
- audioFormat->FormatTag = 0x55;
- audioFormat->Channels = 2;
- audioFormat->SamplesPerSec = audio->outSampleRate;
- audioFormat->AvgBytesPerSec = audio->outBitrate * 1024 / 8;
- audioFormat->BlockAlign = 1152;
- audioFormat->Size = 12;
- audioFormat->Id = 1;
- audioFormat->Flags = 2;
- audioFormat->BlockSize = 1152;
- audioFormat->FramesPerBlock = 1;
- audioFormat->CodecDelay = 1393;
-
- audio->aviAudioFormat = audioFormat;
+ af.FourCC = FOURCC( "strf" );
+ af.BytesCount = sizeof( HBWaveFormatEx ) - 8;
+ af.FormatTag = 0x55;
+ af.Channels = 2;
+ af.SamplesPerSec = audio->outSampleRate;
+ af.AvgBytesPerSec = audio->outBitrate * 1000 / 8;
+ af.BlockAlign = 1;
+ af.Size = 12;
+ af.Id = 1;
+ af.Flags = 2;
+ af.BlockSize = 1152 * af.AvgBytesPerSec /
+ audio->outSampleRate;
+ af.FramesPerBlock = 1;
+ af.CodecDelay = 1393;
}
hdrlBytes = 4 + sizeof( HBAviMainHeader ) + ( 1 + audioCount ) *
@@ -405,114 +297,147 @@ static void InitAviHeaders( HBAviMux * a )
/* Here we really start to write into the file */
- WriteInt32( file, FOURCC( "RIFF" ) );
- WriteInt32( file, 2040 );
- WriteInt32( file, FOURCC( "AVI " ) );
- WriteInt32( file, FOURCC( "LIST" ) );
- WriteInt32( file, hdrlBytes );
- WriteInt32( file, FOURCC( "hdrl" ) );
- WriteMainHeader( file, title->aviMainHeader );
- WriteInt32( file, FOURCC( "LIST" ) );
- WriteInt32( file, 4 + sizeof( HBAviStreamHeader ) +
- sizeof( HBBitmapInfo ) );
- WriteInt32( file, FOURCC( "strl" ) );
- WriteStreamHeader( file, title->aviVideoHeader );
- WriteHBBitmapInfo( file, title->aviVideoFormat );
+ WriteInt32( m->file, FOURCC( "RIFF" ) );
+ WriteInt32( m->file, 2040 );
+ WriteInt32( m->file, FOURCC( "AVI " ) );
+ WriteInt32( m->file, FOURCC( "LIST" ) );
+ WriteInt32( m->file, hdrlBytes );
+ WriteInt32( m->file, FOURCC( "hdrl" ) );
+ WriteMainHeader( m->file, &mh );
+ WriteInt32( m->file, FOURCC( "LIST" ) );
+ WriteInt32( m->file, 4 + sizeof( HBAviStreamHeader ) +
+ sizeof( HBBitmapInfo ) );
+ WriteInt32( m->file, FOURCC( "strl" ) );
+ WriteStreamHeader( m->file, &vh );
+ WriteHBBitmapInfo( m->file, &vf );
for( i = 0; i < audioCount; i++ )
{
char fourCC[5];
audio = HBListItemAt( title->ripAudioList, i );
+ audioMuxData = (AviAudioMuxData *) audio->muxData;
snprintf( fourCC, 5, "%02dwb", i + 1 );
- audio->aviFourCC = FOURCC( fourCC );
+ audioMuxData->fourCC = FOURCC( fourCC );
- WriteInt32( file, FOURCC( "LIST" ) );
- WriteInt32( file, 4 + sizeof( HBAviStreamHeader ) +
+ WriteInt32( m->file, FOURCC( "LIST" ) );
+ WriteInt32( m->file, 4 + sizeof( HBAviStreamHeader ) +
sizeof( HBWaveFormatEx ) );
- WriteInt32( file, FOURCC( "strl" ) );
- WriteStreamHeader( file, audio->aviAudioHeader );
- WriteHBWaveFormatEx( file, audio->aviAudioFormat );
+ WriteInt32( m->file, FOURCC( "strl" ) );
+ WriteStreamHeader( m->file, &ah );
+ WriteHBWaveFormatEx( m->file, &af );
}
- WriteInt32( file, FOURCC( "JUNK" ) );
- WriteInt32( file, 2008 - hdrlBytes );
+ WriteInt32( m->file, FOURCC( "JUNK" ) );
+ WriteInt32( m->file, 2008 - hdrlBytes );
for( i = 0; i < 2008 - hdrlBytes; i++ )
{
- WriteInt8( file, 0 );
+ WriteInt8( m->file, 0 );
}
- WriteInt32( file, FOURCC( "LIST" ) );
- WriteInt32( file, 4 );
- WriteInt32( file, FOURCC( "movi" ) );
+ WriteInt32( m->file, FOURCC( "LIST" ) );
+ WriteInt32( m->file, 4 );
+ WriteInt32( m->file, FOURCC( "movi" ) );
+
+ return 0;
+}
+
+static int AviMuxVideo( HBMux * m, void * _muxData, HBBuffer * buffer )
+{
+ AviVideoMuxData * muxData = (AviVideoMuxData *) _muxData;
+ AddChunk( m, buffer, FOURCC( "00dc" ), &muxData->videoHeader );
+ return 0;
+}
+
+static int AviMuxAudio( HBMux * m, void * _muxData, HBBuffer * buffer )
+{
+ AviAudioMuxData * muxData = (AviAudioMuxData *) _muxData;
+ AddChunk( m, buffer, muxData->fourCC, &muxData->audioHeader );
+ return 0;
+}
+
+static int AviEnd( HBMux * m )
+{
+ AddIndex( m );
+ fclose( m->file );
+ return 0;
}
+#undef mh
+#undef vh
+#undef vf
+#undef ah
+#undef af
-static void AddChunk( HBAviMux * a, HBBuffer * buffer,
+static void AddChunk( HBMux * m, HBBuffer * buffer,
uint32_t fourCC, HBAviStreamHeader * header )
{
- HBTitle * title = a->title;
+ HBTitle * title = m->title;
+ AviVideoMuxData * videoMuxData = (AviVideoMuxData *) title->muxData;
+ AviAudioMuxData * audioMuxData;
HBAudio * audio;
int i;
/* Update index */
- IndexAddInt32( a->index, fourCC );
- IndexAddInt32( a->index, buffer->keyFrame ? AVIIF_KEYFRAME : 0 );
- IndexAddInt32( a->index, 4 + a->size );
- IndexAddInt32( a->index, buffer->size );
+ IndexAddInt32( m->index, fourCC );
+ IndexAddInt32( m->index, buffer->keyFrame ? AVIIF_KEYFRAME : 0 );
+ IndexAddInt32( m->index, 4 + m->size );
+ IndexAddInt32( m->index, buffer->size );
/* Write the chunk to the file */
- fseek( a->file, 0, SEEK_END );
- WriteInt32( a->file, fourCC );
- WriteInt32( a->file, buffer->size );
- WriteBuffer( a->file, buffer );
+ fseek( m->file, 0, SEEK_END );
+ WriteInt32( m->file, fourCC );
+ WriteInt32( m->file, buffer->size );
+ WriteBuffer( m->file, buffer );
/* Chunks must be 2-bytes aligned */
if( buffer->size & 1 )
{
- WriteInt8( a->file, 0 );
+ WriteInt8( m->file, 0 );
}
/* Update headers */
- a->size += 8 + EVEN( buffer->size );
+ m->size += 8 + EVEN( buffer->size );
header->Length++;
/* RIFF size */
- fseek( a->file, 4, SEEK_SET );
- WriteInt32( a->file, 2040 + a->size );
+ fseek( m->file, 4, SEEK_SET );
+ WriteInt32( m->file, 2040 + m->size );
/* HBAviStreamHeader's lengths */
- fseek( a->file, 140, SEEK_SET );
- WriteInt32( a->file, title->aviVideoHeader->Length );
+ fseek( m->file, 140, SEEK_SET );
+ WriteInt32( m->file, videoMuxData->videoHeader.Length );
for( i = 0; i < HBListCount( title->ripAudioList ); i++ )
{
audio = (HBAudio*) HBListItemAt( title->ripAudioList, i );
- fseek( a->file, 268 + i * 114, SEEK_SET );
- WriteInt32( a->file, audio->aviAudioHeader->Length );
+ audioMuxData = (AviAudioMuxData *) audio->muxData;
+ fseek( m->file, 268 + i * 114, SEEK_SET );
+ WriteInt32( m->file, audioMuxData->audioHeader.Length );
}
/* movi size */
- fseek( a->file, 2040, SEEK_SET );
- WriteInt32( a->file, 4 + a->size );
+ fseek( m->file, 2040, SEEK_SET );
+ WriteInt32( m->file, 4 + m->size );
}
-static void AddIndex( HBAviMux * a )
+static void AddIndex( HBMux * m )
{
- HBTitle * title = a->title;
+ HBTitle * title = m->title;
+ AviVideoMuxData * videoMuxData = (AviVideoMuxData *) title->muxData;
- fseek( a->file, 0, SEEK_END );
+ fseek( m->file, 0, SEEK_END );
- WriteInt32( a->file, FOURCC( "idx1" ) );
- WriteInt32( a->file, a->index->size );
- WriteBuffer( a->file, a->index );
+ WriteInt32( m->file, FOURCC( "idx1" ) );
+ WriteInt32( m->file, m->index->size );
+ WriteBuffer( m->file, m->index );
- a->size += 8 + a->index->size;
- fseek( a->file, 4, SEEK_SET );
- WriteInt32( a->file, 2040 + a->size );
- title->aviMainHeader->Flags |= AVIF_HASINDEX;
- fseek( a->file, 24, SEEK_SET );
- WriteMainHeader( a->file, title->aviMainHeader );
+ m->size += 8 + m->index->size;
+ fseek( m->file, 4, SEEK_SET );
+ WriteInt32( m->file, 2040 + m->size );
+ videoMuxData->mainHeader.Flags |= AVIF_HASINDEX;
+ fseek( m->file, 24, SEEK_SET );
+ WriteMainHeader( m->file, &videoMuxData->mainHeader );
}
static void WriteInt8( FILE * file, uint8_t val )
@@ -554,12 +479,6 @@ static void WriteHBBitmapInfo( FILE * file, HBBitmapInfo * bitmapInfo )
WriteInt32( file, bitmapInfo->YPelsPerMeter );
WriteInt32( file, bitmapInfo->ClrUsed );
WriteInt32( file, bitmapInfo->ClrImportant );
-#if 0
- WriteInt8( file, bitmapInfo->Blue );
- WriteInt8( file, bitmapInfo->Green );
- WriteInt8( file, bitmapInfo->Red );
- WriteInt8( file, bitmapInfo->Reserved );
-#endif
}
static void WriteHBWaveFormatEx( FILE * file, HBWaveFormatEx * waveFormatEx )
diff --git a/core/DVDRead.c b/core/DVDRead.c
index 08e5139f8..4c36f3942 100644
--- a/core/DVDRead.c
+++ b/core/DVDRead.c
@@ -1,4 +1,4 @@
-/* $Id: DVDRead.c,v 1.10 2004/02/29 11:21:34 titer Exp $
+/* $Id: DVDRead.c,v 1.13 2004/05/02 16:25:00 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://handbrake.m0k.org/>.
@@ -6,12 +6,7 @@
#include "HBInternal.h"
-/* libdvdplay */
-#include "dvdread/ifo_types.h"
-#include "dvdplay/dvdplay.h"
-#include "dvdplay/info.h"
-#include "dvdplay/state.h"
-#include "dvdplay/nav.h"
+#include "dvdread/dvd_reader.h"
/* Local prototypes */
static void DVDReadThread( void * );
@@ -23,7 +18,8 @@ struct HBDVDRead
{
HBHandle * handle;
- dvdplay_ptr vmg;
+ dvd_reader_t * reader;
+ dvd_file_t * file;
HBTitle * title;
int beginPosition;
int endPosition;
@@ -46,7 +42,8 @@ HBDVDRead * HBDVDReadInit( HBHandle * handle, HBTitle * title )
/* Initializations */
d->handle = handle;
- d->vmg = NULL;
+ d->reader = NULL;
+ d->file = NULL;
d->title = title;
d->beginPosition = 0;
d->endPosition = 0;
@@ -92,27 +89,20 @@ static void DVDReadThread( void * _d )
int i;
/* Open the device */
- d->vmg = dvdplay_open( title->device, NULL, NULL );
- if( !d->vmg )
+ d->reader = DVDOpen( title->device );
+ if( !d->reader )
{
- HBLog( "HBDVDRead: dvdplay_open() failed" );
+ HBLog( "HBDVDRead: DVDOpen() failed" );
HBErrorOccured( d->handle, HB_ERROR_DVD_OPEN );
return;
}
/* Open the title */
- dvdplay_start( d->vmg, title->index );
- d->beginPosition = dvdplay_title_first( d->vmg );
- d->endPosition = dvdplay_title_end( d->vmg );
-
- HBLog( "HBDVDRead: starting, blocks: %d to %d",
- d->beginPosition, d->endPosition );
+ d->file = DVDOpenFile( d->reader, title->vts_id, DVD_READ_TITLE_VOBS );
/* Do the job */
for( i = 0; i < ( title->twoPass ? 2 : 1 ); i++ )
{
- dvdplay_start( d->vmg, title->index );
-
HBLog( "HBDVDRead: starting pass %d of %d", i + 1,
title->twoPass ? 2 : 1 );
@@ -131,7 +121,8 @@ static void DVDReadThread( void * _d )
}
/* Clean up */
- dvdplay_close( d->vmg );
+ DVDCloseFile( d->file );
+ DVDClose( d->reader );
}
@@ -139,11 +130,11 @@ static int DoPass( HBDVDRead * d )
{
int i;
- for( i = 0; i < d->endPosition - d->beginPosition; i++ )
+ for( i = d->title->startBlock; i < d->title->endBlock; i++ )
{
d->psBuffer = HBBufferInit( DVD_VIDEO_LB_LEN );
- d->psBuffer->position =
- (float) i / ( d->endPosition - d->beginPosition );
+ d->psBuffer->position = (float) ( i - d->title->startBlock ) /
+ ( d->title->endBlock - d->title->startBlock );
if( d->pass )
{
@@ -156,9 +147,9 @@ static int DoPass( HBDVDRead * d )
}
d->psBuffer->pass = d->pass;
- if( dvdplay_read( d->vmg, d->psBuffer->data, 1 ) < 0 )
+ if( DVDReadBlocks( d->file, i, 1, d->psBuffer->data ) < 0 )
{
- HBLog( "HBDVDRead: dvdplay_read() failed" );
+ HBLog( "HBDVDRead: DVDReadBlocks() failed" );
HBErrorOccured( d->handle, HB_ERROR_DVD_READ );
HBBufferClose( &d->psBuffer );
return 0;
@@ -195,6 +186,7 @@ static int Demux( HBDVDRead * d )
continue;
}
+ /* Video */
if( esBuffer->streamId == 0xE0 )
{
if( title->start < 0 )
@@ -212,6 +204,7 @@ static int Demux( HBDVDRead * d )
continue;
}
+ /* Audio or whatever */
for( i = 0; i < HBListCount( title->ripAudioList ); i++ )
{
audio = (HBAudio*) HBListItemAt( title->ripAudioList, i );
diff --git a/core/FaacEnc.c b/core/FaacEnc.c
index b55a9deb6..689e6e18f 100644
--- a/core/FaacEnc.c
+++ b/core/FaacEnc.c
@@ -1,4 +1,4 @@
-/* $Id: FaacEnc.c,v 1.15 2004/02/18 17:07:20 titer Exp $
+/* $Id: FaacEnc.c,v 1.20 2004/05/02 16:25:00 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://handbrake.m0k.org/>.
@@ -9,7 +9,7 @@
/* libfaac */
#include "faac.h"
-typedef struct HBFaacEnc
+struct HBWork
{
HB_WORK_COMMON_MEMBERS
@@ -19,193 +19,119 @@ typedef struct HBFaacEnc
faacEncHandle * faac;
unsigned long inputSamples;
unsigned long maxOutputBytes;
- int32_t * inputBuffer;
- unsigned long samplesGot;
- HBBuffer * rawBuffer;
- int rawBufferPos; /* in bytes */
- float position;
- HBBuffer * aacBuffer;
-
- /* Stats */
- int64_t samples;
- int64_t bytes;
-} HBFaacEnc;
+ float * inputBuffer;
+};
/* Local prototypes */
static int FaacEncWork( HBWork * );
-static int GetSamples( HBFaacEnc * );
HBWork * HBFaacEncInit( HBHandle * handle, HBAudio * audio )
{
- HBFaacEnc * f;
- if( !( f = calloc( sizeof( HBFaacEnc ), 1 ) ) )
+ HBWork * w;
+ if( !( w = calloc( sizeof( HBWork ), 1 ) ) )
{
HBLog( "HBFaacEncInit: malloc() failed, gonna crash" );
return NULL;
}
- f->name = strdup( "FaacEnc" );
- f->work = FaacEncWork;
+ w->name = strdup( "FaacEnc" );
+ w->work = FaacEncWork;
- f->handle = handle;
- f->audio = audio;
+ w->handle = handle;
+ w->audio = audio;
- return (HBWork*) f;
+ return w;
}
-void HBFaacEncClose( HBWork ** _f )
+void HBFaacEncClose( HBWork ** _w )
{
- HBFaacEnc * f = (HBFaacEnc*) *_f;
+ HBWork * w = *_w;
- if( f->faac )
+ if( w->faac )
{
- faacEncClose( f->faac );
- free( f->inputBuffer );
+ faacEncClose( w->faac );
+ free( w->inputBuffer );
}
- if( f->samples )
- {
- int64_t bytes = 128 * f->audio->outBitrate * f->samples /
- f->audio->outSampleRate;
- float bitrate = (float) f->bytes * f->audio->inSampleRate /
- f->samples / 128;
-
- HBLog( "HBFaacEnc: %lld samples encoded (%lld bytes), %.2f kbps",
- f->samples, f->bytes, bitrate );
- HBLog( "HBFaacEnc: error is %lld bytes", f->bytes - bytes );
- }
-
- free( f->name );
- free( f );
+ free( w->name );
+ free( w );
- *_f = NULL;
+ *_w = NULL;
}
static int FaacEncWork( HBWork * w )
{
- HBFaacEnc * f = (HBFaacEnc*) w;
- HBAudio * audio = f->audio;
+ HBAudio * audio = w->audio;
- int didSomething = 0;
+ HBBuffer * aacBuffer;
+ float position;
- if( !f->faac )
+ if( !w->faac )
{
faacEncConfigurationPtr config;
- /* Get a first buffer so we know that audio->inSampleRate is
- correct */
- if( ( f->rawBuffer = HBFifoPop( audio->rawFifo ) ) )
- {
- didSomething = 1;
- }
- else
+ if( !HBFifoSize( audio->resampleFifo ) )
{
- return didSomething;
+ return 0;
}
- f->rawBufferPos = 0;
- f->position = f->rawBuffer->position;
HBLog( "HBFaacEnc: opening libfaac (%x)", audio->id );
- /* No resampling */
- audio->outSampleRate = audio->inSampleRate;
-
- f->faac = faacEncOpen( audio->outSampleRate, 2,
- &f->inputSamples, &f->maxOutputBytes );
- f->inputBuffer = malloc( f->inputSamples * sizeof( int32_t ) );
- config = faacEncGetCurrentConfiguration( f->faac );
+ w->faac = faacEncOpen( audio->outSampleRate, 2,
+ &w->inputSamples, &w->maxOutputBytes );
+ w->inputBuffer = malloc( w->inputSamples * sizeof( float ) );
+ config = faacEncGetCurrentConfiguration( w->faac );
config->mpegVersion = MPEG4;
config->aacObjectType = LOW;
config->allowMidside = 1;
config->useLfe = 0;
config->useTns = 0;
- config->bitRate = audio->outBitrate * 512;
+ config->bitRate = audio->outBitrate * 500; /* per channel */
config->bandWidth = 0;
config->outputFormat = 0;
- faacEncSetConfiguration( f->faac, config );
- faacEncGetDecoderSpecificInfo( f->faac, &audio->esConfig,
- &audio->esConfigLength );
- }
-
- /* Push encoded buffer */
- if( f->aacBuffer )
- {
- if( HBFifoPush( audio->outFifo, &f->aacBuffer ) )
+ config->inputFormat = FAAC_INPUT_FLOAT;
+ if( !faacEncSetConfiguration( w->faac, config ) )
{
- didSomething = 1;
+ HBLog( "HBFaacEnc: faacEncSetConfiguration failed" );
}
- else
+ if( faacEncGetDecoderSpecificInfo( w->faac, &audio->esConfig,
+ &audio->esConfigLength ) < 0 )
{
- return didSomething;
+ HBLog( "HBFaacEnc: faacEncGetDecoderSpecificInfo failed" );
}
}
- if( GetSamples( f ) )
+ if( HBFifoIsHalfFull( audio->outFifo ) )
{
- didSomething = 1;
+ return 0;
}
- else
+
+ if( !HBFifoGetBytes( audio->resampleFifo,
+ (uint8_t *) w->inputBuffer,
+ w->inputSamples * sizeof( float ),
+ &position ) )
{
- return didSomething;
+ return 0;
}
- f->samplesGot = 0;
-
- f->aacBuffer = HBBufferInit( f->maxOutputBytes );
- f->aacBuffer->position = f->position;
- f->aacBuffer->size = faacEncEncode( f->faac, f->inputBuffer,
- f->inputSamples, f->aacBuffer->data, f->maxOutputBytes );
+ aacBuffer = HBBufferInit( w->maxOutputBytes );
+ aacBuffer->position = position;
+ aacBuffer->size = faacEncEncode( w->faac, (int32_t*)w->inputBuffer,
+ w->inputSamples, aacBuffer->data, w->maxOutputBytes );
- f->samples += f->inputSamples / 2;
-
- if( !f->aacBuffer->size )
+ if( !aacBuffer->size )
{
- HBBufferClose( &f->aacBuffer );
+ HBBufferClose( &aacBuffer );
}
- else if( f->aacBuffer->size < 0 )
+ else if( aacBuffer->size < 0 )
{
HBLog( "HBFaacEnc: faacEncEncode() failed" );
}
else
{
- f->bytes += f->aacBuffer->size;
- }
-
- return didSomething;
-}
-
-static int GetSamples( HBFaacEnc * f )
-{
- while( f->samplesGot < f->inputSamples )
- {
- int i, copy;
-
- if( !f->rawBuffer )
- {
- if( !( f->rawBuffer = HBFifoPop( f->audio->rawFifo ) ) )
- {
- return 0;
- }
-
- f->rawBufferPos = 0;
- f->position = f->rawBuffer->position;
- }
-
- copy = MIN( f->inputSamples - f->samplesGot,
- ( f->rawBuffer->samples - f->rawBufferPos ) * 2 );
-
- for( i = 0; i < copy; i += 2 )
- {
- f->inputBuffer[f->samplesGot++] =
- f->rawBuffer->left[f->rawBufferPos];
- f->inputBuffer[f->samplesGot++] =
- f->rawBuffer->right[f->rawBufferPos];
- f->rawBufferPos++;
- }
-
- if( f->rawBufferPos == f->rawBuffer->samples )
+ if( !HBFifoPush( audio->outFifo, &aacBuffer ) )
{
- HBBufferClose( &f->rawBuffer );
+ HBLog( "HBFaacEnc: HBFifoPush failed" );
}
}
diff --git a/core/FfmpegEnc.c b/core/FfmpegEnc.c
index 7d909a7a3..ae474d00b 100644
--- a/core/FfmpegEnc.c
+++ b/core/FfmpegEnc.c
@@ -1,4 +1,4 @@
-/* $Id: FfmpegEnc.c,v 1.19 2004/03/01 21:36:36 titer Exp $
+/* $Id: FfmpegEnc.c,v 1.26 2004/05/12 18:02:35 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://handbrake.m0k.org/>.
@@ -9,120 +9,89 @@
/* libavcodec */
#include "ffmpeg/avcodec.h"
-typedef struct HBFfmpegEnc
+struct HBWork
{
HB_WORK_COMMON_MEMBERS
HBHandle * handle;
HBTitle * title;
- HBBuffer * mpeg4Buffer;
int pass;
AVCodecContext * context;
FILE * file;
-
- /* Stats */
- int frames;
- int64_t bytes;
-} HBFfmpegEnc;
+};
/* Local prototypes */
static int FfmpegEncWork( HBWork * );
-static int InitAvcodec( HBFfmpegEnc * );
-static void CloseAvcodec( HBFfmpegEnc * );
+static int InitAvcodec( HBWork * );
+static void CloseAvcodec( HBWork * );
HBWork * HBFfmpegEncInit( HBHandle * handle, HBTitle * title )
{
- HBFfmpegEnc * f;
- if( !( f = calloc( sizeof( HBFfmpegEnc ), 1 ) ) )
+ HBWork * w;
+ if( !( w = calloc( sizeof( HBWork ), 1 ) ) )
{
HBLog( "HBFfmpegEncInit: malloc() failed, gonna crash" );
return NULL;
}
- f->name = strdup( "FfmpegEnc" );
- f->work = FfmpegEncWork;
+ w->name = strdup( "FfmpegEnc" );
+ w->work = FfmpegEncWork;
- f->handle = handle;
- f->title = title;
- f->pass = 42;
+ w->handle = handle;
+ w->title = title;
+ w->pass = 42;
- return (HBWork*) f;
+ return w;
}
-void HBFfmpegEncClose( HBWork ** _f )
+void HBFfmpegEncClose( HBWork ** _w )
{
- HBFfmpegEnc * f = (HBFfmpegEnc*) *_f;
+ HBWork * w = *_w;
- if( f->context )
+ if( w->context )
{
- CloseAvcodec( f );
+ CloseAvcodec( w );
}
- /* Stats */
- if( f->frames )
- {
- float bitrate = (float) f->bytes * f->title->rate /
- f->frames / f->title->rateBase / 128;
- int64_t bytes = (int64_t) f->frames * f->title->bitrate * 128 *
- f->title->rateBase / f->title->rate;
-
- HBLog( "HBFfmpegEnc: %d frames encoded (%lld bytes), %.2f kbps",
- f->frames, f->bytes, bitrate );
- HBLog( "HBFfmpegEnc: error is %lld bytes", f->bytes - bytes );
- }
- free( f->name );
- free( f );
+ free( w->name );
+ free( w );
- *_f = NULL;
+ *_w = NULL;
}
static int FfmpegEncWork( HBWork * w )
{
- HBFfmpegEnc * f = (HBFfmpegEnc*) w;
- HBTitle * title = f->title;
+ HBTitle * title = w->title;
HBBuffer * scaledBuffer;
HBBuffer * mpeg4Buffer;
AVFrame * frame;
- int didSomething = 0;
-
- if( f->mpeg4Buffer )
+ if( HBFifoIsHalfFull( title->outFifo ) )
{
- if( HBFifoPush( title->outFifo, &f->mpeg4Buffer ) )
- {
- didSomething = 1;
- }
- else
- {
- return didSomething;
- }
+ return 0;
}
- if( ( scaledBuffer = HBFifoPop( title->scaledFifo ) ) )
+ if( !( scaledBuffer = HBFifoPop( title->scaledFifo ) ) )
{
- didSomething = 1;
- }
- else
- {
- return didSomething;
+ return 0;
}
/* Init or re-init if needed */
- if( scaledBuffer->pass != f->pass )
+ if( scaledBuffer->pass != w->pass )
{
- if( f->context )
+ if( w->context )
{
- CloseAvcodec( f );
+ CloseAvcodec( w );
}
-
- f->pass = scaledBuffer->pass;
-
- if( !InitAvcodec( f ) )
+
+ w->pass = scaledBuffer->pass;
+
+ if( !InitAvcodec( w ) )
{
- HBErrorOccured( f->handle, HB_ERROR_MPEG4_INIT );
- return didSomething;
+ HBErrorOccured( w->handle, HB_ERROR_MPEG4_INIT );
+ return 0;
}
}
@@ -139,49 +108,48 @@ static int FfmpegEncWork( HBWork * w )
mpeg4Buffer = HBBufferInit( 3 * title->outWidth *
title->outHeight / 2 );
mpeg4Buffer->position = scaledBuffer->position;
- mpeg4Buffer->size = avcodec_encode_video( f->context,
+ mpeg4Buffer->size = avcodec_encode_video( w->context,
mpeg4Buffer->data, mpeg4Buffer->alloc, frame );
- mpeg4Buffer->keyFrame = f->context->coded_frame->key_frame;
+ mpeg4Buffer->keyFrame = w->context->coded_frame->key_frame;
/* Inform the GUI about the current position */
- HBPosition( f->handle, scaledBuffer->position );
+ HBPosition( w->handle, scaledBuffer->position );
- if( f->pass == 1 )
+ if( w->pass == 1 )
{
- if( f->context->stats_out )
+ if( w->context->stats_out )
{
- fprintf( f->file, "%s", f->context->stats_out );
+ fprintf( w->file, "%s", w->context->stats_out );
}
HBBufferClose( &mpeg4Buffer );
}
else
{
- f->mpeg4Buffer = mpeg4Buffer;
-
- /* Stats */
- f->frames++;
- f->bytes += mpeg4Buffer->size;
+ if( !HBFifoPush( title->outFifo, &mpeg4Buffer ) )
+ {
+ HBLog( "HBFfmpegEnc: HBFifoPush failed" );
+ }
}
HBBufferClose( &scaledBuffer );
free( frame );
- return didSomething;
+ return 1;
}
-static int InitAvcodec( HBFfmpegEnc * f )
+static int InitAvcodec( HBWork * w )
{
AVCodec * codec;
AVCodecContext * context;
- HBTitle * title = f->title;
+ HBTitle * title = w->title;
- HBLog( "HBFfmpegEnc: opening libavcodec (pass %d)", f->pass );
+ HBLog( "HBFfmpegEnc: opening libavcodec (pass %d)", w->pass );
codec = avcodec_find_encoder( CODEC_ID_MPEG4 );
if( !codec )
{
HBLog( "HBFfmpegEnc: avcodec_find_encoder() failed" );
- HBErrorOccured( f->handle, HB_ERROR_MPEG4_INIT );
+ HBErrorOccured( w->handle, HB_ERROR_MPEG4_INIT );
return 0;
}
@@ -194,20 +162,25 @@ static int InitAvcodec( HBFfmpegEnc * f )
context->frame_rate_base = title->rateBase;
context->gop_size = 10 * title->rate / title->rateBase;
- if( title->mux == HB_MUX_MP4 && f->pass != 1 )
+ if( title->mux == HB_MUX_MP4 && w->pass != 1 )
{
context->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
- if( f->pass )
+ if( w->pass )
{
char fileName[1024]; memset( fileName, 0, 1024 );
+#ifndef HB_CYGWIN
sprintf( fileName, "/tmp/HB.%d.ffmpeg.log",
- HBGetPid( f->handle ) );
+ HBGetPid( w->handle ) );
+#else
+ sprintf( fileName, "C:\\HB.%d.ffmpeg.log",
+ HBGetPid( w->handle ) );
+#endif
- if( f->pass == 1 )
+ if( w->pass == 1 )
{
- f->file = fopen( fileName, "w" );
+ w->file = fopen( fileName, "wb" );
context->flags |= CODEC_FLAG_PASS1;
}
else
@@ -216,7 +189,7 @@ static int InitAvcodec( HBFfmpegEnc * f )
int size;
char * log;
- file = fopen( fileName, "r" );
+ file = fopen( fileName, "rb" );
fseek( file, 0, SEEK_END );
size = ftell( file );
fseek( file, 0, SEEK_SET );
@@ -245,7 +218,7 @@ static int InitAvcodec( HBFfmpegEnc * f )
return 0;
}
- if( title->mux == HB_MUX_MP4 && f->pass != 1 )
+ if( title->mux == HB_MUX_MP4 && w->pass != 1 )
{
/* UGLY */
title->esConfig = malloc( 15 );
@@ -253,30 +226,30 @@ static int InitAvcodec( HBFfmpegEnc * f )
memcpy( title->esConfig, context->extradata + 15, 15 );
}
- f->context = context;
+ w->context = context;
return 1;
}
-static void CloseAvcodec( HBFfmpegEnc * f )
+static void CloseAvcodec( HBWork * w )
{
HBLog( "HBFfmpegEnc: closing libavcodec (pass %d)",
- f->pass );
+ w->pass );
- if( f->context->stats_in )
+ if( w->context->stats_in )
{
- free( f->context->stats_in );
+ free( w->context->stats_in );
}
- avcodec_close( f->context );
- if( f->file )
+ avcodec_close( w->context );
+ if( w->file )
{
- fclose( f->file );
- f->file = NULL;
+ fclose( w->file );
+ w->file = NULL;
}
- if( f->title->esConfig )
+ if( w->title->esConfig )
{
- free( f->title->esConfig );
- f->title->esConfig = NULL;
- f->title->esConfigLength = 0;
+ free( w->title->esConfig );
+ w->title->esConfig = NULL;
+ w->title->esConfigLength = 0;
}
}
diff --git a/core/Fifo.c b/core/Fifo.c
index 5c32c59a1..ae0c412da 100644
--- a/core/Fifo.c
+++ b/core/Fifo.c
@@ -1,4 +1,4 @@
-/* $Id: Fifo.c,v 1.14 2004/03/17 10:35:06 titer Exp $
+/* $Id: Fifo.c,v 1.17 2004/04/27 19:30:00 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://handbrake.m0k.org/>.
@@ -14,7 +14,7 @@ HBBuffer * HBBufferInit( int size )
HBBuffer * b;
if( !( b = calloc( sizeof( HBBuffer ), 1 ) ) )
{
- HBLog( "HBBufferInit: malloc() failed, gonna crash" );
+ HBLog( "HBBuffer: malloc() failed, gonna crash" );
return NULL;
}
@@ -31,10 +31,11 @@ HBBuffer * HBBufferInit( int size )
b->data = b->dataOrig + 15;
b->data -= (long) b->data & 15;
#endif
+ b->dataf = (float*) b->data;
if( !b->data )
{
- HBLog( "HBBufferInit: malloc() failed, gonna crash" );
+ HBLog( "HBBuffer: malloc() failed, gonna crash" );
free( b );
return NULL;
}
@@ -57,7 +58,7 @@ void HBBufferReAlloc( HBBuffer * b, int size )
if( !b->data )
{
- HBLog( "HBBufferReAlloc: realloc() failed, gonna crash soon" );
+ HBLog( "HBBuffer: realloc() failed, gonna crash soon" );
}
}
@@ -80,7 +81,7 @@ HBFifo * HBFifoInit( int capacity )
HBFifo * f;
if( !( f = malloc( sizeof( HBFifo ) ) ) )
{
- HBLog( "HBFifoInit: malloc() failed, gonna crash" );
+ HBLog( "HBFifo: malloc() failed, gonna crash" );
return NULL;
}
@@ -91,7 +92,7 @@ HBFifo * HBFifoInit( int capacity )
if( !( f->buffers = malloc( ( capacity + 1 ) * sizeof( void* ) ) ) )
{
- HBLog( "HBFifoInit: malloc() failed, gonna crash" );
+ HBLog( "HBFifo: malloc() failed, gonna crash" );
free( f );
return NULL;
}
@@ -114,7 +115,7 @@ void HBFifoClose( HBFifo ** _f )
{
HBFifo * f = (*_f);
- HBLog( "HBFifoClose: trashing %d buffer%s",
+ HBLog( "HBFifo: trashing %d buffer%s",
HBFifoSize( f ), ( HBFifoSize( f ) > 1 ) ? "s" : "" );
while( f->whereToPush != f->whereToPop )
diff --git a/core/Fifo.h b/core/Fifo.h
index 264a7eeb3..26c4b5581 100644
--- a/core/Fifo.h
+++ b/core/Fifo.h
@@ -1,4 +1,4 @@
-/* $Id: Fifo.h,v 1.13 2004/03/17 10:35:06 titer Exp $
+/* $Id: Fifo.h,v 1.16 2004/04/27 22:02:59 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://handbrake.m0k.org/>.
@@ -19,23 +19,22 @@ struct HBBuffer
#if defined( HB_CYGWIN )
uint8_t * dataOrig;
#endif
+ float * dataf;
float position;
int pass;
/* Only used for PStoES */
- int streamId;
+ uint32_t streamId;
uint64_t pts;
/* NTSC suxx */
int repeat;
- /* Only used for raw audio buffers */
- int samples; /* Number of samples for each track */
- float * left;
- float * right;
-
/* Only used for MPEG-4, MP3 and AAC buffers */
int keyFrame;
+
+ /* Use for bitstreams */
+ int _pos;
};
HBBuffer * HBBufferInit( int size );
@@ -55,10 +54,13 @@ struct HBFifo
HBFifo * HBFifoInit( int capacity );
static inline int HBFifoSize( HBFifo * );
+static inline int HBFifoIsHalfFull( HBFifo * );
static inline int HBFifoPush( HBFifo *, HBBuffer ** );
static inline HBBuffer * HBFifoPop( HBFifo * );
static inline int HBFifoWait( HBFifo * );
static inline float HBFifoPosition( HBFifo * );
+static inline int HBFifoGetBytes( HBFifo * f, uint8_t *, int,
+ float * position );
void HBFifoDie( HBFifo * );
void HBFifoClose( HBFifo ** );
@@ -72,6 +74,16 @@ static inline int HBFifoSize( HBFifo * f )
return size;
}
+static inline int HBFifoIsHalfFull( HBFifo * f )
+{
+ int size;
+ HBLockLock( f->lock );
+ size = ( f->capacity + 1 + f->whereToPush - f->whereToPop ) %
+ ( f->capacity + 1 );
+ HBLockUnlock( f->lock );
+ return ( 2 * size > f->capacity );
+}
+
static inline int HBFifoPush( HBFifo * f, HBBuffer ** b )
{
HBLockLock( f->lock );
@@ -144,4 +156,62 @@ static inline float HBFifoPosition( HBFifo * f )
return pos;
}
+static inline int HBFifoGetBytes( HBFifo * f, uint8_t * data, int nb,
+ float * position )
+{
+ int whereToPop, bytes = 0;
+ HBBuffer * buffer;
+ HBLockLock( f->lock );
+
+ /* Do we have enough? */
+ for( whereToPop = f->whereToPop; ; whereToPop++ )
+ {
+ whereToPop %= ( f->capacity + 1 );
+ if( f->whereToPush == whereToPop )
+ {
+ /* We hit the end of the fifo */
+ break;
+ }
+
+ bytes += f->buffers[whereToPop]->size -
+ f->buffers[whereToPop]->_pos;
+
+ if( bytes >= nb )
+ {
+ break;
+ }
+ }
+
+ if( bytes < nb )
+ {
+ /* Not enough data */
+ HBLockUnlock( f->lock );
+ return 0;
+ }
+
+ for( bytes = 0; bytes < nb; )
+ {
+ int copy;
+
+ buffer = f->buffers[f->whereToPop];
+ copy = MIN( nb - bytes, buffer->size - buffer->_pos );
+
+ memcpy( data + bytes, buffer->data + buffer->_pos, copy );
+ (*position) = buffer->position;
+
+ buffer->_pos += copy;
+ bytes += copy;
+
+ if( buffer->_pos == buffer->size )
+ {
+ HBBufferClose( &buffer );
+ f->whereToPop++;
+ f->whereToPop %= ( f->capacity + 1 );
+ }
+ }
+
+ HBLockUnlock( f->lock );
+ return 1;
+}
+
#endif
diff --git a/core/HBInternal.h b/core/HBInternal.h
index a8adb4d44..4fa45f8b0 100644
--- a/core/HBInternal.h
+++ b/core/HBInternal.h
@@ -1,4 +1,4 @@
-/* $Id: HBInternal.h,v 1.5 2004/03/08 11:32:48 titer Exp $
+/* $Id: HBInternal.h,v 1.10 2004/05/12 17:21:24 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://handbrake.m0k.org/>.
@@ -9,9 +9,16 @@
#include "HandBrake.h"
#include "Fifo.h"
+#include "Mux.h"
#include "Thread.h"
#include "Work.h"
+#ifndef HB_CYGWIN
+#define LLD "%lld"
+#else
+#define LLD "%I64d"
+#endif
+
/* Demuxer */
HBDVDRead * HBDVDReadInit( HBHandle *, HBTitle * );
void HBDVDReadClose( HBDVDRead ** );
@@ -23,13 +30,17 @@ HBWork * HBAc3DecInit( HBHandle *, HBAudio * );
void HBAc3DecClose( HBWork ** );
HBWork * HBLpcmDecInit( HBHandle *, HBAudio * );
void HBLpcmDecClose( HBWork ** );
-HBWork * HBMadDecInit( HBHandle *, HBAudio * );
-void HBMadDecClose( HBWork ** );
+HBWork * HBMpgaDecInit( HBHandle *, HBAudio * );
+void HBMpgaDecClose( HBWork ** );
/* Scaler */
HBWork * HBScaleInit( HBHandle *, HBTitle * );
void HBScaleClose( HBWork ** );
+/* Resampler */
+HBWork * HBResampleInit( HBHandle *, HBAudio * );
+void HBResampleClose( HBWork ** );
+
/* Encoders */
HBWork * HBFfmpegEncInit( HBHandle *, HBTitle * );
void HBFfmpegEncClose( HBWork ** );
@@ -44,14 +55,6 @@ void HBFaacEncClose( HBWork ** );
HBWork * HBVorbisEncInit ( HBHandle *, HBAudio * );
void HBVorbisEncClose( HBWork ** );
-/* Muxers */
-HBAviMux * HBAviMuxInit( HBHandle *, HBTitle * );
-void HBAviMuxClose( HBAviMux ** );
-HBMp4Mux * HBMp4MuxInit( HBHandle *, HBTitle * );
-void HBMp4MuxClose( HBMp4Mux ** );
-HBOgmMux * HBOgmMuxInit( HBHandle *, HBTitle * );
-void HBOgmMuxClose( HBOgmMux ** );
-
/* Scanner */
HBScan * HBScanInit( HBHandle *, const char * device, int title );
void HBScanClose( HBScan ** );
diff --git a/core/HandBrake.c b/core/HandBrake.c
index 9c88b37c6..6d16b4640 100644
--- a/core/HandBrake.c
+++ b/core/HandBrake.c
@@ -1,4 +1,4 @@
-/* $Id: HandBrake.c,v 1.47 2004/03/21 22:58:41 titer Exp $
+/* $Id: HandBrake.c,v 1.58 2004/05/12 18:02:35 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://handbrake.m0k.org/>.
@@ -48,11 +48,6 @@ struct HBHandle
HBHandle * HBInit( int debug, int cpuCount )
{
HBHandle * h;
- if( !( h = calloc( sizeof( HBHandle ), 1 ) ) )
- {
- HBLog( "HBInit: malloc() failed, gonna crash" );
- return NULL;
- }
/* See HBLog() in Utils.cpp */
if( debug )
@@ -60,9 +55,18 @@ HBHandle * HBInit( int debug, int cpuCount )
putenv( "HB_DEBUG=1" );
}
+ HBLog( "HBInit: starting HandBrake " HB_VERSION );
+
+ if( !( h = calloc( sizeof( HBHandle ), 1 ) ) )
+ {
+ HBLog( "HBInit: malloc() failed, gonna crash" );
+ return NULL;
+ }
+
/* Init libavcodec */
avcodec_init();
register_avcodec( &mpeg4_encoder );
+ register_avcodec( &mp2_decoder );
/* Check CPU count */
if( !cpuCount )
@@ -131,9 +135,9 @@ void HBStartRip( HBHandle * h, HBTitle * title )
/* Video fifos */
title->inFifo = HBFifoInit( 2048 );
- title->rawFifo = HBFifoInit( 1 );
- title->scaledFifo = HBFifoInit( 1 );
- title->outFifo = HBFifoInit( 1 );
+ title->rawFifo = HBFifoInit( 32 );
+ title->scaledFifo = HBFifoInit( 32 );
+ title->outFifo = HBFifoInit( 32 );
/* Video work objects */
title->decoder = HBMpeg2DecInit( h, title );
@@ -150,15 +154,20 @@ void HBStartRip( HBHandle * h, HBTitle * title )
audio = HBListItemAt( title->ripAudioList, i );
/* Audio fifos */
- audio->inFifo = HBFifoInit( 2048 );
- audio->rawFifo = HBFifoInit( 1 );
- audio->outFifo = HBFifoInit( 4 ); /* At least 4 for Vorbis */
+ audio->inFifo = HBFifoInit( 2048 );
+ audio->rawFifo = HBFifoInit( 32 );
+ audio->resampleFifo = HBFifoInit( 32 );
+ audio->outFifo = HBFifoInit( 32 );
/* Audio work objects */
if( audio->inCodec == HB_CODEC_AC3 )
audio->decoder = HBAc3DecInit( h, audio );
else if( audio->inCodec == HB_CODEC_LPCM )
audio->decoder = HBLpcmDecInit( h, audio );
+ else if( audio->inCodec == HB_CODEC_MPGA )
+ audio->decoder = HBMpgaDecInit( h, audio );
+
+ audio->resample = HBResampleInit( h, audio );
if( audio->outCodec == HB_CODEC_MP3 )
audio->encoder = HBMp3EncInit( h, audio );
@@ -171,12 +180,7 @@ void HBStartRip( HBHandle * h, HBTitle * title )
/* Create threads */
title->dvdRead = HBDVDReadInit( h, title );
- if( title->mux == HB_MUX_AVI )
- title->aviMux = HBAviMuxInit( h, title );
- else if( title->mux == HB_MUX_MP4 )
- title->mp4Mux = HBMp4MuxInit( h, title );
- else if( title->mux == HB_MUX_OGM )
- title->ogmMux = HBOgmMuxInit( h, title );
+ title->muxThread = HBMuxThreadInit( h, title );
for( i = 0; i < h->cpuCount; i++ )
{
@@ -254,9 +258,9 @@ uint8_t * HBGetPreview( HBHandle * h, HBTitle * t, int picture )
/* Get the original image from the temp file */
memset( fileName, 0, 1024 );
- sprintf( fileName, "/tmp/HB.%d.%d.%d", h->pid, t->index,
+ sprintf( fileName, "/tmp/HB.%d.%d.%d", h->pid, t->title,
picture );
- file = fopen( fileName, "r" );
+ file = fopen( fileName, "rb" );
if( file )
{
fread( buf1, 3 * t->inWidth * t->inHeight / 2, 1, file );
@@ -341,49 +345,49 @@ int HBGetBitrateForSize( HBTitle * title, int size, int muxer,
{
int64_t available;
int overheadPerFrame;
- int sampleRate;
int samplesPerFrame;
+ int length;
switch( muxer )
{
+ /* Overhead are max seen values */
case HB_MUX_MP4:
- overheadPerFrame = 5; /* hopefully */
- sampleRate = 48000; /* No resampling */
+ overheadPerFrame = 6;
samplesPerFrame = 1024; /* AAC */
break;
case HB_MUX_AVI:
- overheadPerFrame = 24;
- sampleRate = 44100; /* Resampling */
+ overheadPerFrame = 26;
samplesPerFrame = 1152; /* MP3 */
break;
case HB_MUX_OGM:
overheadPerFrame = 0; /* XXX */
- sampleRate = 48000; /* No resampling */
samplesPerFrame = 1024; /* Vorbis */
break;
default:
return 0;
}
- /* Actually target 1 MB less */
- available = (int64_t) ( size - 1 ) * 1024 * 1024;
+ length = 3600 * title->hours + 60 * title->minutes +
+ title->seconds + 1;
+
+ available = (int64_t) size * 1024 * 1024;
/* Audio data */
- available -= audioCount * title->length * audioBitrate * 128;
+ available -= audioCount * length * audioBitrate * 1000 / 8;
/* Video headers */
- available -= (int64_t) title->length * title->rate *
+ available -= (int64_t) length * title->rate *
overheadPerFrame / title->rateBase;
/* Audio headers */
- available -= (int64_t) audioCount * title->length * sampleRate *
+ available -= (int64_t) audioCount * length * 44100 *
overheadPerFrame / samplesPerFrame;
if( available < 0 )
{
return 0;
}
- return( available / ( 128 * title->length ) );
+ return( available / ( 128 * length ) );
}
void HBClose( HBHandle ** _h )
@@ -413,9 +417,11 @@ void HBClose( HBHandle ** _h )
}
}
+#ifndef HB_CYGWIN
memset( command, 0, 1024 );
sprintf( command, "rm -f /tmp/HB.%d.*", h->pid );
system( command );
+#endif
HBLockClose( &h->lock );
HBLockClose( &h->pauseLock );
@@ -442,7 +448,6 @@ void HBScanDone( HBHandle * h, HBList * titleList )
h->stopScan = 1;
h->titleList = titleList;
HBLockUnlock( h->lock );
- h->cb.scanDone( h->cb.data, titleList );
}
int HBGetPid( HBHandle * h )
@@ -522,6 +527,7 @@ static void HandBrakeThread( void * _h )
HBScanClose( &h->scan );
h->stopScan = 0;
HBLockUnlock( h->lock );
+ h->cb.scanDone( h->cb.data, h->titleList );
continue;
}
@@ -537,10 +543,9 @@ static void HandBrakeThread( void * _h )
if( h->ripDone )
{
HBTitle * title = h->curTitle;
- HBAudio * audio;
- int i, ok = 0;
- /* Wait until we're done with the decoding of one track */
+ /* Wait until we're done with the video track */
+ uint64_t waitStart = HBGetDate();
for( ;; )
{
if( !HBFifoSize( title->inFifo ) &&
@@ -549,26 +554,21 @@ static void HandBrakeThread( void * _h )
{
break;
}
- for( i = 0; i < HBListCount( title->ripAudioList ); i++ )
- {
- audio = (HBAudio*) HBListItemAt( title->ripAudioList, i );
- if( !HBFifoSize( title->inFifo ) &&
- !HBFifoSize( title->rawFifo ) )
- {
- ok = 1;
- break;
- }
- }
- if( ok )
+
+ /* XXX Deadlock workaround */
+ if( HBGetDate() - waitStart > 30000000 )
{
+ HBLog( "Waited too long, stopping now" );
break;
}
+
HBSnooze( 5000 );
}
HBSnooze( 500000 );
_StopRip( h );
h->ripDone = 0;
+ h->error = 0;
HBLockUnlock( h->lock );
h->cb.ripDone( h->cb.data, HB_SUCCESS );
continue;
@@ -577,9 +577,9 @@ static void HandBrakeThread( void * _h )
if( h->error )
{
_StopRip( h );
- h->error = 0;
HBLockUnlock( h->lock );
h->cb.ripDone( h->cb.data, h->error );
+ h->error = 0;
continue;
}
@@ -615,12 +615,7 @@ static void _StopRip( HBHandle * h )
}
/* Stop mux thread */
- if( title->mux == HB_MUX_AVI )
- HBAviMuxClose( &title->aviMux );
- else if( title->mux == HB_MUX_MP4 )
- HBMp4MuxClose( &title->mp4Mux );
- else if( title->mux == HB_MUX_OGM )
- HBOgmMuxClose( &title->ogmMux );
+ HBMuxThreadClose( &title->muxThread );
/* Clean up */
HBMpeg2DecClose( &title->decoder );
@@ -645,6 +640,10 @@ static void _StopRip( HBHandle * h )
HBAc3DecClose( &audio->decoder );
else if( audio->inCodec == HB_CODEC_LPCM )
HBLpcmDecClose( &audio->decoder );
+ else if( audio->inCodec == HB_CODEC_MPGA )
+ HBMpgaDecClose( &audio->decoder );
+
+ HBResampleClose( &audio->resample );
if( audio->outCodec == HB_CODEC_MP3 )
HBMp3EncClose( &audio->encoder );
@@ -656,6 +655,7 @@ static void _StopRip( HBHandle * h )
/* Audio fifos */
HBFifoClose( &audio->inFifo );
HBFifoClose( &audio->rawFifo );
+ HBFifoClose( &audio->resampleFifo );
HBFifoClose( &audio->outFifo );
HBListRemove( title->ripAudioList, audio );
diff --git a/core/Jamfile b/core/Jamfile
index 992dc5cf8..3c683531b 100644
--- a/core/Jamfile
+++ b/core/Jamfile
@@ -1,4 +1,4 @@
-# $Id: Jamfile,v 1.7 2004/03/29 00:28:42 titer Exp $
+# $Id: Jamfile,v 1.12 2004/04/27 19:42:24 titer Exp $
#
# This file is part of the HandBrake source code.
# Homepage: <http://handbrake.m0k.org/>.
@@ -8,21 +8,21 @@ SubDir TOP core ;
LIBHB_SRC =
Ac3Dec.c AviMux.c DVDRead.c FaacEnc.c FfmpegEnc.c Fifo.c HandBrake.c
- LpcmDec.c MadDec.c Mp3Enc.c Mp4Mux.c Mpeg2Dec.c OgmMux.c Scale.c
- Scan.c Thread.c Utils.c VorbisEnc.c Work.c X264Enc.c XvidEnc.c ;
+ LpcmDec.c Mp3Enc.c Mp4Mux.c Mpeg2Dec.c MpgaDec.c Mux.c OgmMux.c
+ Resample.c Scale.c Scan.c Thread.c Utils.c VorbisEnc.c Work.c
+ X264Enc.c XvidEnc.c ;
Library libhb : $(LIBHB_SRC) ;
# Sadly, we might want to debug our code
-ObjectCcFlags $(LIBHB_SRC) : -g -Wall ;
+ObjectCcFlags $(LIBHB_SRC) : -g -Wall -W ;
# Needed includes
ObjectHdrs Ac3Dec.c : $(TOP)/contrib/liba52 ;
ObjectHdrs FfmpegEnc.c
HandBrake.c
- Scale.c : $(TOP)/contrib/libavcodec ;
-ObjectHdrs DVDRead.c
- Scan.c : $(TOP)/contrib/libdvdplay ;
+ MpgaDec.c
+ Scale.c : $(TOP)/contrib/libavcodec ;
ObjectHdrs DVDRead.c
Scan.c : $(TOP)/contrib/libdvdread ;
ObjectHdrs FaacEnc.c : $(TOP)/contrib/libfaac ;
@@ -30,6 +30,7 @@ ObjectHdrs Mp3Enc.c : $(TOP)/contrib/libmp3lame ;
ObjectHdrs Mp4Mux.c : $(TOP)/contrib/libmp4v2 ;
ObjectHdrs Mpeg2Dec.c
Scan.c : $(TOP)/contrib/libmpeg2 ;
+ObjectHdrs Resample.c : $(TOP)/contrib/libsamplerate ;
ObjectHdrs OgmMux.c
VorbisEnc.c : $(TOP)/contrib/libogg ;
ObjectHdrs VorbisEnc.c : $(TOP)/contrib/libvorbis ;
diff --git a/core/LpcmDec.c b/core/LpcmDec.c
index 519b4868a..425f429d9 100644
--- a/core/LpcmDec.c
+++ b/core/LpcmDec.c
@@ -1,4 +1,4 @@
-/* $Id: LpcmDec.c,v 1.3 2004/03/29 00:29:41 titer Exp $
+/* $Id: LpcmDec.c,v 1.10 2004/05/10 16:50:32 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://handbrake.m0k.org/>.
@@ -6,7 +6,7 @@
#include "HBInternal.h"
-typedef struct HBLpcmDec
+struct HBWork
{
HB_WORK_COMMON_MEMBERS
@@ -14,102 +14,60 @@ typedef struct HBLpcmDec
HBAudio * audio;
int initDone;
- int channels;
- float sampleLevel;
- HBBuffer * rawBuffer;
-} HBLpcmDec;
+};
/* Local prototypes */
static int LpcmDecWork( HBWork * );
HBWork * HBLpcmDecInit( HBHandle * handle, HBAudio * audio )
{
- HBLpcmDec * l;
- if( !( l = calloc( sizeof( HBLpcmDec ), 1 ) ) )
+ HBWork * w;
+ if( !( w = calloc( sizeof( HBWork ), 1 ) ) )
{
HBLog( "HBLpcmDecInit: malloc() failed, gonna crash" );
return NULL;
}
- l->name = strdup( "LpcmDec" );
- l->work = LpcmDecWork;
+ w->name = strdup( "LpcmDec" );
+ w->work = LpcmDecWork;
- l->handle = handle;
- l->audio = audio;
+ w->handle = handle;
+ w->audio = audio;
- if( audio->outCodec & ( HB_CODEC_MP3 | HB_CODEC_VORBIS ) )
- {
- /* 16 bits samples */
- l->sampleLevel = 1.0;
- }
- else if( audio->outCodec & HB_CODEC_AAC )
- {
- /* 24 bits samples */
- l->sampleLevel = 256.0;
- }
-
- return (HBWork*) l;
-}
-
-void HBLpcmDecClose( HBWork ** _l )
-{
- HBLpcmDec * l = (HBLpcmDec*) *_l;
-
- /* Clean up */
- if( l->rawBuffer )
- {
- HBBufferClose( &l->rawBuffer );
- }
- free( l->name );
- free( l );
-
- *_l = NULL;
+ return w;
}
-#ifndef HB_MACOSX
-static int16_t Swap16( int16_t * p )
+void HBLpcmDecClose( HBWork ** _w )
{
- uint8_t tmp[2];
-
- tmp[0] = ((uint8_t*)p)[1];
- tmp[1] = ((uint8_t*)p)[0];
-
- return *(int16_t*)tmp;
+ HBWork * w = *_w;
+ free( w->name );
+ free( w );
+ *_w = NULL;
}
-#endif
static int LpcmDecWork( HBWork * w )
{
- HBLpcmDec * l = (HBLpcmDec*) w;
- HBAudio * audio = l->audio;
- HBBuffer * lpcmBuffer;
- int16_t * int16data;
+ HBAudio * audio = w->audio;
- int i;
- int samples;
- int didSomething = 0;
+ HBBuffer * lpcmBuffer;
+ HBBuffer * rawBuffer;
+ uint8_t * samples_u8;
+ float * samples_f;
+ int samples_nr, i;
- /* Push decoded buffer */
- if( l->rawBuffer )
+ if( HBFifoIsHalfFull( audio->rawFifo ) )
{
- if( HBFifoPush( audio->rawFifo, &l->rawBuffer ) )
- {
- didSomething = 1;
- }
- else
- {
- return 0;
- }
+ return 0;
}
/* Get a new LPCM buffer */
lpcmBuffer = HBFifoPop( audio->inFifo );
if( !lpcmBuffer )
{
- return didSomething;
+ return 0;
}
- if( !l->initDone )
+ if( !w->initDone )
{
/* SampleRate */
switch( ( lpcmBuffer->data[4] >> 4 ) & 0x3 )
@@ -121,45 +79,46 @@ static int LpcmDecWork( HBWork * w )
audio->inSampleRate = 32000;
break;
default:
- HBLog( "LpcmDec: unknown samplerate (%d)",
+ HBLog( "HBLpcmDec: unknown samplerate (%d)",
( lpcmBuffer->data[4] >> 4 ) & 0x3 );
}
- HBLog( "LpcmDec: samplerate = %d Hz", audio->inSampleRate );
- /* Channels */
- HBLog( "LpcmDec: %d channels",
- ( lpcmBuffer->data[4] & 0x7 ) + 1 );
+ /* We hope there are 2 channels */
+ HBLog( "HBLpcmDec: samplerate: %d Hz, channels: %d",
+ audio->inSampleRate, ( lpcmBuffer->data[4] & 0x7 ) + 1 );
- l->initDone = 1;
+ w->initDone = 1;
}
if( lpcmBuffer->data[5] != 0x80 )
{
- HBLog( "LpcmDec: no frame synx (%02x�", lpcmBuffer->data[5] );
+ HBLog( "HBLpcmDec: no frame sync (%02x)", lpcmBuffer->data[5] );
}
- samples = ( lpcmBuffer->size - 6 ) / sizeof( int16_t ) / 2;
- int16data = (int16_t*) ( lpcmBuffer->data + 6 );
-
- l->rawBuffer = HBBufferInit( samples * sizeof( float ) * 2 );
- l->rawBuffer->left = (float*) l->rawBuffer->data;
- l->rawBuffer->right = l->rawBuffer->left + samples;
- l->rawBuffer->position = lpcmBuffer->position;
- l->rawBuffer->samples = samples;
+ /* Allocate raw buffer */
+ samples_nr = ( lpcmBuffer->size - 6 ) / sizeof( int16_t );
+ rawBuffer = HBBufferInit( samples_nr * sizeof( float ) );
+ rawBuffer->position = lpcmBuffer->position;
- for( i = 0; i < samples; i++ )
+ /* Big endian int16 -> float conversion (happy casting) */
+ samples_u8 = lpcmBuffer->data + 6;
+ samples_f = rawBuffer->dataf;
+ for( i = 0; i < samples_nr; i++ )
{
-#ifdef HB_MACOSX
- l->rawBuffer->left[i] = (float) int16data[2*i] * l->sampleLevel;
- l->rawBuffer->right[i] = (float) int16data[2*i+1] * l->sampleLevel;
-#else
- l->rawBuffer->left[i] = (float) Swap16(&int16data[2*i]) * l->sampleLevel;
- l->rawBuffer->right[i] = (float) Swap16(&int16data[2*i+1]) * l->sampleLevel;
-#endif
+ samples_f[0] = (float) (int16_t)
+ ( ( ( (uint16_t) samples_u8[0] ) << 8 ) +
+ (uint16_t) samples_u8[1] );
+ samples_u8 += 2;
+ samples_f += 1;
}
HBBufferClose( &lpcmBuffer );
+ if( !HBFifoPush( audio->rawFifo, &rawBuffer ) )
+ {
+ HBLog( "HBLpcmDec: HBFifoPush failed" );
+ }
+
return 1;
}
diff --git a/core/MadDec.c b/core/MadDec.c
deleted file mode 100644
index da79ad886..000000000
--- a/core/MadDec.c
+++ /dev/null
@@ -1,8 +0,0 @@
-/* $Id: MadDec.c,v 1.2 2003/12/26 20:03:27 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 "HBInternal.h"
-
diff --git a/core/Mp3Enc.c b/core/Mp3Enc.c
index bd62df4ae..c1aae34fe 100644
--- a/core/Mp3Enc.c
+++ b/core/Mp3Enc.c
@@ -1,4 +1,4 @@
-/* $Id: Mp3Enc.c,v 1.13 2004/01/21 17:59:33 titer Exp $
+/* $Id: Mp3Enc.c,v 1.23 2004/05/02 16:25:00 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://handbrake.m0k.org/>.
@@ -9,226 +9,110 @@
/* libmp3lame */
#include "lame/lame.h"
-typedef struct HBMp3Enc
+struct HBWork
{
HB_WORK_COMMON_MEMBERS
HBHandle * handle;
HBAudio * audio;
lame_global_flags * globalFlags;
- HBBuffer * rawBuffer;
- int rawBufferPos;
- float position;
- int inputSamples;
- int samplesGot;
- float * left;
- float * right;
- HBBuffer * mp3Buffer;
-
- /* Stats */
- int64_t samples;
- int64_t bytes;
-} HBMp3Enc;
+};
/* Local prototypes */
static int Mp3EncWork( HBWork * );
-static int GetSamples( HBMp3Enc * );
HBWork * HBMp3EncInit( HBHandle * handle, HBAudio * audio )
{
- HBMp3Enc * m;
- if( !( m = calloc( sizeof( HBMp3Enc ), 1 ) ) )
+ HBWork * w;
+ if( !( w = calloc( sizeof( HBWork ), 1 ) ) )
{
HBLog( "HBMp3EncInit: malloc() failed, gonna crash" );
return NULL;
}
- m->name = strdup( "Mp3Enc" );
- m->work = Mp3EncWork;
+ w->name = strdup( "Mp3Enc" );
+ w->work = Mp3EncWork;
- m->handle = handle;
- m->audio = audio;
+ w->handle = handle;
+ w->audio = audio;
- return (HBWork*) m;
+ return w;
}
-void HBMp3EncClose( HBWork ** _m )
+void HBMp3EncClose( HBWork ** _w )
{
- HBMp3Enc * m = (HBMp3Enc*) *_m;
-
- if( m->globalFlags ) lame_close( m->globalFlags );
- if( m->rawBuffer ) HBBufferClose( &m->rawBuffer );
- if( m->left ) free( m->left );
- if( m->right ) free( m->right );
- if( m->mp3Buffer ) HBBufferClose( &m->mp3Buffer );
+ HBWork * w = *_w;
- if( m->samples )
- {
- int64_t bytes = 128 * m->audio->outBitrate * m->samples /
- m->audio->inSampleRate;
- float bitrate = (float) m->bytes * m->audio->inSampleRate /
- m->samples / 128;
+ if( w->globalFlags ) lame_close( w->globalFlags );
- HBLog( "HBMp3Enc: %lld samples encoded (%lld bytes), %.2f kbps",
- m->samples, m->bytes, bitrate );
- HBLog( "HBFaacEnc: error is %lld bytes", m->bytes - bytes );
- }
-
- free( m->name );
- free( m );
-
- *_m = NULL;
+ free( w->name );
+ free( w );
+ *_w = NULL;
}
static int Mp3EncWork( HBWork * w )
{
- HBMp3Enc * m = (HBMp3Enc*) w;
- HBAudio * audio = m->audio;
+ HBAudio * audio = w->audio;
HBBuffer * mp3Buffer;
int ret;
- int didSomething = 0;
+ float samples_f[1152 * 2];
+ int16_t samples_s16[1152 * 2];
+ float position;
+ int i;
- if( !m->globalFlags )
+ if( !w->globalFlags )
{
- int i;
-
- /* Get a first buffer so we know that audio->inSampleRate is
- correct */
- if( ( m->rawBuffer = HBFifoPop( audio->rawFifo ) ) )
+ if( !HBFifoSize( audio->resampleFifo ) )
{
- didSomething = 1;
+ return 0;
}
- else
- {
- return didSomething;
- }
- m->rawBufferPos = 0;
- m->position = m->rawBuffer->position;
-
- /* The idea is to have exactly one mp3 frame (i.e. 1152 samples) by
- output buffer. As we are resampling from inSampleRate to
- outSampleRate, we will give ( 1152 * inSampleRate ) /
- ( 2 * outSampleRate ) samples to libmp3lame so we are sure we
- will never get more than 1 frame at a time */
- audio->outSampleRate = 44100;
- m->inputSamples = 1152 * audio->inSampleRate /
- audio->outSampleRate / 2;
-
- HBLog( "HBMp3Enc: opening lame (%d->%d Hz, %d kbps)",
- audio->inSampleRate, audio->outSampleRate,
- audio->outBitrate );
- m->globalFlags = lame_init();
- lame_set_in_samplerate( m->globalFlags, audio->inSampleRate );
- lame_set_out_samplerate( m->globalFlags, audio->outSampleRate );
- lame_set_brate( m->globalFlags, audio->outBitrate );
- if( lame_init_params( m->globalFlags ) == -1 )
- {
- HBLog( "HBMp3Enc: lame_init_params() failed" );
- HBErrorOccured( m->handle, HB_ERROR_MP3_INIT );
- return didSomething;
- }
+ HBLog( "HBMp3Enc: opening lame (%d kbps)", audio->outBitrate );
- m->left = malloc( m->inputSamples * sizeof( float ) );
- m->right = malloc( m->inputSamples * sizeof( float ) );
+ w->globalFlags = lame_init();
+ lame_set_brate( w->globalFlags, audio->outBitrate );
- if( !m->left || !m->right )
- {
- HBLog( "HBMp3Enc: malloc() failed, gonna crash" );
- }
+ /* No resampling there - it's been done before */
+ lame_set_in_samplerate( w->globalFlags, audio->outSampleRate );
+ lame_set_out_samplerate( w->globalFlags, audio->outSampleRate );
- for( i = 0; i < m->inputSamples; i++ )
+ if( lame_init_params( w->globalFlags ) == -1 )
{
- m->left[i] = 0.0;
- m->right[i] = 0.0;
+ HBLog( "HBMp3Enc: lame_init_params() failed" );
+ HBErrorOccured( w->handle, HB_ERROR_MP3_INIT );
+ return 0;
}
}
- /* Push encoded buffer */
- if( m->mp3Buffer )
+ if( HBFifoIsHalfFull( audio->outFifo ) )
{
- if( HBFifoPush( audio->outFifo, &m->mp3Buffer ) )
- {
- didSomething = 1;
- }
- else
- {
- return didSomething;
- }
+ return 0;
}
- /* A/V synchro fix in case audio doesn't start at the same time
- than video */
- if( audio->delay > 0 )
+ if( !HBFifoGetBytes( audio->resampleFifo, (uint8_t*) samples_f,
+ 1152 * 2 * sizeof( float ), &position ) )
{
- /* Audio starts later - insert some silence */
- int length = m->inputSamples * 1000 / audio->inSampleRate;
-
- if( audio->delay > length )
- {
- HBLog( "HBMp3Enc: adding %d ms of silence", length );
- m->samplesGot = m->inputSamples;
- audio->delay -= length;
- }
- else
- {
- audio->delay = 0;
- }
+ return 0;
}
- else if( audio->delay < 0 )
- {
- /* Audio starts sooner - trash some */
- int length = m->inputSamples * 1000 / audio->inSampleRate;
- if( - audio->delay > length )
- {
- if( GetSamples( m ) )
- {
- didSomething = 1;
- HBLog( "HBMp3Enc: trashing %d ms", length );
- m->samplesGot = 0;
- audio->delay += length;
- return didSomething;
- }
- else
- {
- return didSomething;
- }
- }
- else
- {
- audio->delay = 0;
- }
- }
-
- /* Get new samples */
- if( GetSamples( m ) )
+ /* float -> s16 */
+ for( i = 0; i < 1152 * 2; i++ )
{
- didSomething = 1;
+ samples_s16[i] = samples_f[i];
}
- else
- {
- return didSomething;
- }
-
- m->samplesGot = 0;
mp3Buffer = HBBufferInit( LAME_MAXMP3BUFFER );
- ret = lame_encode_buffer_float( m->globalFlags, m->left,
- m->right, m->inputSamples,
- mp3Buffer->data,
- mp3Buffer->size );
- /* Stats */
- m->samples += m->inputSamples;
+ ret = lame_encode_buffer_interleaved( w->globalFlags,
+ samples_s16, 1152, mp3Buffer->data, LAME_MAXMP3BUFFER );
if( ret < 0 )
{
/* Error */
HBLog( "HBMp3Enc: lame_encode_buffer_float() failed (%d)",
ret );
- HBErrorOccured( m->handle, HB_ERROR_MP3_ENCODE );
+ HBErrorOccured( w->handle, HB_ERROR_MP3_ENCODE );
HBBufferClose( &mp3Buffer );
}
else if( ret == 0 )
@@ -241,51 +125,14 @@ static int Mp3EncWork( HBWork * w )
/* Encoding was successful */
mp3Buffer->size = ret;
mp3Buffer->keyFrame = 1;
- mp3Buffer->position = m->position;
- m->mp3Buffer = mp3Buffer;
+ mp3Buffer->position = position;
- /* Stats */
- m->bytes += ret;
- }
-
- return didSomething;
-}
-
-static int GetSamples( HBMp3Enc * m )
-{
- while( m->samplesGot < m->inputSamples )
- {
- int i;
-
- if( !m->rawBuffer )
- {
- if( !( m->rawBuffer = HBFifoPop( m->audio->rawFifo ) ) )
- {
- return 0;
- }
-
- m->rawBufferPos = 0;
- m->position = m->rawBuffer->position;
- }
-
- i = MIN( m->inputSamples - m->samplesGot,
- m->rawBuffer->samples - m->rawBufferPos );
-
- memcpy( m->left + m->samplesGot,
- m->rawBuffer->left + m->rawBufferPos,
- i * sizeof( float ) );
- memcpy( m->right + m->samplesGot,
- m->rawBuffer->right + m->rawBufferPos,
- i * sizeof( float ) );
-
- m->samplesGot += i;
- m->rawBufferPos += i;
-
- if( m->rawBufferPos == m->rawBuffer->samples )
+ if( !HBFifoPush( audio->outFifo, &mp3Buffer ) )
{
- HBBufferClose( &m->rawBuffer );
+ HBLog( "HBMp3Enc: HBFifoPush failed" );
}
}
return 1;
}
+
diff --git a/core/Mp4Mux.c b/core/Mp4Mux.c
index c545c96fc..d48c1adc6 100644
--- a/core/Mp4Mux.c
+++ b/core/Mp4Mux.c
@@ -1,4 +1,4 @@
-/* $Id: Mp4Mux.c,v 1.24 2004/03/08 13:42:29 titer Exp $
+/* $Id: Mp4Mux.c,v 1.31 2004/05/13 21:10:56 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://handbrake.m0k.org/>.
@@ -9,191 +9,170 @@
/* libmp4v2 */
#include "mp4.h"
-int64_t videoFrames;
-int64_t videoBytes;
-int64_t audioFrames;
-int64_t audioBytes;
-
-/* Local prototypes */
-static void Mp4MuxThread( void * );
-
-struct HBMp4Mux
+struct HBMux
{
+ HB_MUX_COMMON_MEMBERS
+
HBHandle * handle;
HBTitle * title;
- volatile int die;
- HBThread * thread;
+ MP4FileHandle file;
+
+ /* QuickTime sync workaround */
+ int sampleRate;
+ uint64_t frames;
+ uint64_t date;
+
};
-HBMp4Mux * HBMp4MuxInit( HBHandle * handle, HBTitle * title )
+typedef struct
+{
+ int track;
+
+} Mp4MuxData;
+
+/* Local prototypes */
+static int Mp4Start( HBMux * );
+static int Mp4MuxVideo( HBMux *, void *, HBBuffer *);
+static int Mp4MuxAudio( HBMux *, void *, HBBuffer *);
+static int Mp4End( HBMux * );
+
+HBMux * HBMp4MuxInit( HBHandle * handle, HBTitle * title )
{
- HBMp4Mux * m;
- if( !( m = malloc( sizeof( HBMp4Mux ) ) ) )
+ HBMux * m;
+ HBAudio * audio;
+ int i;
+
+ if( !( m = calloc( sizeof( HBMux ), 1 ) ) )
{
- HBLog( "HBMp4MuxInit: malloc() failed, gonna crash" );
+ HBLog( "HBMp4Mux: malloc() failed, gonna crash" );
return NULL;
}
-
- videoFrames = 0;
- videoBytes = 0;
- audioFrames = 0;
- audioBytes = 0;
+ m->start = Mp4Start;
+ m->muxVideo = Mp4MuxVideo;
+ m->muxAudio = Mp4MuxAudio;
+ m->end = Mp4End;
m->handle = handle;
m->title = title;
- m->die = 0;
- m->thread = HBThreadInit( "mp4 muxer", Mp4MuxThread, m,
- HB_NORMAL_PRIORITY );
+ /* Alloc muxer data */
+ title->muxData = calloc( sizeof( Mp4MuxData ), 1 );
+ for( i = 0; i < HBListCount( title->ripAudioList ); i++ )
+ {
+ audio = (HBAudio *) HBListItemAt( title->ripAudioList, i );
+ audio->muxData = calloc( sizeof( Mp4MuxData ), 1 );
+ }
+
return m;
}
-void HBMp4MuxClose( HBMp4Mux ** _m )
+void HBMp4MuxClose( HBMux ** _m )
{
- HBMp4Mux * m = *_m;
- FILE * file;
- long size;
-
- m->die = 1;
- HBThreadClose( &m->thread );
-
- file = fopen( m->title->file, "r" );
- if( file )
+ HBMux * m = *_m;
+ HBTitle * title = m->title;
+ HBAudio * audio;
+ int i;
+
+ /* Free muxer data */
+ free( title->muxData );
+ for( i = 0; i < HBListCount( title->ripAudioList ); i++ )
{
- fseek( file, 0, SEEK_END );
- size = ftell( file );
- fclose( file );
-
- HBLog( "HBMp4Mux: videoFrames=%lld, %lld bytes",
- videoFrames, videoBytes );
- HBLog( "HBMp4Mux: audioFrames=%lld, %lld bytes",
- audioFrames, audioBytes );
- HBLog( "HBMp4Mux: overhead=%.2f bytes / frame",
- ( (float) size - videoBytes - audioBytes ) /
- ( videoFrames + audioFrames ) );
+ audio = (HBAudio *) HBListItemAt( title->ripAudioList, i );
+ free( audio->muxData );
}
free( m );
-
*_m = NULL;
}
-static void Mp4MuxThread( void * _m )
+static int Mp4Start( HBMux * m )
{
- HBMp4Mux * m = (HBMp4Mux*) _m;
- HBTitle * title = m->title;
- HBAudio * audio;
- HBBuffer * buffer;
- char tmpFile[1024];
+ HBTitle * title = m->title;
+ HBAudio * audio;
+ Mp4MuxData * muxData;
+ int i;
- int audioCount = HBListCount( m->title->ripAudioList );
- int i;
+ /* Create file */
+ m->file = MP4Create( title->file, 0, 0 );
- MP4FileHandle file;
-
- /* Wait until we have one encoded frame for each track */
- while( !m->die && !HBFifoSize( title->outFifo ) )
+ /* Add video track */
+ muxData = (Mp4MuxData *) title->muxData;
+ if( HBListCount( title->ripAudioList ) )
{
- HBSnooze( 10000 );
+ /* QuickTime sync workaround */
+ audio = (HBAudio *) HBListItemAt( title->ripAudioList, 0 );
+ m->sampleRate = audio->outSampleRate;
+ MP4SetTimeScale( m->file, m->sampleRate );
+ muxData->track = MP4AddVideoTrack( m->file, m->sampleRate,
+ MP4_INVALID_DURATION, title->outWidth, title->outHeight,
+ MP4_MPEG4_VIDEO_TYPE );
}
- for( i = 0; i < audioCount; i++ )
+ else
{
- audio = HBListItemAt( title->ripAudioList, i );
- while( !m->die && !HBFifoSize( audio->outFifo ) )
- {
- HBSnooze( 10000 );
- }
+ MP4SetTimeScale( m->file, 90000 );
+ muxData->track = MP4AddVideoTrack( m->file, 90000,
+ (uint64_t) 90000 * title->rateBase / title->rate,
+ title->outWidth, title->outHeight,
+ MP4_MPEG4_VIDEO_TYPE );
}
+ MP4SetVideoProfileLevel( m->file, 0x03 );
+ MP4SetTrackESConfiguration( m->file, muxData->track,
+ title->esConfig, title->esConfigLength );
- if( m->die )
+ /* Add audio tracks */
+ for( i = 0; i < HBListCount( title->ripAudioList ); i++ )
{
- return;
+ audio = HBListItemAt( title->ripAudioList, i );
+ muxData = (Mp4MuxData *) audio->muxData;
+ muxData->track = MP4AddAudioTrack( m->file,
+ audio->outSampleRate, 1024, MP4_MPEG4_AUDIO_TYPE );
+ MP4SetAudioProfileLevel( m->file, 0x0F );
+ MP4SetTrackESConfiguration( m->file, muxData->track,
+ audio->esConfig, audio->esConfigLength );
}
- /* Write file headers */
- file = MP4Create( title->file, 0, 0 );
- MP4SetTimeScale( file, 90000 );
- title->track = MP4AddVideoTrack( file, 90000,
- MP4_INVALID_DURATION,
- title->outWidth, title->outHeight,
- MP4_MPEG4_VIDEO_TYPE );
- MP4SetVideoProfileLevel( file, 0x03 );
- MP4SetTrackESConfiguration( file, title->track, title->esConfig,
- title->esConfigLength );
-
- for( i = 0; i < audioCount; i++ )
+ return 0;
+}
+
+static int Mp4MuxVideo( HBMux * m, void * _muxData, HBBuffer * buffer )
+{
+ Mp4MuxData * muxData = (Mp4MuxData *) _muxData;
+ HBTitle * title = m->title;
+
+ if( HBListCount( title->ripAudioList ) )
{
- audio = HBListItemAt( title->ripAudioList, i );
- audio->track = MP4AddAudioTrack( file, audio->outSampleRate,
- 1024, MP4_MPEG4_AUDIO_TYPE );
- MP4SetAudioProfileLevel( file, 0x0F );
- MP4SetTrackESConfiguration( file, audio->track, audio->esConfig,
- audio->esConfigLength );
+ /* QuickTime sync workaround */
+ int dur = (uint64_t) m->sampleRate * ( ++m->frames ) *
+ title->rateBase / title->rate - m->date;
+ MP4WriteSample( m->file, muxData->track, buffer->data, buffer->size,
+ dur, 0, buffer->keyFrame );
+ m->date += dur;
}
-
- for( ;; )
+ else
{
- /* Wait until we have one encoded frame for each track */
- if( !HBFifoWait( title->outFifo ) )
- {
- m->die = 1;
- break;
- }
- for( i = 0; i < audioCount; i++ )
- {
- audio = HBListItemAt( title->ripAudioList, i );
- if( !HBFifoWait( audio->outFifo ) )
- {
- m->die = 1;
- break;
- }
- }
-
- if( m->die )
- {
- break;
- }
-
- /* Interleave frames in the same order than they were in the
- original MPEG stream */
- audio = NULL;
- for( i = 0; i < audioCount; i++ )
- {
- HBAudio * otherAudio;
- otherAudio = HBListItemAt( title->ripAudioList, i );
- if( !audio || HBFifoPosition( otherAudio->outFifo ) <
- HBFifoPosition( audio->outFifo ) )
- {
- audio = otherAudio;
- }
- }
-
- if( !audio || HBFifoPosition( title->outFifo ) <
- HBFifoPosition( audio->outFifo ) )
- {
- buffer = HBFifoPop( title->outFifo );
- MP4WriteSample( file, title->track, buffer->data,
- buffer->size,
- (uint64_t) 90000 * title->rateBase / title->rate,
- 0, buffer->keyFrame );
- videoFrames++;
- videoBytes += buffer->size;
- HBBufferClose( &buffer );
- }
- else
- {
- buffer = HBFifoPop( audio->outFifo );
- MP4WriteSample( file, audio->track, buffer->data,
- buffer->size, MP4_INVALID_DURATION,
- 0, buffer->keyFrame );
- audioFrames++;
- audioBytes += buffer->size;
- HBBufferClose( &buffer );
- }
+ MP4WriteSample( m->file, muxData->track, buffer->data,
+ buffer->size, MP4_INVALID_DURATION, 0,
+ buffer->keyFrame );
}
+ return 0;
+}
+
+static int Mp4MuxAudio( HBMux * m, void * _muxData, HBBuffer * buffer )
+{
+ Mp4MuxData * muxData = (Mp4MuxData *) _muxData;
+
+ MP4WriteSample( m->file, muxData->track, buffer->data, buffer->size,
+ MP4_INVALID_DURATION, 0, buffer->keyFrame );
+ return 0;
+}
+
+static int Mp4End( HBMux * m )
+{
+ HBTitle * title = m->title;
+ char tmpFile[1024];
- MP4Close( file );
+ MP4Close( m->file );
HBLog( "HBMp4Mux: making the file ISMA compliant" );
if( !MP4MakeIsmaCompliant( title->file, 0 /*MP4_DETAILS_ALL*/, 1 ) )
@@ -213,5 +192,6 @@ static void Mp4MuxThread( void * _m )
{
rename( tmpFile, title->file );
}
+ return 0;
}
diff --git a/core/Mpeg2Dec.c b/core/Mpeg2Dec.c
index ea3ffa2e4..043c416dc 100644
--- a/core/Mpeg2Dec.c
+++ b/core/Mpeg2Dec.c
@@ -1,4 +1,4 @@
-/* $Id: Mpeg2Dec.c,v 1.12 2004/01/16 19:04:04 titer Exp $
+/* $Id: Mpeg2Dec.c,v 1.15 2004/05/02 16:25:00 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://handbrake.m0k.org/>.
@@ -8,170 +8,144 @@
#include "mpeg2dec/mpeg2.h"
-typedef struct HBMpeg2Dec
+struct HBWork
{
HB_WORK_COMMON_MEMBERS
HBHandle * handle;
HBTitle * title;
- HBList * rawBufferList;
int pass;
mpeg2dec_t * libmpeg2;
const mpeg2_info_t * info;
int lateField;
-} HBMpeg2Dec;
+};
/* Local prototypes */
static int Mpeg2DecWork( HBWork * );
HBWork * HBMpeg2DecInit( HBHandle * handle, HBTitle * title )
{
- HBMpeg2Dec * m ;
- if( !( m = malloc( sizeof( HBMpeg2Dec ) ) ) )
+ HBWork * w ;
+ if( !( w = malloc( sizeof( HBWork ) ) ) )
{
HBLog( "HBMpeg2Dec: malloc() failed, gonna crash" );
return NULL;
}
- m->name = strdup( "Mpeg2Dec" );
- m->work = Mpeg2DecWork;
+ w->name = strdup( "Mpeg2Dec" );
+ w->work = Mpeg2DecWork;
- m->handle = handle;
- m->title = title;
+ w->handle = handle;
+ w->title = title;
- m->rawBufferList = HBListInit();
- m->pass = 42;
- m->libmpeg2 = NULL;
- m->info = NULL;
- m->lateField = 0;
+ w->pass = 42;
+ w->libmpeg2 = NULL;
+ w->info = NULL;
+ w->lateField = 0;
- return (HBWork*) m;
+ return w;
}
-void HBMpeg2DecClose( HBWork ** _m )
+void HBMpeg2DecClose( HBWork ** _w )
{
- HBBuffer * buffer;
+ HBWork * w = *_w;
- HBMpeg2Dec * m = (HBMpeg2Dec*) *_m;
-
- if( m->libmpeg2 )
- {
- HBLog( "HBMpeg2Dec: closing libmpeg2 (pass %d)", m->pass );
- mpeg2_close( m->libmpeg2 );
- }
- while( ( buffer = HBListItemAt( m->rawBufferList, 0 ) ) )
+ if( w->libmpeg2 )
{
- HBListRemove( m->rawBufferList, buffer );
- HBBufferClose( &buffer );
+ HBLog( "HBMpeg2Dec: closing libmpeg2 (pass %d)", w->pass );
+ mpeg2_close( w->libmpeg2 );
}
- HBListClose( &m->rawBufferList );
- free( m->name );
- free( m );
+ free( w->name );
+ free( w );
- *_m = NULL;
+ *_w = NULL;
}
static int Mpeg2DecWork( HBWork * w )
{
- HBMpeg2Dec * m = (HBMpeg2Dec*) w;
- HBTitle * title = m->title;
+ HBTitle * title = w->title;
HBBuffer * mpeg2Buffer;
HBBuffer * rawBuffer;
- HBBuffer * tmpBuffer;
mpeg2_state_t state;
- int didSomething = 0;
-
- /* Push decoded buffers */
- while( ( rawBuffer = (HBBuffer*)
- HBListItemAt( m->rawBufferList, 0 ) ) )
+ if( HBFifoIsHalfFull( title->rawFifo ) )
{
- tmpBuffer = rawBuffer;
- if( HBFifoPush( title->rawFifo, &rawBuffer ) )
- {
- didSomething = 1;
- HBListRemove( m->rawBufferList, tmpBuffer );
- }
- else
- {
- return didSomething;
- }
+ return 0;
}
/* Get a new buffer to decode */
- if( ( mpeg2Buffer = HBFifoPop( title->inFifo ) ) )
- {
- didSomething = 1;
- }
- else
+ if( !( mpeg2Buffer = HBFifoPop( title->inFifo ) ) )
{
- return didSomething;
+ return 0;
}
/* Init or re-init if needed */
- if( mpeg2Buffer->pass != m->pass )
+ if( mpeg2Buffer->pass != w->pass )
{
- if( m->libmpeg2 )
+ if( w->libmpeg2 )
{
- HBLog( "HBMpeg2Dec: closing libmpeg2 (pass %d)", m->pass );
- mpeg2_close( m->libmpeg2 );
+ HBLog( "HBMpeg2Dec: closing libmpeg2 (pass %d)", w->pass );
+ mpeg2_close( w->libmpeg2 );
}
- m->pass = mpeg2Buffer->pass;
+ w->pass = mpeg2Buffer->pass;
- HBLog( "HBMpeg2Dec: opening libmpeg2 (pass %d)", m->pass );
+ HBLog( "HBMpeg2Dec: opening libmpeg2 (pass %d)", w->pass );
#ifdef HB_NOMMX
mpeg2_accel( 0 );
#endif
- m->libmpeg2 = mpeg2_init();
- m->info = mpeg2_info( m->libmpeg2 );
- m->lateField = 0;
+ w->libmpeg2 = mpeg2_init();
+ w->info = mpeg2_info( w->libmpeg2 );
+ w->lateField = 0;
}
/* Decode */
- mpeg2_buffer( m->libmpeg2, mpeg2Buffer->data,
+ mpeg2_buffer( w->libmpeg2, mpeg2Buffer->data,
mpeg2Buffer->data + mpeg2Buffer->size );
for( ;; )
{
- state = mpeg2_parse( m->libmpeg2 );
+ state = mpeg2_parse( w->libmpeg2 );
if( state == STATE_BUFFER )
{
break;
}
else if( ( state == STATE_SLICE || state == STATE_END ) &&
- m->info->display_fbuf )
+ w->info->display_fbuf )
{
rawBuffer = HBBufferInit( 3 * title->inWidth *
title->inHeight );
/* TODO: make libmpeg2 write directly in our buffer */
- memcpy( rawBuffer->data, m->info->display_fbuf->buf[0],
+ memcpy( rawBuffer->data, w->info->display_fbuf->buf[0],
title->inWidth * title->inHeight );
memcpy( rawBuffer->data + title->inWidth * title->inHeight,
- m->info->display_fbuf->buf[1],
+ w->info->display_fbuf->buf[1],
title->inWidth * title->inHeight / 4 );
memcpy( rawBuffer->data + title->inWidth * title->inHeight +
title->inWidth * title->inHeight / 4,
- m->info->display_fbuf->buf[2],
+ w->info->display_fbuf->buf[2],
title->inWidth * title->inHeight / 4 );
rawBuffer->position = mpeg2Buffer->position;
rawBuffer->pass = mpeg2Buffer->pass;
- HBListAdd( m->rawBufferList, rawBuffer );
-
/* NTSC pulldown kludge */
- if( m->info->display_picture->nb_fields == 3 )
+ if( w->info->display_picture->nb_fields == 3 )
{
- rawBuffer->repeat = m->lateField;
- m->lateField = !m->lateField;
+ rawBuffer->repeat = w->lateField;
+ w->lateField = !w->lateField;
}
else
{
rawBuffer->repeat = 0;
}
+
+ if( !HBFifoPush( title->rawFifo, &rawBuffer ) )
+ {
+ HBLog( "HBMpeg2Dec: HBFifoPush failed" );
+ }
}
else if( state == STATE_INVALID )
{
@@ -182,5 +156,5 @@ static int Mpeg2DecWork( HBWork * w )
HBBufferClose( &mpeg2Buffer );
- return didSomething;
+ return 1;
}
diff --git a/core/MpgaDec.c b/core/MpgaDec.c
new file mode 100644
index 000000000..e397a7234
--- /dev/null
+++ b/core/MpgaDec.c
@@ -0,0 +1,132 @@
+/* $Id: MpgaDec.c,v 1.3 2004/05/02 16:25:00 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 "HBInternal.h"
+
+#include "ffmpeg/avcodec.h"
+
+struct HBWork
+{
+ HB_WORK_COMMON_MEMBERS
+
+ HBHandle * handle;
+ HBAudio * audio;
+
+ AVCodecContext * context;
+};
+
+/* Local prototypes */
+static int MpgaDecWork( HBWork * );
+
+HBWork * HBMpgaDecInit( HBHandle * handle, HBAudio * audio )
+{
+ HBWork * w;
+ AVCodec * codec;
+
+ if( !( w = calloc( sizeof( HBWork ), 1 ) ) )
+ {
+ HBLog( "HBMpgaDecInit: malloc() failed, gonna crash" );
+ return NULL;
+ }
+
+ w->name = strdup( "MpgaDec" );
+ w->work = MpgaDecWork;
+
+ w->handle = handle;
+ w->audio = audio;
+
+ codec = avcodec_find_decoder( CODEC_ID_MP2 );
+ if( !codec )
+ {
+ HBLog( "HBMpgaDec: avcodec_find_decoder failed" );
+ }
+
+ w->context = avcodec_alloc_context();
+ if( !w->context )
+ {
+ HBLog( "HBMpgaDec: avcodec_alloc_context failed" );
+ }
+
+ if( avcodec_open( w->context, codec ) < 0 )
+ {
+ HBLog( "HBMpgaDec: avcodec_open failed" );
+ }
+
+ return w;
+}
+
+void HBMpgaDecClose( HBWork ** _w )
+{
+ HBWork * w = *_w;
+
+ avcodec_close( w->context );
+ free( w->name );
+ free( w );
+ *_w = NULL;
+}
+
+static int MpgaDecWork( HBWork * w )
+{
+ HBAudio * audio = w->audio;
+
+ HBBuffer * mpgaBuffer;
+ HBBuffer * rawBuffer;
+
+ int out_size, len, pos;
+ short buffer[AVCODEC_MAX_AUDIO_FRAME_SIZE];
+
+ if( HBFifoIsHalfFull( audio->rawFifo ) )
+ {
+ return 0;
+ }
+
+ /* Get a new mpeg buffer */
+ mpgaBuffer = HBFifoPop( audio->inFifo );
+ if( !mpgaBuffer )
+ {
+ return 0;
+ }
+
+ pos = 0;
+ while( pos < mpgaBuffer->size )
+ {
+ len = avcodec_decode_audio( w->context, buffer, &out_size,
+ mpgaBuffer->data + pos,
+ mpgaBuffer->size - pos );
+ pos += len;
+
+ if( !audio->inSampleRate )
+ {
+ audio->inSampleRate = w->context->sample_rate;
+ HBLog( "HBMpgaDec: samplerate = %d", audio->inSampleRate );
+ }
+
+ if( out_size )
+ {
+ int i;
+ rawBuffer = HBBufferInit( 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE );
+ rawBuffer->position = mpgaBuffer->position;
+
+ /* s16 -> float */
+ for( i = 0; i < out_size / 2; i++ )
+ {
+ rawBuffer->dataf[i] = buffer[i];
+ }
+
+ rawBuffer->size = out_size * 2;
+
+ if( !HBFifoPush( audio->rawFifo, &rawBuffer ) )
+ {
+ HBLog( "HBMpgaDec: HBFifoPush failed" );
+ }
+ }
+ }
+
+ HBBufferClose( &mpgaBuffer );
+
+ return 1;
+}
+
diff --git a/core/Mux.c b/core/Mux.c
new file mode 100644
index 000000000..c9449e7ff
--- /dev/null
+++ b/core/Mux.c
@@ -0,0 +1,228 @@
+/* $Id: Mux.c,v 1.9 2004/05/25 17:36:40 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 <sys/types.h>
+#include <sys/stat.h>
+
+#include "HBInternal.h"
+
+HBMux * HBAviMuxInit( HBHandle * handle, HBTitle * title );
+void HBAviMuxClose( HBMux ** );
+HBMux * HBMp4MuxInit( HBHandle * handle, HBTitle * title );
+void HBMp4MuxClose( HBMux ** );
+HBMux * HBOgmMuxInit( HBHandle * handle, HBTitle * title );
+void HBOgmMuxClose( HBMux ** );
+
+/* Local prototypes */
+static void MuxThread( void * t );
+
+struct HBMux
+{
+ HB_MUX_COMMON_MEMBERS
+};
+
+struct HBMuxThread
+{
+ HBHandle * handle;
+ HBTitle * title;
+ HBMux * mux;
+
+ uint64_t videoFrames;
+ uint64_t videoBytes;
+ uint64_t audioFrames;
+ uint64_t audioBytes;
+
+ volatile int die;
+ HBThread * thread;
+};
+
+HBMuxThread * HBMuxThreadInit( HBHandle * handle, HBTitle * title )
+{
+ HBMuxThread * t;
+ if( !( t = calloc( sizeof( HBMuxThread ), 1 ) ) )
+ {
+ HBLog( "HBMuxThreadInit: malloc() failed, gonna crash" );
+ return NULL;
+ }
+ t->handle = handle;
+ t->title = title;
+
+ /* Init muxer */
+ if( title->mux == HB_MUX_AVI )
+ t->mux = HBAviMuxInit( handle, title );
+ else if( title->mux == HB_MUX_MP4 )
+ t->mux = HBMp4MuxInit( handle, title );
+ else if( title->mux == HB_MUX_OGM )
+ t->mux = HBOgmMuxInit( handle, title );
+
+ /* Launch the thread */
+ t->thread = HBThreadInit( "mux thread", MuxThread, t,
+ HB_NORMAL_PRIORITY );
+
+ return t;
+}
+
+void HBMuxThreadClose( HBMuxThread ** _t )
+{
+ HBMuxThread * t = (*_t);
+ HBTitle * title = t->title;
+ struct stat sb;
+
+ /* Stop the thread */
+ t->die = 1;
+ HBThreadClose( &t->thread );
+
+ /* Close muxer */
+ if( title->mux == HB_MUX_AVI )
+ HBAviMuxClose( &t->mux );
+ else if( title->mux == HB_MUX_MP4 )
+ HBMp4MuxClose( &t->mux );
+ else if( title->mux == HB_MUX_OGM )
+ HBOgmMuxClose( &t->mux );
+
+ /* Stats */
+ if( !stat( title->file, &sb ) )
+ {
+ uint64_t overhead;
+ HBAudio * audio;
+
+ overhead = (uint64_t) sb.st_size - t->videoBytes - t->audioBytes;
+ HBLog( "HBMuxThread: file size: "LLD" bytes",
+ (uint64_t) sb.st_size );
+ HBLog( "HBMuxThread: video data: "LLD" bytes ("LLD" frames)",
+ t->videoBytes, t->videoFrames );
+ HBLog( "HBMuxThread: audio data: "LLD" bytes ("LLD" frames)",
+ t->audioBytes, t->audioFrames );
+ HBLog( "HBMuxThread: overhead: "LLD" bytes (%.2f bytes per "
+ "frame)", overhead, (float) overhead / ( t->videoFrames +
+ t->audioFrames ) );
+
+ HBLog( "HBMuxThread: video bitrate: %.2f kbps",
+ (float) t->videoBytes * title->rate / t->videoFrames /
+ title->rateBase / 128 );
+ HBLog( "HBMuxThread: video error: "LLD" bytes", t->videoBytes -
+ t->videoFrames * title->bitrate * 128 * title->rateBase /
+ title->rate );
+
+ /* FIXME - handle multi-audio encoding */
+ audio = (HBAudio *) HBListItemAt( title->ripAudioList, 0 );
+ if( audio )
+ {
+ int samplesPerFrame = ( audio->outCodec == HB_CODEC_MP3 ?
+ 1152 : 1024 );
+ HBLog( "HBMuxThread: audio bitrate: %.2f kbps",
+ (float) t->audioBytes * audio->outSampleRate /
+ t->audioFrames / samplesPerFrame / 125 );
+ HBLog( "HBMuxThread: audio error: "LLD" bytes",
+ t->audioBytes - audio->outBitrate * t->audioFrames *
+ 125 * samplesPerFrame / audio->outSampleRate );
+ }
+ }
+
+ free( t );
+
+ *_t = NULL;
+}
+
+static int MuxWait( HBTitle * title )
+{
+ int i;
+ HBAudio * audio;
+
+ if( !HBFifoWait( title->outFifo ) )
+ {
+ return 0;
+ }
+ for( i = 0; i < HBListCount( title->ripAudioList ); i++ )
+ {
+ audio = HBListItemAt( title->ripAudioList, i );
+ if( !HBFifoWait( audio->outFifo ) )
+ {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static void MuxThread( void * _t )
+{
+ HBMuxThread * t = (HBMuxThread*) _t;
+ HBTitle * title = t->title;
+ HBMux * m = t->mux;
+ HBAudio * audio;
+ HBBuffer * buffer;
+ int i;
+
+ /* Remove the file if already existing */
+ unlink( title->file );
+
+ /* Wait until we have at least one video frame and 3 audio frames
+ for each track (Vorbis...) */
+ if( !HBFifoWait( title->outFifo ) )
+ {
+ return;
+ }
+ for( i = 0; i < HBListCount( title->ripAudioList ); i++ )
+ {
+ audio = HBListItemAt( title->ripAudioList, i );
+ while( !t->die && HBFifoSize( audio->outFifo ) < 3 )
+ {
+ HBSnooze( 10000 );
+ }
+ if( t->die )
+ {
+ return;
+ }
+ }
+
+ m->start( m );
+
+ /* Mux */
+ for( ;; )
+ {
+ /* Wait until we have one frame for each track */
+ if( !MuxWait( title ) )
+ {
+ break;
+ }
+
+ /* Interleave frames in the same order than they were in the
+ original MPEG stream */
+ audio = NULL;
+ for( i = 0; i < HBListCount( title->ripAudioList ); i++ )
+ {
+ HBAudio * otherAudio;
+ otherAudio = HBListItemAt( title->ripAudioList, i );
+ if( !audio || HBFifoPosition( otherAudio->outFifo ) <
+ HBFifoPosition( audio->outFifo ) )
+ {
+ audio = otherAudio;
+ }
+ }
+ if( !audio || HBFifoPosition( title->outFifo ) <
+ HBFifoPosition( audio->outFifo ) )
+ {
+ /* Video */
+ buffer = HBFifoPop( title->outFifo );
+ m->muxVideo( m, title->muxData, buffer );
+ t->videoBytes += buffer->size;
+ t->videoFrames++;
+ HBBufferClose( &buffer );
+ }
+ else
+ {
+ /* Audio */
+ buffer = HBFifoPop( audio->outFifo );
+ m->muxAudio( m, audio->muxData, buffer );
+ t->audioBytes += buffer->size;
+ t->audioFrames++;
+ HBBufferClose( &buffer );
+ }
+ }
+
+ m->end( m );
+}
+
diff --git a/core/Mux.h b/core/Mux.h
new file mode 100644
index 000000000..fbd1fd98f
--- /dev/null
+++ b/core/Mux.h
@@ -0,0 +1,21 @@
+/* $Id: Mux.h,v 1.2 2004/05/02 16:25:00 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. */
+
+#ifndef HB_MUX_H
+#define HB_MUX_H
+
+#define HB_MUX_COMMON_MEMBERS \
+ int (*start) ( HBMux * ); \
+ int (*muxVideo) ( HBMux *, void *, HBBuffer * ); \
+ int (*muxAudio) ( HBMux *, void *, HBBuffer * ); \
+ int (*end) ( HBMux * );
+
+typedef struct HBMux HBMux;
+
+HBMuxThread * HBMuxThreadInit( HBHandle *, HBTitle * );
+void HBMuxThreadClose( HBMuxThread ** );
+
+#endif
diff --git a/core/OgmMux.c b/core/OgmMux.c
index fef1ae01b..e99a494f5 100644
--- a/core/OgmMux.c
+++ b/core/OgmMux.c
@@ -1,4 +1,4 @@
-/* $Id: OgmMux.c,v 1.7 2004/03/08 11:32:48 titer Exp $
+/* $Id: OgmMux.c,v 1.13 2004/05/13 21:10:56 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://handbrake.m0k.org/>.
@@ -8,209 +8,26 @@
#include <ogg/ogg.h>
-static void OgmMuxThread( void * );
-static int OgmStart( HBOgmMux * );
-static int OgmFlush( HBOgmMux *, int );
-static int OgmEnd( HBOgmMux * );
+static int OgmStart( HBMux * );
+static int OgmMux( HBMux *, void *, HBBuffer * );
+static int OgmEnd( HBMux * );
-struct HBOgmMux
+struct HBMux
{
- HBHandle *handle;
- HBTitle *title;
+ HB_MUX_COMMON_MEMBERS
- volatile int die;
- HBThread *thread;
-
- FILE *file;
-
- int i_tk;
- struct
- {
- HBFifo *fifo;
-
- int codec;
-
- ogg_stream_state os;
- int i_packet_no;
-
- } tk[100]; /* The first who set more than 100 stream !! */
+ HBHandle * handle;
+ HBTitle * title;
+ FILE * file;
};
-HBOgmMux * HBOgmMuxInit( HBHandle * handle, HBTitle * title )
-{
- HBOgmMux *ogm = malloc( sizeof( HBOgmMux ) );
-
- ogm->handle = handle;
- ogm->title = title;
-
- ogm->file = NULL;
- ogm->i_tk = 0;
-
- ogm->die = 0;
- ogm->thread = HBThreadInit( "ogm muxer", OgmMuxThread, ogm, HB_NORMAL_PRIORITY );
- return ogm;
-}
-
-void HBOgmMuxClose( HBOgmMux ** _ogm )
-{
- HBOgmMux *ogm = *_ogm;
-
- ogm->die = 1;
- HBThreadClose( &ogm->thread );
-
- free( ogm );
-
- *_ogm = NULL;
-}
-
-static int OgmDataWait( HBOgmMux *ogm )
-{
- int i;
-
- for( i = 0; i < ogm->i_tk; i++ )
- {
- while( !ogm->die && HBFifoSize( ogm->tk[i].fifo ) <= 0 )
- {
- HBSnooze( 10000 );
- }
- }
- return ogm->die ? -1 : 0;
-}
-
-static void OgmMuxThread( void * _this )
+typedef struct
{
- HBOgmMux *ogm = _this;
-
- HBTitle *title = ogm->title;
-
- int i;
-
- /* Open output file */
- if( ( ogm->file = fopen( title->file, "w" ) ) == NULL )
- {
- HBLog( "HBOgmMux: failed to open `%s'", title->file );
- /* FIXME */
- HBErrorOccured( ogm->handle, HB_ERROR_AVI_WRITE );
- return;
- }
- HBLog( "HBOgmMux: `%s' opened", title->file );
-
-
- /* Wait for data in each fifo */
- HBLog( "HBOgmMux: waiting video/audio data" );
- if( OgmDataWait( ogm ) < 0 )
- {
- HBLog( "HBOgmMux: exiting" );
- fclose( ogm->file );
- unlink( title->file );
- return;
- }
-
- if( OgmStart( ogm ) < 0 )
- {
- HBLog( "HBOgmMux: failed to write headers" );
- fclose( ogm->file );
- unlink( title->file );
- return;
- }
+ int codec;
+ ogg_stream_state os;
+ int i_packet_no;
- HBLog( "HBOgmMux: headers written" );
-
- for( ;; )
- {
- HBBuffer *buffer;
- ogg_packet op;
- int i_tk;
-
- /* Wait data */
- if( OgmDataWait( ogm ) < 0 )
- {
- break;
- }
-
- /* Choose the right track to write (interleaved data) */
- for( i = 0, i_tk = -1; i < ogm->i_tk; i++ )
- {
- if( i_tk < 0 ||
- HBFifoPosition( ogm->tk[i].fifo ) < HBFifoPosition( ogm->tk[i_tk].fifo ) )
- {
- i_tk = i;
- }
- }
-
- buffer = HBFifoPop( ogm->tk[i_tk].fifo );
-
- switch( ( ogm->tk[i_tk].codec ) )
- {
- case HB_CODEC_FFMPEG:
- case HB_CODEC_XVID:
- case HB_CODEC_X264:
- op.bytes = buffer->size + 1;
- op.packet = malloc( op.bytes );
- op.packet[0] = buffer->keyFrame ? 0x08 : 0x00;
- memcpy( &op.packet[1], buffer->data, buffer->size );
- op.b_o_s = 0;
- op.e_o_s = 0;
- op.granulepos = ogm->tk[i_tk].i_packet_no;
- op.packetno = ogm->tk[i_tk].i_packet_no++;
- break;
- case HB_CODEC_MP3:
- op.bytes = buffer->size + 1;
- op.packet = malloc( op.bytes );
- op.packet[0] = 0x08;
- memcpy( &op.packet[1], buffer->data, buffer->size );
- op.b_o_s = 0;
- op.e_o_s = 0;
- op.granulepos = ogm->tk[i_tk].i_packet_no * 1152;
- op.packetno = ogm->tk[i_tk].i_packet_no++;
- break;
- case HB_CODEC_VORBIS:
- memcpy( &op, buffer->data, sizeof( ogg_packet ) );
-
- op.packet = malloc( op.bytes );
- memcpy( op.packet, buffer->data + sizeof( ogg_packet ), op.bytes );
- break;
-
- default:
- HBLog( "HBOgmMux: unhandled codec" );
- op.bytes = 0;
- op.packet = NULL;
- break;
- }
-
- if( op.packet )
- {
- ogg_stream_packetin( &ogm->tk[i_tk].os, &op );
-
- for( ;; )
- {
- ogg_page og;
- if( ogg_stream_pageout( &ogm->tk[i_tk].os, &og ) == 0 )
- {
- break;
- }
-
- if( fwrite( og.header, og.header_len, 1, ogm->file ) <= 0 ||
- fwrite( og.body, og.body_len, 1, ogm->file ) <= 0 )
- {
- HBLog( "HBOgmMux: write failed" );
- break;
- }
- }
- free( op.packet );
- }
-
- HBBufferClose( &buffer );
- }
-
- if( OgmEnd( ogm ) < 0 )
- {
- HBLog( "HBOgmMux: flush failed" );
- }
-
- fclose( ogm->file );
- HBLog( "HBOgmMux: `%s' closed", title->file );
-}
+} OgmMuxData;
typedef struct __attribute__((__packed__))
{
@@ -268,17 +85,66 @@ static void _SetQWLE( uint8_t *p, uint64_t i_qw )
SetDWLE( p+4, ( i_qw >> 32)&0xffffffff );
}
-static int OgmFlush( HBOgmMux *ogm, int i_tk )
+HBMux * HBOgmMuxInit( HBHandle * handle, HBTitle * title )
+{
+ HBMux * m;
+ HBAudio * audio;
+ int i;
+
+ if( !( m = calloc( sizeof( HBMux ), 1 ) ) )
+ {
+ HBLog( "HBOgmMux: malloc failed, gonna crash" );
+ return NULL;
+ }
+ m->start = OgmStart;
+ m->muxVideo = OgmMux;
+ m->muxAudio = OgmMux;
+ m->end = OgmEnd;
+
+ m->handle = handle;
+ m->title = title;
+
+ /* Alloc muxer data */
+ title->muxData = calloc( sizeof( OgmMuxData ), 1 );
+ for( i = 0; i < HBListCount( title->ripAudioList ); i++ )
+ {
+ audio = (HBAudio *) HBListItemAt( title->ripAudioList, i );
+ audio->muxData = calloc( sizeof( OgmMuxData ), 1 );
+ }
+
+ return m;
+}
+
+void HBOgmMuxClose( HBMux ** _m )
+{
+ HBMux * m = *_m;
+ HBTitle * title = m->title;
+ HBAudio * audio;
+ int i;
+
+ /* Free muxer data */
+ free( title->muxData );
+ for( i = 0; i < HBListCount( title->ripAudioList ); i++ )
+ {
+ audio = (HBAudio *) HBListItemAt( title->ripAudioList, i );
+ free( audio->muxData );
+ }
+
+ free( m );
+ *_m = NULL;
+}
+
+static int OgmFlush( HBMux * m, OgmMuxData * muxData )
{
for( ;; )
{
ogg_page og;
- if( ogg_stream_flush( &ogm->tk[i_tk].os, &og ) == 0 )
+ if( ogg_stream_flush( &muxData->os, &og ) == 0 )
{
break;
}
- if( fwrite( og.header, og.header_len, 1, ogm->file ) <= 0 ||
- fwrite( og.body, og.body_len, 1, ogm->file ) <= 0 )
+ if( fwrite( og.header, og.header_len, 1, m->file ) <= 0 ||
+ fwrite( og.body, og.body_len, 1, m->file ) <= 0 )
{
return -1;
}
@@ -286,92 +152,87 @@ static int OgmFlush( HBOgmMux *ogm, int i_tk )
return 0;
}
-static int OgmStart( HBOgmMux *ogm )
+static int OgmStart( HBMux * m )
{
- HBTitle *title = ogm->title;
- int i;
+ HBTitle * title = m->title;
+ HBAudio * audio;
+ OgmMuxData * muxData;
+ ogg_packet op;
+ ogg_stream_header_t h;
+ int i;
- ogg_packet op;
+ /* Open output file */
+ if( ( m->file = fopen( title->file, "wb" ) ) == NULL )
+ {
+ HBLog( "HBOgmMux: failed to open `%s'", title->file );
+ /* FIXME */
+ HBErrorOccured( m->handle, HB_ERROR_AVI_WRITE );
+ return -1;
+ }
+ HBLog( "HBOgmMux: `%s' opened", title->file );
- /* Init track */
- ogm->tk[0].codec = title->codec;
- ogm->tk[0].fifo = title->outFifo;
- ogm->tk[0].i_packet_no = 0;
- ogg_stream_init (&ogm->tk[0].os, 0 );
+ /* Init tracks */
- for( i = 1; i < HBListCount( title->ripAudioList ) + 1; i++ )
+ /* Video */
+ muxData = (OgmMuxData *) title->muxData;
+ muxData->codec = title->codec;
+ muxData->i_packet_no = 0;
+ ogg_stream_init( &muxData->os, 0 );
+
+ /* Audio */
+ for( i = 0; i < HBListCount( title->ripAudioList ); i++ )
{
- HBAudio *audio = HBListItemAt( title->ripAudioList, i - 1 );
+ HBAudio * audio = (HBAudio *) HBListItemAt( title->ripAudioList, i );
+ muxData = (OgmMuxData *) audio->muxData;
- ogm->tk[i].codec = audio->outCodec;
- ogm->tk[i].fifo = audio->outFifo;
- ogm->tk[i].i_packet_no = 0;
- ogg_stream_init (&ogm->tk[i].os, i );
+ muxData->codec = audio->outCodec;
+ muxData->i_packet_no = 0;
+ ogg_stream_init( &muxData->os, i + 1 );
}
- ogm->i_tk = 1 + HBListCount( title->ripAudioList );
- /* Wait data for each track */
- for( i = 0; i < ogm->i_tk; i++ )
+ /* First pass: all b_o_s packets */
+
+ /* Video */
+ muxData = (OgmMuxData *) title->muxData;
+ memset( &h, 0, sizeof( ogg_stream_header_t ) );
+ h.i_packet_type = 0x01;
+ memcpy( h.stream_type, "video ", 8 );
+ if( muxData->codec == HB_CODEC_X264 )
{
- while( !ogm->die &&
- ( ( ogm->tk[i].codec == HB_CODEC_VORBIS && HBFifoSize( ogm->tk[i].fifo ) <= 3 ) ||
- HBFifoSize( ogm->tk[i].fifo ) <= 0 ) )
- {
- HBSnooze( 10000 );
- }
+ memcpy( h.sub_type, "H264", 4 );
}
-
- if( ogm->die )
+ else
{
- return -1;
+ memcpy( h.sub_type, "XVID", 4 );
}
-
- /* First pass: all b_o_s packets */
- for( i = 0; i < ogm->i_tk; i++ )
+ SetDWLE( &h.i_size, sizeof( ogg_stream_header_t ) - 1);
+ SetQWLE( &h.i_time_unit, (int64_t)10*1000*1000*(int64_t)title->rateBase/(int64_t)title->rate );
+ SetQWLE( &h.i_samples_per_unit, 1 );
+ SetDWLE( &h.i_default_len, 0 );
+ SetDWLE( &h.i_buffer_size, 1024*1024 );
+ SetWLE ( &h.i_bits_per_sample, 0 );
+ SetDWLE( &h.header.video.i_width, title->outWidth );
+ SetDWLE( &h.header.video.i_height, title->outHeight );
+ op.packet = (char*)&h;
+ op.bytes = sizeof( ogg_stream_header_t );
+ op.b_o_s = 1;
+ op.e_o_s = 0;
+ op.granulepos = 0;
+ op.packetno = muxData->i_packet_no++;
+ ogg_stream_packetin( &muxData->os, &op );
+ OgmFlush( m, muxData );
+
+ /* Audio */
+ for( i = 0; i < HBListCount( title->ripAudioList ); i++ )
{
- ogg_stream_header_t h;
-
+ audio = (HBAudio *) HBListItemAt( title->ripAudioList, i );
+ muxData = (OgmMuxData *) audio->muxData;
memset( &h, 0, sizeof( ogg_stream_header_t ) );
-
- switch( ogm->tk[i].codec )
+ switch( muxData->codec )
{
- case HB_CODEC_FFMPEG:
- case HB_CODEC_XVID:
- case HB_CODEC_X264:
- h.i_packet_type = 0x01;
- memcpy( h.stream_type, "video ", 8 );
- if( ogm->tk[i].codec == HB_CODEC_X264 )
- {
- memcpy( h.sub_type, "H264", 4 );
- }
- else
- {
- memcpy( h.sub_type, "XVID", 4 );
- }
-
- SetDWLE( &h.i_size, sizeof( ogg_stream_header_t ) - 1);
- SetQWLE( &h.i_time_unit, (int64_t)10*1000*1000*(int64_t)title->rateBase/(int64_t)title->rate );
- SetQWLE( &h.i_samples_per_unit, 1 );
- SetDWLE( &h.i_default_len, 0 );
- SetDWLE( &h.i_buffer_size, 1024*1024 );
- SetWLE ( &h.i_bits_per_sample, 0 );
- SetDWLE( &h.header.video.i_width, title->outWidth );
- SetDWLE( &h.header.video.i_height, title->outHeight );
-
- op.packet = (char*)&h;
- op.bytes = sizeof( ogg_stream_header_t );
- op.b_o_s = 1;
- op.e_o_s = 0;
- op.granulepos = 0;
- op.packetno = ogm->tk[i].i_packet_no++;
- ogg_stream_packetin( &ogm->tk[i].os, &op );
- break;
-
case HB_CODEC_MP3:
{
- HBAudio *audio = HBListItemAt( title->ripAudioList, i - 1 );
-
h.i_packet_type = 0x01;
memcpy( h.stream_type, "audio ", 8 );
memcpy( h.sub_type, "55 ", 4 );
@@ -385,87 +246,151 @@ static int OgmStart( HBOgmMux *ogm )
SetDWLE( &h.header.audio.i_channels, 2 );
SetDWLE( &h.header.audio.i_block_align, 0 );
- SetDWLE( &h.header.audio.i_avgbytespersec, audio->outBitrate / 8 );
-
+ SetDWLE( &h.header.audio.i_avgbytespersec,
+ audio->outBitrate / 8 );
op.packet = (char*)&h;
op.bytes = sizeof( ogg_stream_header_t );
op.b_o_s = 1;
op.e_o_s = 0;
op.granulepos = 0;
- op.packetno = ogm->tk[i].i_packet_no++;
- ogg_stream_packetin( &ogm->tk[i].os, &op );
+ op.packetno = muxData->i_packet_no++;
+ ogg_stream_packetin( &muxData->os, &op );
break;
}
case HB_CODEC_VORBIS:
{
- HBBuffer *h = HBFifoPop( ogm->tk[i].fifo );
+ HBBuffer *h = HBFifoPop( audio->outFifo );
memcpy( &op, h->data, sizeof( ogg_packet ) );
op.packet = h->data + sizeof( ogg_packet );
- ogg_stream_packetin( &ogm->tk[i].os, &op );
+ ogg_stream_packetin( &muxData->os, &op );
break;
}
- case HB_CODEC_AAC:
- break;
default:
- HBLog( "unhandled codec" );
+ HBLog( "HBOgmMux: unhandled codec" );
break;
}
- OgmFlush( ogm, i );
+ OgmFlush( m, muxData );
}
/* second pass: all non b_o_s packets */
- for( i = 0; i < ogm->i_tk; i++ )
+ for( i = 0; i < HBListCount( title->ripAudioList ); i++ )
{
- if( ogm->tk[i].codec == HB_CODEC_VORBIS )
+ audio = (HBAudio *) HBListItemAt( title->ripAudioList, i );
+ if( audio->outCodec == HB_CODEC_VORBIS )
{
HBBuffer *h;
int j;
+ muxData = (OgmMuxData *) audio->muxData;
for( j = 0; j < 2; j++ )
{
- HBFifoWait( ogm->tk[i].fifo );
- h = HBFifoPop( ogm->tk[i].fifo );
+ h = HBFifoPop( audio->outFifo );
memcpy( &op, h->data, sizeof( ogg_packet ) );
op.packet = h->data + sizeof( ogg_packet );
- ogg_stream_packetin( &ogm->tk[i].os, &op );
+ ogg_stream_packetin( &muxData->os, &op );
- OgmFlush( ogm, i );
+ OgmFlush( m, muxData );
}
}
-#if 0
- else
+ }
+
+ HBLog( "HBOgmMux: headers written" );
+ return 0;
+}
+
+static int OgmMux( HBMux * m, void * _muxData, HBBuffer * buffer )
+{
+ OgmMuxData * muxData = (OgmMuxData *) _muxData;
+ ogg_packet op;
+
+ switch( muxData->codec )
+ {
+ case HB_CODEC_FFMPEG:
+ case HB_CODEC_XVID:
+ case HB_CODEC_X264:
+ op.bytes = buffer->size + 1;
+ op.packet = malloc( op.bytes );
+ op.packet[0] = buffer->keyFrame ? 0x08 : 0x00;
+ memcpy( &op.packet[1], buffer->data, buffer->size );
+ op.b_o_s = 0;
+ op.e_o_s = 0;
+ op.granulepos = muxData->i_packet_no;
+ op.packetno = muxData->i_packet_no++;
+ break;
+ case HB_CODEC_MP3:
+ op.bytes = buffer->size + 1;
+ op.packet = malloc( op.bytes );
+ op.packet[0] = 0x08;
+ memcpy( &op.packet[1], buffer->data, buffer->size );
+ op.b_o_s = 0;
+ op.e_o_s = 0;
+ op.granulepos = muxData->i_packet_no * 1152;
+ op.packetno = muxData->i_packet_no++;
+ break;
+ case HB_CODEC_VORBIS:
+ memcpy( &op, buffer->data, sizeof( ogg_packet ) );
+ op.packet = malloc( op.bytes );
+ memcpy( op.packet, buffer->data + sizeof( ogg_packet ), op.bytes );
+ break;
+
+ default:
+ HBLog( "HBOgmMux: unhandled codec" );
+ op.bytes = 0;
+ op.packet = NULL;
+ break;
+ }
+
+ if( op.packet )
+ {
+ ogg_stream_packetin( &muxData->os, &op );
+
+ for( ;; )
{
- /* Home made commentary */
- op.packet = "\003Handbrake";
- op.bytes = strlen( "\003Handbrake" );;
- op.b_o_s = 0;
- op.e_o_s = 0;
- op.granulepos = 0;
- op.packetno = ogm->tk[i].i_packet_no++;
-
- ogg_stream_packetin( &ogm->tk[i].os, &op );
- OgmFlush( ogm, i );
+ ogg_page og;
+ if( ogg_stream_pageout( &muxData->os, &og ) == 0 )
+ {
+ break;
+ }
+
+ if( fwrite( og.header, og.header_len, 1, m->file ) <= 0 ||
+ fwrite( og.body, og.body_len, 1, m->file ) <= 0 )
+ {
+ HBLog( "HBOgmMux: write failed" );
+ break;
+ }
}
-#endif
+ free( op.packet );
}
-
return 0;
}
-static int OgmEnd( HBOgmMux *ogm )
+static int OgmEnd( HBMux * m )
{
- int i;
+ HBTitle * title = m->title;
+ HBAudio * audio;
+ OgmMuxData * muxData;
+ int i;
- for( i = 0; i < ogm->i_tk; i++ )
+ muxData = (OgmMuxData *) title->muxData;
+ if( OgmFlush( m, muxData ) < 0 )
{
- if( OgmFlush( ogm, i ) < 0 )
+ return -1;
+ }
+ for( i = 0; i < HBListCount( title->ripAudioList ); i++ )
+ {
+ audio = (HBAudio *) HBListItemAt( title->ripAudioList, i );
+ muxData = (OgmMuxData *) audio->muxData;
+ if( OgmFlush( m, muxData ) < 0 )
{
return -1;
}
}
+
+ fclose( m->file );
+ HBLog( "HBOgmMux: `%s' closed", title->file );
return 0;
}
diff --git a/core/Resample.c b/core/Resample.c
new file mode 100644
index 000000000..f3632b371
--- /dev/null
+++ b/core/Resample.c
@@ -0,0 +1,159 @@
+/* $Id: Resample.c,v 1.4 2004/05/02 16:25:00 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 "HBInternal.h"
+
+#include "samplerate.h"
+
+struct HBWork
+{
+ HB_WORK_COMMON_MEMBERS
+
+ HBHandle * handle;
+ HBAudio * audio;
+
+ float * samples;
+ SRC_STATE * state;
+ SRC_DATA data;
+
+ uint64_t in;
+ uint64_t out;
+};
+
+/* Local prototypes */
+static int ResampleWork( HBWork * );
+
+HBWork * HBResampleInit( HBHandle * handle, HBAudio * audio )
+{
+ HBWork * w;
+ if( !( w = calloc( sizeof( HBWork ), 1 ) ) )
+ {
+ HBLog( "HBResampleInit: malloc() failed, gonna crash" );
+ return NULL;
+ }
+
+ w->name = strdup( "Resample" );
+ w->work = ResampleWork;
+
+ w->handle = handle;
+ w->audio = audio;
+
+ return w;
+}
+
+void HBResampleClose( HBWork ** _w )
+{
+ HBWork * w = *_w;
+
+ if( w->samples ) free( w->samples );
+ if( w->state ) src_delete( w->state );
+
+ free( w->name );
+ free( w );
+ *_w = NULL;
+}
+
+static int ResampleWork( HBWork * w )
+{
+ HBAudio * audio = w->audio;
+
+ HBBuffer * resampleBuffer;
+ float position;
+
+ if( HBFifoIsHalfFull( audio->resampleFifo ) )
+ {
+ return 0;
+ }
+
+ /* Initialization */
+ if( !w->samples )
+ {
+ int error;
+
+ /* Until a first packet comes, audio->inSampleRate is
+ undefined */
+ if( !HBFifoSize( audio->rawFifo ) )
+ {
+ return 0;
+ }
+
+ /* No, the user can't choose. 44100 Hz, take it or leave it */
+ audio->outSampleRate = 44100;
+ HBLog( "HBResample: in = %d Hz, out = %d Hz",
+ audio->inSampleRate, audio->outSampleRate );
+
+ /* Buffer in which we'll pop the samples from the decoder */
+ w->samples = malloc( audio->inSampleRate * 2 *
+ sizeof( float ) / 10 );
+
+ /* Init libsamplerate */
+ w->state = src_new( SRC_SINC_FASTEST, 2, &error );
+
+ /* Prepare the SRC_DATA structure */
+ w->data.data_in = w->samples;
+ w->data.input_frames = audio->inSampleRate / 10;
+ w->data.output_frames = audio->outSampleRate / 10;
+ w->data.src_ratio = (double) audio->outSampleRate /
+ (double) audio->inSampleRate;
+ w->data.end_of_input = 0;
+ }
+
+ /* Fix A/V synchro in case the audio track starts later than the
+ video */
+ if( audio->delay > 0 )
+ {
+ HBLog( "HBResample: adding %d ms of silence", audio->delay );
+
+ resampleBuffer = HBBufferInit( audio->delay *
+ audio->outSampleRate * 2 * sizeof( float ) / 1000 );
+ memset( resampleBuffer->data, 0, resampleBuffer->size );
+ if( !HBFifoPush( audio->resampleFifo, &resampleBuffer ) )
+ {
+ HBLog( "HBResample: HBFifoPush failed" );
+ }
+
+ audio->delay = 0;
+ return 1;
+ }
+
+ /* Get samples from the decoder */
+ if( !HBFifoGetBytes( audio->rawFifo, (uint8_t *) w->samples,
+ audio->inSampleRate * 2 * sizeof( float ) / 10,
+ &position ) )
+ {
+ return 0;
+ }
+
+ /* Init resampled buffer */
+ resampleBuffer = HBBufferInit( audio->outSampleRate * 2 *
+ sizeof( float ) / 10 );
+ resampleBuffer->position = position;
+
+ /* Resample */
+ w->data.data_out = resampleBuffer->dataf;
+ if( src_process( w->state, &w->data ) )
+ {
+ HBLog( "HBResample: src_process failed" );
+ }
+ resampleBuffer->size = w->data.output_frames_gen * 2 *
+ sizeof( float );
+
+ if( w->data.input_frames_used != w->data.input_frames )
+ {
+ /* Here we're basically f*cked */
+ HBLog( "HBResample: ohoh, %d/%d used",
+ w->data.input_frames_used, w->data.input_frames );
+ }
+
+ /* Send resampled data to the encoder */
+ if( !HBFifoPush( audio->resampleFifo, &resampleBuffer ) )
+ {
+ HBLog( "HBResample: HBFifoPush failed" );
+ }
+
+ return 1;
+}
+
diff --git a/core/Scale.c b/core/Scale.c
index 527882539..2908d6456 100644
--- a/core/Scale.c
+++ b/core/Scale.c
@@ -1,4 +1,4 @@
-/* $Id: Scale.c,v 1.10 2004/03/08 11:32:48 titer Exp $
+/* $Id: Scale.c,v 1.14 2004/05/02 16:25:00 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://handbrake.m0k.org/>.
@@ -6,13 +6,9 @@
#include "HBInternal.h"
-#define USE_FFMPEG
-
-#ifdef USE_FFMPEG
#include "ffmpeg/avcodec.h"
-#endif
-typedef struct HBScale
+struct HBWork
{
HB_WORK_COMMON_MEMBERS
@@ -20,114 +16,74 @@ typedef struct HBScale
HBTitle * title;
HBBuffer * deintBuffer;
- HBList * scaledBufferList;
-#ifdef USE_FFMPEG
ImgReSampleContext * context;
AVPicture rawPicture;
AVPicture deintPicture;
AVPicture scaledPicture;
-#endif
-} HBScale;
+};
/* Local prototypes */
static int ScaleWork( HBWork * );
-#ifndef USE_FFMPEG
-static void Deinterlace( uint8_t * in, uint8_t * out, int w, int h,
- int tcrop, int bcrop, int lcrop, int rcrop );
-static void Resample( uint8_t * in, uint8_t * out, int oldw, int oldh,
- int neww, int newh, int tcrop, int bcrop,
- int lcrop, int rcrop );
-#endif
HBWork * HBScaleInit( HBHandle * handle, HBTitle * title )
{
- HBScale * s;
- if( !( s = malloc( sizeof( HBScale ) ) ) )
+ HBWork * w;
+ if( !( w = malloc( sizeof( HBWork ) ) ) )
{
HBLog( "HBScaleInit: malloc() failed, gonna crash" );
return NULL;
}
- s->name = strdup( "Scale" );
- s->work = ScaleWork;
+ w->name = strdup( "Scale" );
+ w->work = ScaleWork;
- s->handle = handle;
- s->title = title;
+ w->handle = handle;
+ w->title = title;
/* Allocate a constant buffer used for deinterlacing */
- s->deintBuffer = HBBufferInit( 3 * title->inWidth *
- title->inHeight / 2 );
+ w->deintBuffer = HBBufferInit( 3 * title->inWidth *
+ title->inHeight / 2 );
-#ifdef USE_FFMPEG
- avpicture_fill( &s->deintPicture, s->deintBuffer->data,
+ avpicture_fill( &w->deintPicture, w->deintBuffer->data,
PIX_FMT_YUV420P, title->inWidth, title->inHeight );
/* Init libavcodec */
- s->context =
+ w->context =
img_resample_full_init( title->outWidth, title->outHeight,
title->inWidth, title->inHeight,
title->topCrop, title->bottomCrop,
title->leftCrop, title->rightCrop );
-#endif
-
- s->scaledBufferList = HBListInit();
- return (HBWork*) s;
+ return w;
}
-void HBScaleClose( HBWork ** _s )
+void HBScaleClose( HBWork ** _w )
{
- HBScale * s = (HBScale*) *_s;
-
-#ifdef USE_FFMPEG
- img_resample_close( s->context );
-#endif
- HBListClose( &s->scaledBufferList );
- HBBufferClose( &s->deintBuffer );
- free( s->name );
- free( s );
+ HBWork * w = *_w;
- *_s = NULL;
+ img_resample_close( w->context );
+ HBBufferClose( &w->deintBuffer );
+ free( w->name );
+ free( w );
+ *_w = NULL;
}
static int ScaleWork( HBWork * w )
{
- HBScale * s = (HBScale*) w;
- HBTitle * title = s->title;
+ HBTitle * title = w->title;
HBBuffer * rawBuffer;
HBBuffer * scaledBuffer;
HBBuffer * tmpBuffer;
-#ifndef USE_FFMPEG
- uint8_t * in, * out;
- int plane, shift;
-#endif
- int didSomething = 0;
-
- /* Push scaled buffer(s) */
- while( ( scaledBuffer = (HBBuffer*)
- HBListItemAt( s->scaledBufferList, 0 ) ) )
+ if( HBFifoIsHalfFull( title->scaledFifo ) )
{
- tmpBuffer = scaledBuffer;
- if( HBFifoPush( title->scaledFifo, &scaledBuffer ) )
- {
- didSomething = 1;
- HBListRemove( s->scaledBufferList, tmpBuffer );
- }
- else
- {
- return didSomething;
- }
+ return 0;
}
/* Get a new raw picture */
- if( ( rawBuffer = HBFifoPop( title->rawFifo ) ) )
- {
- didSomething = 1;
- }
- else
+ if( !( rawBuffer = HBFifoPop( title->rawFifo ) ) )
{
- return didSomething;
+ return 0;
}
/* Allocate new buffer for the scaled picture */
@@ -136,62 +92,26 @@ static int ScaleWork( HBWork * w )
scaledBuffer->position = rawBuffer->position;
scaledBuffer->pass = rawBuffer->pass;
-#ifdef USE_FFMPEG
/* libavcodec stuff */
- avpicture_fill( &s->rawPicture, rawBuffer->data, PIX_FMT_YUV420P,
+ avpicture_fill( &w->rawPicture, rawBuffer->data, PIX_FMT_YUV420P,
title->inWidth, title->inHeight );
- avpicture_fill( &s->scaledPicture, scaledBuffer->data,
+ avpicture_fill( &w->scaledPicture, scaledBuffer->data,
PIX_FMT_YUV420P, title->outWidth,
title->outHeight );
/* Do the job */
if( title->deinterlace )
{
- avpicture_deinterlace( &s->deintPicture, &s->rawPicture,
+ avpicture_deinterlace( &w->deintPicture, &w->rawPicture,
PIX_FMT_YUV420P, title->inWidth,
title->inHeight );
- img_resample( s->context, &s->scaledPicture,
- &s->deintPicture );
+ img_resample( w->context, &w->scaledPicture,
+ &w->deintPicture );
}
else
{
- img_resample( s->context, &s->scaledPicture, &s->rawPicture );
- }
-#else
- if( title->deinterlace )
- {
- in = rawBuffer->data;
- out = s->deintBuffer->data;
- for( plane = 0; plane < 3; plane++ )
- {
- shift = plane ? 1 : 0;
- Deinterlace( in, out, title->inWidth >> shift,
- title->inHeight >> shift,
- title->topCrop >> shift,
- title->bottomCrop >> shift,
- title->leftCrop >> shift,
- title->rightCrop >> shift );
- in += title->inWidth * title->inHeight >> ( 2 * shift );
- out += title->inWidth * title->inHeight >> ( 2 * shift );
- }
- }
-
- in = title->deinterlace ? s->deintBuffer->data : rawBuffer->data;
- out = scaledBuffer->data;
- for( plane = 0; plane < 3; plane++ )
- {
- shift = plane ? 1 : 0;
- Resample( in, out, title->inWidth >> shift,
- title->inHeight >> shift, title->outWidth >> shift,
- title->outHeight >> shift, title->topCrop >> shift,
- title->bottomCrop >> shift, title->leftCrop >> shift,
- title->rightCrop >> shift );
- in += title->inWidth * title->inHeight >> ( 2 * shift );
- out += title->outWidth * title->outHeight >> ( 2 * shift );;
+ img_resample( w->context, &w->scaledPicture, &w->rawPicture );
}
-#endif
-
- HBListAdd( s->scaledBufferList, scaledBuffer );
if( rawBuffer->repeat )
{
@@ -201,52 +121,20 @@ static int ScaleWork( HBWork * w )
memcpy( tmpBuffer->data, scaledBuffer->data,
scaledBuffer->size );
- HBListAdd( s->scaledBufferList, tmpBuffer );
- }
-
- /* Free memory */
- HBBufferClose( &rawBuffer );
-
- return didSomething;
-}
-
-#ifndef USE_FFMPEG
-static void Deinterlace( uint8_t * in, uint8_t * out, int w, int h,
- int tcrop, int bcrop, int lcrop, int rcrop )
-{
- int i, j;
-
- /* First line */
- if( !tcrop )
- {
- memcpy( out, in + lcrop, w - lcrop - rcrop );
- }
-
- /* Merge lines */
- for( i = MAX( 1, tcrop ); i < h - bcrop; i++ )
- {
- for( j = lcrop; j < w - rcrop; j++ )
+ if( !HBFifoPush( title->scaledFifo, &tmpBuffer ) )
{
- out[i*w+j] = ( in[(i-1)*w+j] + in[i*w+j] ) / 2;
+ HBLog( "HBScale: HBFifoPush failed" );
}
}
-}
-static void Resample( uint8_t * in, uint8_t * out, int oldw, int oldh,
- int neww, int newh, int tcrop, int bcrop,
- int lcrop, int rcrop )
-{
- int i, j;
- int cropw = oldw - lcrop - rcrop;
- int croph = oldh - tcrop - bcrop;
- for( i = 0; i < newh; i++ )
+ if( !HBFifoPush( title->scaledFifo, &scaledBuffer ) )
{
- for( j = 0; j < neww; j++ )
- {
- out[i*neww+j] = in[(tcrop+i*croph/newh)*oldw +
- lcrop+j*cropw/neww];
- }
+ HBLog( "HBScale: HBFifoPush failed" );
}
+
+ /* Free memory */
+ HBBufferClose( &rawBuffer );
+
+ return 1;
}
-#endif
diff --git a/core/Scan.c b/core/Scan.c
index 8f19a138d..9315e59d0 100644
--- a/core/Scan.c
+++ b/core/Scan.c
@@ -1,4 +1,4 @@
-/* $Id: Scan.c,v 1.15 2004/03/08 11:32:48 titer Exp $
+/* $Id: Scan.c,v 1.26 2004/05/12 18:02:35 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://handbrake.m0k.org/>.
@@ -7,18 +7,15 @@
#include "HBInternal.h"
#include "Languages.h"
-#include "dvdread/ifo_types.h"
-#include "dvdplay/dvdplay.h"
-#include "dvdplay/info.h"
-#include "dvdplay/state.h"
-#include "dvdplay/nav.h"
+#include "dvdread/ifo_read.h"
#include "mpeg2dec/mpeg2.h"
/* Local prototypes */
static void ScanThread( void * );
-static HBTitle * ScanTitle( HBScan *, dvdplay_ptr vmg, int index );
-static int DecodeFrame( HBScan * s, dvdplay_ptr vmg,
+static HBTitle * ScanTitle( HBScan *, dvd_reader_t * reader,
+ ifo_handle_t * vmg, int index );
+static int DecodeFrame( HBScan * s, dvd_file_t * dvdFile,
HBTitle * title, int which );
static char * LanguageForCode( int code );
@@ -29,6 +26,7 @@ struct HBScan
int title;
volatile int die;
HBThread * thread;
+ HBList * titleList;
};
HBScan * HBScanInit( HBHandle * handle, const char * device, int title )
@@ -64,40 +62,47 @@ void HBScanClose( HBScan ** _s )
static void ScanThread( void * _s )
{
- HBScan * s = (HBScan*) _s;
- dvdplay_ptr vmg;
- HBList * titleList = HBListInit();
- HBTitle * title;
- int i;
+ int i;
+ HBScan * s = (HBScan*) _s;
+ HBList * titleList = HBListInit();
+ HBTitle * title;
+ dvd_reader_t * reader;
+ ifo_handle_t * vmg;
+
+ s->titleList = titleList;
HBLog( "HBScan: opening device %s", s->device );
- vmg = dvdplay_open( s->device, NULL, NULL );
- if( !vmg )
+ reader = DVDOpen( s->device );
+ if( !reader )
{
- HBLog( "HBScan: dvdplay_open() failed (%s)", s->device );
+ HBLog( "HBScan: DVDOpen() failed (%s)", s->device );
HBListClose( &titleList );
HBScanDone( s->handle, NULL );
return;
}
+ vmg = ifoOpen( reader, 0 );
+
/* Detect titles */
i = s->title ? ( s->title - 1 ) : 0;
while( !s->die )
{
- if( ( title = ScanTitle( s, vmg, i + 1 ) ) )
+ if( ( title = ScanTitle( s, reader, vmg, i + 1 ) ) )
{
HBListAdd( titleList, title );
}
- if( s->title || i == dvdplay_title_nr( vmg ) - 1 )
+ if( s->title || i == vmg->tt_srpt->nr_of_srpts - 1 )
{
break;
}
i++;
}
+ ifoClose( vmg );
+
HBLog( "HBScan: closing device %s", s->device );
- dvdplay_close( vmg );
+ DVDClose( reader );
if( s->die )
{
@@ -117,27 +122,102 @@ static void ScanThread( void * _s )
HBScanDone( s->handle, titleList );
}
-static HBTitle * ScanTitle( HBScan * s, dvdplay_ptr vmg, int index )
+
+static unsigned int convert_bcd( unsigned int i_x )
+{
+ int y = 0, z = 1;
+
+ for( ; i_x ; )
+ {
+ y += z * ( i_x & 0xf );
+ i_x = i_x >> 4;
+ z = z * 10;
+ }
+
+ return y;
+}
+
+static HBTitle * ScanTitle( HBScan * s, dvd_reader_t * reader,
+ ifo_handle_t * vmg, int index )
{
HBTitle * title;
- int audio_nr, foo;
- audio_attr_t * attr;
+ HBTitle * title2;
HBAudio * audio;
- int i;
- uint8_t dummy[DVD_VIDEO_LB_LEN];
+ int i, audio_nr;
+ int ttn;
+ ifo_handle_t * vts;
+ int pgc_id, pgn, cell;
+ pgc_t * pgc;
+ dvd_file_t * dvdFile;
- HBScanning( s->handle, index, dvdplay_title_nr( vmg ) );
+ HBScanning( s->handle, index, vmg->tt_srpt->nr_of_srpts );
title = HBTitleInit( s->device, index );
- dvdplay_start( vmg, index );
- /* Length */
- title->length = dvdplay_title_time( vmg );
- HBLog( "HBScan: title %d: length is %d seconds", index,
- title->length );
+ /* VTS in which our title is */
+ title->vts_id = vmg->tt_srpt->title[index-1].title_set_nr;
+
+ vts = ifoOpen( reader, title->vts_id );
+ if( !vts )
+ {
+ HBLog( "HBScan: ifoOpen failed (vts %d)", title->vts_id );
+ HBTitleClose( &title );
+ return NULL;
+ }
+
+ /* Position of the title in the VTS */
+ ttn = vmg->tt_srpt->title[index-1].vts_ttn;
+
+ /* Get pgc */
+ pgc_id = vts->vts_ptt_srpt->title[ttn-1].ptt[0].pgcn;
+ pgn = vts->vts_ptt_srpt->title[ttn-1].ptt[0].pgn;
+ pgc = vts->vts_pgcit->pgci_srp[pgc_id-1].pgc;
+
+ /* Start block */
+ cell = pgc->program_map[pgn-1] - 1;
+ title->startBlock = pgc->cell_playback[cell].first_sector;
+
+ /* End block */
+ cell = pgc->nr_of_cells - 1;
+ title->endBlock = pgc->cell_playback[cell].last_sector;
+
+ HBLog( "HBScan: vts=%d, ttn=%d, blocks %d to %d", title->vts_id,
+ ttn, title->startBlock, title->endBlock );
+
+ /* I've seen a DVD with strictly identical titles. Check this here,
+ and ignore it if redundant */
+ title2 = NULL;
+ for( i = 0; i < HBListCount( s->titleList ); i++ )
+ {
+ title2 = (HBTitle*) HBListItemAt( s->titleList, i );
+ if( title->vts_id == title2->vts_id &&
+ title->startBlock == title2->startBlock &&
+ title->endBlock == title2->endBlock )
+ {
+ break;
+ }
+ else
+ {
+ title2 = NULL;
+ }
+ }
+ if( title2 )
+ {
+ HBLog( "HBScan: title %d is duplicate with title %d",
+ index, title2->title );
+ HBTitleClose( &title );
+ return NULL;
+ }
+
+ /* Get time */
+ title->hours = convert_bcd( pgc->playback_time.hour );
+ title->minutes = convert_bcd( pgc->playback_time.minute );
+ title->seconds = convert_bcd( pgc->playback_time.second );
+ HBLog( "HBScan: title %d: length is %02d:%02d:%02d", index,
+ title->hours, title->minutes, title->seconds );
/* Discard titles under 10 seconds */
- if( title->length < 10 )
+ if( !title->hours && !title->minutes && title->seconds < 10 )
{
HBLog( "HBScan: ignoring title %d (too short)", index );
HBTitleClose( &title );
@@ -145,36 +225,57 @@ static HBTitle * ScanTitle( HBScan * s, dvdplay_ptr vmg, int index )
}
/* Detect languages */
- dvdplay_audio_info( vmg, &audio_nr, &foo );
+ audio_nr = vts->vtsi_mat->nr_of_vts_audio_streams;
for( i = 0; i < audio_nr; i++ )
{
- int id, j, codec;
+ uint32_t id = 0;
+ int j, codec;
+ int audio_format = vts->vtsi_mat->vts_audio_attr[i].audio_format;
+ int lang_code = vts->vtsi_mat->vts_audio_attr[i].lang_code;
+ int audio_control = vts->vts_pgcit->pgci_srp[pgc_id-1].pgc->audio_control[i];
+ int i_position;
if( s->die )
{
break;
}
- id = dvdplay_audio_id( vmg, i );
-
- if( id < 1 )
+ if( !( audio_control & 0x8000 ) )
{
continue;
}
- if( ( id & 0xF0FF ) == 0x80BD )
- {
- codec = HB_CODEC_AC3;
- }
- else if( ( id & 0xF0FF ) == 0xA0BD )
+ i_position = ( audio_control & 0x7F00 ) >> 8;
+
+ switch( audio_format )
{
- codec = HB_CODEC_LPCM;
+ case 0x00: /* A52 */
+ codec = HB_CODEC_AC3;
+ id = ( ( 0x80 + i_position ) << 8 ) | 0xbd;
+ break;
+
+ case 0x02:
+ case 0x03:
+ codec = HB_CODEC_MPGA;
+ id = 0xc0 + i_position;
+ break;
+
+ case 0x04: /* LPCM */
+ codec = HB_CODEC_LPCM;
+ id = ( ( 0xa0 + i_position ) << 8 ) | 0xbd;
+ break;
+
+ default:
+ codec = 0;
+ id = 0;
+ HBLog( "HBScan: title %d: unknown audio codec (%x), "
+ "ignoring", index, audio_format );
+ break;
}
- else
+
+ if( !id )
{
- HBLog( "HBScan: title %d: unknown audio codec (%x), "
- "ignoring", index, id );
continue;
}
@@ -200,8 +301,7 @@ static HBTitle * ScanTitle( HBScan * s, dvdplay_ptr vmg, int index )
continue;
}
- attr = dvdplay_audio_attr( vmg, j );
- audio = HBAudioInit( id, LanguageForCode( attr->lang_code ) );
+ audio = HBAudioInit( id, LanguageForCode( lang_code ), codec );
audio->inCodec = codec;
HBLog( "HBScan: title %d: new language (%x, %s)", index, id,
audio->language );
@@ -216,8 +316,15 @@ static HBTitle * ScanTitle( HBScan * s, dvdplay_ptr vmg, int index )
return NULL;
}
- /* Kludge : libdvdplay wants us to read a first block before seeking */
- dvdplay_read( vmg, dummy, 1 );
+ ifoClose( vts );
+
+ dvdFile = DVDOpenFile( reader, title->vts_id, DVD_READ_TITLE_VOBS );
+ if( !dvdFile )
+ {
+ HBLog( "HBScan: DVDOpenFile failed" );
+ HBTitleClose( &title );
+ return NULL;
+ }
for( i = 0; i < 10; i++ )
{
@@ -226,7 +333,7 @@ static HBTitle * ScanTitle( HBScan * s, dvdplay_ptr vmg, int index )
break;
}
- if( !DecodeFrame( s, vmg, title, i ) )
+ if( !DecodeFrame( s, dvdFile, title, i ) )
{
HBLog( "HBScan: ignoring title %d (could not decode)",
index );
@@ -235,6 +342,8 @@ static HBTitle * ScanTitle( HBScan * s, dvdplay_ptr vmg, int index )
}
}
+ DVDCloseFile( dvdFile );
+
/* Handle ratio */
if( title->inHeight * title->aspect >
title->inWidth * VOUT_ASPECT_FACTOR )
@@ -257,41 +366,88 @@ static HBTitle * ScanTitle( HBScan * s, dvdplay_ptr vmg, int index )
return title;
}
-static int DecodeFrame( HBScan * s, dvdplay_ptr vmg,
+static HBBuffer * GetBuffer( HBList * esBufferList,
+ dvd_file_t * dvdFile,
+ int * pictureStart, int pictureEnd )
+{
+ HBBuffer * esBuffer = NULL;
+ HBBuffer * psBuffer = NULL;
+
+ while( !esBuffer )
+ {
+ while( !HBListCount( esBufferList ) )
+ {
+ psBuffer = HBBufferInit( DVD_VIDEO_LB_LEN );
+ if( DVDReadBlocks( dvdFile, (*pictureStart)++, 1,
+ psBuffer->data ) != 1 )
+ {
+ HBLog( "HBScan: DVDReadBlocks() failed" );
+ HBBufferClose( &psBuffer );
+ return NULL;
+ }
+ if( !HBPStoES( &psBuffer, esBufferList ) )
+ {
+ HBLog( "HBScan: HBPStoES() failed" );
+ return NULL;
+ }
+ if( *pictureStart >= pictureEnd )
+ {
+ HBLog( "HBScan: gone too far, aborting" );
+ return NULL;
+ }
+ }
+
+ esBuffer = (HBBuffer*) HBListItemAt( esBufferList, 0 );
+ HBListRemove( esBufferList, esBuffer );
+
+ if( esBuffer->streamId != 0xE0 )
+ {
+ HBBufferClose( &esBuffer );
+ }
+ }
+
+ return esBuffer;
+}
+
+static int DecodeFrame( HBScan * s, dvd_file_t * dvdFile,
HBTitle * title, int which )
{
- int titleFirst = dvdplay_title_first( vmg );
- int titleEnd = dvdplay_title_end( vmg );
- int pictureStart = ( which + 1 ) * ( titleEnd - titleFirst ) / 11;
- int pictureEnd = titleFirst + ( which + 2 ) *
- ( titleEnd - titleFirst ) / 11;
+ int pictureStart = title->startBlock + ( which + 1 ) *
+ ( title->endBlock - title->startBlock ) / 11;
+ int pictureEnd = title->startBlock + ( which + 2 ) *
+ ( title->endBlock - title->startBlock ) / 11;
mpeg2dec_t * handle;
const mpeg2_info_t * info;
mpeg2_state_t state;
char fileName[1024];
FILE * file;
- int ret = 1;
+ int ret = 0;
HBList * esBufferList = HBListInit();
- HBBuffer * psBuffer = NULL;
HBBuffer * esBuffer = NULL;
- /* Seek to the right place */
- dvdplay_seek( vmg, pictureStart );
/* Init libmpeg2 */
-#ifdef HB_NOMMX
- mpeg2_accel( 0 );
-#endif
handle = mpeg2_init();
info = mpeg2_info( handle );
/* Init the destination file */
memset( fileName, 0, 1024 );
+#ifndef HB_CYGWIN
sprintf( fileName, "/tmp/HB.%d.%d.%d", HBGetPid( s->handle ),
- title->index, which );
- file = fopen( fileName, "w" );
+ title->title, which );
+#else
+ sprintf( fileName, "C:\\HB.%d.%d.%d", HBGetPid( s->handle ),
+ title->title, which );
+#endif
+ file = fopen( fileName, "wb" );
+ if( !file )
+ {
+ HBLog( "HBScan: fopen failed" );
+ HBListClose( &esBufferList );
+ return 0;
+ }
for( ;; )
{
@@ -306,43 +462,10 @@ static int DecodeFrame( HBScan * s, dvdplay_ptr vmg,
}
/* Get a new one */
- while( !esBuffer )
- {
- while( !HBListCount( esBufferList ) )
- {
- psBuffer = HBBufferInit( DVD_VIDEO_LB_LEN );
- if( dvdplay_read( vmg, psBuffer->data, 1 ) != 1 ||
- !HBPStoES( &psBuffer, esBufferList ) )
- {
- HBLog( "HBScan: failed to get a valid PS "
- "packet" );
- break;
- }
-
- if( dvdplay_position( vmg ) >= pictureEnd )
- {
- HBLog( "HBScan: gone too far, aborting" );
- break;
- }
- }
-
- if( !HBListCount( esBufferList ) )
- {
- break;
- }
-
- esBuffer = (HBBuffer*) HBListItemAt( esBufferList, 0 );
- HBListRemove( esBufferList, esBuffer );
-
- if( esBuffer->streamId != 0xE0 )
- {
- HBBufferClose( &esBuffer );
- }
- }
-
+ esBuffer = GetBuffer( esBufferList, dvdFile, &pictureStart,
+ pictureEnd );
if( !esBuffer )
{
- ret = 0;
break;
}
@@ -413,7 +536,7 @@ static int DecodeFrame( HBScan * s, dvdplay_ptr vmg,
}
#undef Y
#undef DARK
-
+
/* Write the raw picture to a file */
fwrite( info->display_fbuf->buf[0],
title->inWidth * title->inHeight, 1, file );
@@ -421,6 +544,7 @@ static int DecodeFrame( HBScan * s, dvdplay_ptr vmg,
title->inWidth * title->inHeight / 4, 1, file );
fwrite( info->display_fbuf->buf[2],
title->inWidth * title->inHeight / 4, 1, file );
+ ret = 1;
break;
}
else if( state == STATE_INVALID )
@@ -440,7 +564,6 @@ static int DecodeFrame( HBScan * s, dvdplay_ptr vmg,
HBBufferClose( &esBuffer );
}
HBListClose( &esBufferList );
- if( psBuffer ) HBBufferClose( &psBuffer );
if( esBuffer ) HBBufferClose( &esBuffer );
mpeg2_close( handle );
fclose( file );
diff --git a/core/Thread.c b/core/Thread.c
index 8c63b2423..9379223f0 100644
--- a/core/Thread.c
+++ b/core/Thread.c
@@ -1,4 +1,4 @@
-/* $Id: Thread.c,v 1.13 2004/03/16 16:14:03 titer Exp $
+/* $Id: Thread.c,v 1.14 2004/04/27 19:30:00 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://handbrake.m0k.org/>.
@@ -46,7 +46,7 @@ static void ThreadFunc( void * _t )
param.sched_priority = t->priority;
if( pthread_setschedparam( pthread_self(), SCHED_OTHER, &param ) )
{
- HBLog( "HBThreadInit: couldn't set thread priority" );
+ HBLog( "HBThread: couldn't set thread priority" );
}
#endif
@@ -61,7 +61,7 @@ HBThread * HBThreadInit( char * name, void (* function)(void *),
HBThread * t;
if( !( t = malloc( sizeof( HBThread ) ) ) )
{
- HBLog( "HBThreadInit: malloc() failed, gonna crash" );
+ HBLog( "HBThread: malloc() failed, gonna crash" );
return NULL;
}
t->name = strdup( name );
@@ -82,7 +82,7 @@ HBThread * HBThreadInit( char * name, void (* function)(void *),
(LPTHREAD_START_ROUTINE) ThreadFunc, t, 0, NULL );
#endif
- HBLog( "HBThreadInit: thread %d started (\"%s\")",
+ HBLog( "HBThread: thread %d started (\"%s\")",
t->thread, t->name );
return t;
@@ -102,7 +102,7 @@ void HBThreadClose( HBThread ** _t )
WaitForSingleObject( t->thread, INFINITE );
#endif
- HBLog( "HBThreadClose: thread %d stopped (\"%s\")",
+ HBLog( "HBThread: thread %d stopped (\"%s\")",
t->thread, t->name );
/* Clean up */
@@ -120,7 +120,7 @@ HBLock * HBLockInit()
HBLock * l;
if( !( l = malloc( sizeof( HBLock ) ) ) )
{
- HBLog( "HBLockInit: malloc() failed, gonna crash" );
+ HBLog( "HBLock: malloc() failed, gonna crash" );
return NULL;
}
diff --git a/core/Utils.c b/core/Utils.c
index 81aeebea5..45ebf7bd4 100644
--- a/core/Utils.c
+++ b/core/Utils.c
@@ -1,4 +1,4 @@
-/* $Id: Utils.c,v 1.16 2004/03/08 11:32:48 titer Exp $
+/* $Id: Utils.c,v 1.20 2004/05/12 17:21:24 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://handbrake.m0k.org/>.
@@ -14,6 +14,19 @@
#include "Utils.h"
#include "Fifo.h"
+#ifdef HB_CYGWIN
+int gettimeofday( struct timeval * tv, struct timezone * tz )
+{
+ tv->tv_sec = 0;
+ tv->tv_usec = 0;
+ return 0;
+}
+void bcopy( const void * src, void * dest, size_t n )
+{
+ memcpy( dest, src, n );
+}
+#endif
+
struct HBList
{
void ** items;
@@ -126,7 +139,8 @@ int HBPStoES( HBBuffer ** _psBuffer, HBList * esBufferList )
pos += 2; /* PES_packet_length */
PES_packet_end = pos + PES_packet_length;
- if( streamId != 0xE0 && streamId != 0xBD )
+ if( streamId != 0xE0 && streamId != 0xBD &&
+ ( streamId & 0xC0 ) != 0xC0 )
{
/* Not interesting */
pos = PES_packet_end;
@@ -303,7 +317,7 @@ HBTitle * HBTitleInit( char * device, int index )
}
t->device = strdup( device );
- t->index = index;
+ t->title = index;
t->codec = HB_CODEC_FFMPEG;
t->mux = HB_MUX_MP4;
@@ -336,7 +350,7 @@ void HBTitleClose( HBTitle ** _t )
*_t = NULL;
}
-HBAudio * HBAudioInit( int id, char * language )
+HBAudio * HBAudioInit( int id, char * language, int codec )
{
HBAudio * a;
if( !( a = calloc( sizeof( HBAudio ), 1 ) ) )
@@ -346,19 +360,20 @@ HBAudio * HBAudioInit( int id, char * language )
}
a->id = id;
- a->language = strdup( language );
a->start = -1;
+ a->inCodec = codec;
+ memset( a->language, 0, 512 );
+ snprintf( a->language, 511, "%s (%s)", language,
+ ( codec == HB_CODEC_AC3 ) ? "AC3" : ( ( codec ==
+ HB_CODEC_LPCM ? "LPCM" : "MPEG" ) ) );
return a;
}
void HBAudioClose( HBAudio ** _a )
{
HBAudio * a = *_a;
-
- free( a->language );
free( a );
-
*_a = NULL;
}
diff --git a/core/Utils.h b/core/Utils.h
index 2d1a06b92..fce20e557 100644
--- a/core/Utils.h
+++ b/core/Utils.h
@@ -1,4 +1,4 @@
-/* $Id: Utils.h,v 1.23 2004/03/08 11:32:48 titer Exp $
+/* $Id: Utils.h,v 1.30 2004/05/04 12:50:52 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://handbrake.m0k.org/>.
@@ -48,21 +48,13 @@ typedef struct HBTitle HBTitle;
typedef struct HBThread HBThread;
/* (De)Muxers */
-typedef struct HBAviMux HBAviMux;
-typedef struct HBOgmMux HBOgmMux;
typedef struct HBDVDRead HBDVDRead;
-typedef struct HBMp4Mux HBMp4Mux;
typedef struct HBScan HBScan;
typedef struct HBWork HBWork;
+typedef struct HBMuxThread HBMuxThread;
typedef struct HBWorkThread HBWorkThread;
-/* AVI stuff */
-typedef struct HBAviMainHeader HBAviMainHeader;
-typedef struct HBAviStreamHeader HBAviStreamHeader;
-typedef struct HBBitmapInfo HBBitmapInfo;
-typedef struct HBWaveFormatEx HBWaveFormatEx;
-
/* Misc functions which may be used from anywhere */
void HBSnooze( int time );
void HBLog( char * log, ... );
@@ -82,7 +74,7 @@ HBTitle * HBTitleInit();
void HBTitleClose( HBTitle ** );
/* HBAudio functions */
-HBAudio * HBAudioInit( int id, char * language );
+HBAudio * HBAudioInit( int id, char * language, int codec );
void HBAudioClose( HBAudio ** );
#define HB_SUCCESS 0x00
@@ -96,15 +88,16 @@ void HBAudioClose( HBAudio ** );
#define HB_ERROR_MPEG4_INIT 0x80
/* Possible codecs */
-#define HB_CODEC_MPEG2 0x00
-#define HB_CODEC_FFMPEG 0x01
-#define HB_CODEC_XVID 0x02
-#define HB_CODEC_AC3 0x04
-#define HB_CODEC_LPCM 0x08
-#define HB_CODEC_MP3 0x10
-#define HB_CODEC_AAC 0x20
-#define HB_CODEC_X264 0x40
-#define HB_CODEC_VORBIS 0x80
+#define HB_CODEC_MPEG2 0x000
+#define HB_CODEC_FFMPEG 0x001
+#define HB_CODEC_XVID 0x002
+#define HB_CODEC_AC3 0x004
+#define HB_CODEC_LPCM 0x008
+#define HB_CODEC_MP3 0x010
+#define HB_CODEC_AAC 0x020
+#define HB_CODEC_X264 0x040
+#define HB_CODEC_VORBIS 0x080
+#define HB_CODEC_MPGA 0x100
/* Possible muxers */
#define HB_MUX_AVI 0x00
@@ -115,8 +108,13 @@ struct HBTitle
{
/* DVD info */
char * device;
- int index;
- int length;
+ int title;
+ int vts_id;
+ int startBlock;
+ int endBlock;
+ int hours;
+ int minutes;
+ int seconds;
/* Audio infos */
HBList * audioList;
@@ -156,16 +154,13 @@ struct HBTitle
char * file;
int mux;
+ /* Muxer data */
+ void * muxData;
+
/* MP4 muxer specific */
- int track;
uint8_t * esConfig;
int esConfigLength;
- /* AVI muxer specific */
- HBAviMainHeader * aviMainHeader;
- HBAviStreamHeader * aviVideoHeader;
- HBBitmapInfo * aviVideoFormat;
-
/* Fifos */
HBFifo * inFifo;
HBFifo * rawFifo;
@@ -174,10 +169,8 @@ struct HBTitle
/* Threads */
HBDVDRead * dvdRead;
- HBAviMux * aviMux;
- HBMp4Mux * mp4Mux;
- HBOgmMux * ogmMux;
HBWorkThread * workThreads[8];
+ HBMuxThread * muxThread;
/* Work objects */
HBWork * decoder;
@@ -189,7 +182,7 @@ struct HBAudio
{
/* Ident */
uint32_t id;
- char * language;
+ char language[512];
/* Settings */
int inCodec;
@@ -208,22 +201,19 @@ struct HBAudio
uint8_t * esConfig;
unsigned long esConfigLength;
- /* MP4 track id */
- int track;
-
- /* AVI stuff */
- uint32_t aviFourCC;
- HBAviStreamHeader * aviAudioHeader;
- HBWaveFormatEx * aviAudioFormat;
+ /* Muxer data */
+ void * muxData;
/* Fifos */
HBFifo * inFifo;
HBFifo * rawFifo;
+ HBFifo * resampleFifo;
HBFifo * outFifo;
/* Work objects */
HBWork * decoder;
- HBWork * encoder;;
+ HBWork * resample;
+ HBWork * encoder;
};
#endif
diff --git a/core/VorbisEnc.c b/core/VorbisEnc.c
index c75b36850..8b7b10f8f 100644
--- a/core/VorbisEnc.c
+++ b/core/VorbisEnc.c
@@ -1,4 +1,4 @@
-/* $Id: VorbisEnc.c,v 1.5 2004/03/08 11:32:49 titer Exp $
+/* $Id: VorbisEnc.c,v 1.9 2004/05/02 16:25:00 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://handbrake.m0k.org/>.
@@ -11,7 +11,7 @@
#define OGGVORBIS_FRAME_SIZE 1024
-typedef struct HBVorbisEnc
+struct HBWork
{
HB_WORK_COMMON_MEMBERS
@@ -23,60 +23,46 @@ typedef struct HBVorbisEnc
vorbis_comment vc;
vorbis_dsp_state vd;
vorbis_block vb;
+ float position;
- HBBuffer *rawBuffer;
- int rawBufferPos; /* in bytes */
- float position;
int32_t * inputBuffer;
- unsigned long samplesGot;
- unsigned long inputSamples;
- HBBuffer *vorbisBuffer;
-
- HBBuffer *header[3];
-} HBVorbisEnc;
+};
/* Local prototypes */
static int VorbisEncWork( HBWork * );
-static int GetSamples( HBVorbisEnc * );
-HBWork *HBVorbisEncInit ( HBHandle *handle, HBAudio *audio )
+HBWork * HBVorbisEncInit ( HBHandle * handle, HBAudio * audio )
{
- HBVorbisEnc *enc = malloc( sizeof( HBVorbisEnc ) );
-
- enc->name = strdup( "VorbisEnc" );
- enc->work = VorbisEncWork;
+ HBWork * w = calloc( sizeof( HBWork ), 1 );
- enc->handle = handle;
- enc->audio = audio;
+ w->name = strdup( "VorbisEnc" );
+ w->work = VorbisEncWork;
- enc->inited = 0;
- enc->rawBuffer = NULL;
- enc->inputSamples = 2 * OGGVORBIS_FRAME_SIZE;
- enc->inputBuffer = malloc( 2 * OGGVORBIS_FRAME_SIZE * sizeof( int32_t ) );
- enc->samplesGot = 0;
+ w->handle = handle;
+ w->audio = audio;
- enc->vorbisBuffer = NULL;
+ w->inputBuffer = malloc( 2 * OGGVORBIS_FRAME_SIZE * sizeof( int32_t ) );
- return (HBWork*) enc;
+ return w;
}
-void HBVorbisEncClose( HBWork **_enc )
+void HBVorbisEncClose( HBWork ** _w )
{
- HBVorbisEnc *enc = (HBVorbisEnc*) *_enc;
+ HBWork * w = *_w;
- if( enc->inited )
+ if( w->inited )
{
- vorbis_block_clear( &enc->vb );
- vorbis_dsp_clear( &enc->vd );
- vorbis_comment_clear( &enc->vc );
- vorbis_info_clear( &enc->vi );
+ vorbis_block_clear( &w->vb );
+ vorbis_dsp_clear( &w->vd );
+ vorbis_comment_clear( &w->vc );
+ vorbis_info_clear( &w->vi );
}
- free( enc->name );
- free( enc );
+ free( w->name );
+ free( w );
- *_enc = NULL;
+ *_w = NULL;
}
static HBBuffer *PacketToBuffer( ogg_packet *op )
@@ -89,170 +75,98 @@ static HBBuffer *PacketToBuffer( ogg_packet *op )
return buf;
}
-static int VorbisEncWork( HBWork *w )
+static int VorbisEncWork( HBWork * w )
{
- HBVorbisEnc *enc = (HBVorbisEnc*)w;
- HBAudio *audio = enc->audio;
- int didSomething = 0;
+ HBAudio * audio = w->audio;
float **buffer;
int i;
+ float inputBuffer[OGGVORBIS_FRAME_SIZE * 2];
+ HBBuffer * vorbisBuffer;
+ if( HBFifoIsHalfFull( audio->outFifo ) )
+ {
+ return 0;
+ }
- if( !enc->inited )
+ if( !w->inited )
{
ogg_packet header[3];
- /* Get a first buffer so we know that audio->inSampleRate is correct */
- if( ( enc->rawBuffer = HBFifoPop( audio->rawFifo ) ) == NULL )
+ if( !HBFifoSize( audio->resampleFifo ) )
{
return 0;
}
- enc->inited = 1;
-
- didSomething = 1;
- enc->rawBufferPos = 0;
- enc->position = enc->rawBuffer->position;
- /* No resampling */
- audio->outSampleRate = audio->inSampleRate;
+ w->inited = 1;
/* init */
- vorbis_info_init( &enc->vi );
- if( vorbis_encode_setup_managed( &enc->vi, 2,
- audio->inSampleRate, -1, 1000 * audio->outBitrate, -1 ) ||
- vorbis_encode_ctl( &enc->vi, OV_ECTL_RATEMANAGE_AVG, NULL ) ||
- vorbis_encode_setup_init( &enc->vi ) )
+ vorbis_info_init( &w->vi );
+ if( vorbis_encode_setup_managed( &w->vi, 2,
+ audio->outSampleRate, -1, 1000 * audio->outBitrate, -1 ) ||
+ vorbis_encode_ctl( &w->vi, OV_ECTL_RATEMANAGE_AVG, NULL ) ||
+ vorbis_encode_setup_init( &w->vi ) )
{
- HBLog( "VorbisEnc: vorbis_encode_setup_managed failed" );
+ HBLog( "HBVorbisEnc: vorbis_encode_setup_managed failed" );
return 0;
}
/* add a comment */
- vorbis_comment_init( &enc->vc );
- vorbis_comment_add_tag( &enc->vc, "ENCODER", "HandBrake");
+ vorbis_comment_init( &w->vc );
+ vorbis_comment_add_tag( &w->vc, "ENCODER", "HandBrake");
/* set up the analysis state and auxiliary encoding storage */
- vorbis_analysis_init( &enc->vd, &enc->vi);
- vorbis_block_init( &enc->vd, &enc->vb);
+ vorbis_analysis_init( &w->vd, &w->vi);
+ vorbis_block_init( &w->vd, &w->vb);
/* get the 3 headers */
- vorbis_analysis_headerout( &enc->vd, &enc->vc,
+ vorbis_analysis_headerout( &w->vd, &w->vc,
&header[0], &header[1], &header[2] );
-
- enc->header[0] = PacketToBuffer( &header[0] );
- enc->header[1] = PacketToBuffer( &header[1] );
- enc->header[2] = PacketToBuffer( &header[2] );
- }
-
- if( enc->header[0] )
- {
- HBLog( "VorbisEncWork: sending header 1" );
- if( !HBFifoPush( audio->outFifo, &enc->header[0] ) )
- {
- return didSomething;
- }
- didSomething = 1;
- }
- if( enc->header[1] )
- {
- HBLog( "VorbisEncWork: sending header 2" );
- if( !HBFifoPush( audio->outFifo, &enc->header[1] ) )
- {
- return didSomething;
- }
- didSomething = 1;
- }
- if( enc->header[2] )
- {
- HBLog( "VorbisEncWork: sending header 3" );
- if( !HBFifoPush( audio->outFifo, &enc->header[2] ) )
- {
- return didSomething;
- }
- didSomething = 1;
- }
-
- /* Push already encoded data */
- if( enc->vorbisBuffer )
- {
- if( !HBFifoPush( audio->outFifo, &enc->vorbisBuffer ) )
+ for( i = 0; i < 3; i++ )
{
- return didSomething;
+ vorbisBuffer = PacketToBuffer( &header[i] );
+ if( !HBFifoPush( audio->outFifo, &vorbisBuffer ) )
+ {
+ HBLog( "HBVorbisEnc: HBFifoPush failed" );
+ }
}
}
/* Try to extract more data */
- if( vorbis_analysis_blockout( &enc->vd, &enc->vb ) == 1 )
+ if( vorbis_analysis_blockout( &w->vd, &w->vb ) == 1 )
{
ogg_packet op;
- vorbis_analysis( &enc->vb, NULL );
- vorbis_bitrate_addblock( &enc->vb );
+ vorbis_analysis( &w->vb, NULL );
+ vorbis_bitrate_addblock( &w->vb );
- if( vorbis_bitrate_flushpacket( &enc->vd, &op ) )
+ if( vorbis_bitrate_flushpacket( &w->vd, &op ) )
{
- enc->vorbisBuffer = PacketToBuffer( &op );
- enc->vorbisBuffer->position = enc->position;
+ vorbisBuffer = PacketToBuffer( &op );
+ vorbisBuffer->position = w->position;
+ if( !HBFifoPush( audio->outFifo, &vorbisBuffer ) )
+ {
+ HBLog( "HBVorbisEnc: HBFifoPush failed" );
+ }
return 1;
}
}
- /* FUCK -Werror ! */
- if( !GetSamples( enc ) )
+ if( !HBFifoGetBytes( audio->resampleFifo, (uint8_t*) inputBuffer,
+ OGGVORBIS_FRAME_SIZE * 2 * sizeof( float ),
+ &w->position ) )
{
- return didSomething;
+ return 0;
}
- didSomething = 1;
-
- buffer = vorbis_analysis_buffer( &enc->vd, OGGVORBIS_FRAME_SIZE );
+ buffer = vorbis_analysis_buffer( &w->vd, OGGVORBIS_FRAME_SIZE );
for( i = 0; i < OGGVORBIS_FRAME_SIZE; i++ )
{
- buffer[0][i] = (float)enc->inputBuffer[2 * i + 0]/32768.f;
- buffer[1][i] = (float)enc->inputBuffer[2 * i + 1]/32768.f;
+ buffer[0][i] = inputBuffer[2*i] / 32768.f;
+ buffer[1][i] = inputBuffer[2*i+1] / 32768.f;
}
- vorbis_analysis_wrote( &enc->vd, OGGVORBIS_FRAME_SIZE );
-
- enc->samplesGot = 0;
+ vorbis_analysis_wrote( &w->vd, OGGVORBIS_FRAME_SIZE );
return 1;
}
-static int GetSamples( HBVorbisEnc * f )
-{
- while( f->samplesGot < f->inputSamples )
- {
- int i, copy;
-
- if( !f->rawBuffer )
- {
- if( !( f->rawBuffer = HBFifoPop( f->audio->rawFifo ) ) )
- {
- return 0;
- }
-
- f->rawBufferPos = 0;
- f->position = f->rawBuffer->position;
- }
-
- copy = MIN( f->inputSamples - f->samplesGot,
- ( f->rawBuffer->samples - f->rawBufferPos ) * 2 );
-
- for( i = 0; i < copy; i += 2 )
- {
- f->inputBuffer[f->samplesGot++] =
- f->rawBuffer->left[f->rawBufferPos];
- f->inputBuffer[f->samplesGot++] =
- f->rawBuffer->right[f->rawBufferPos];
- f->rawBufferPos++;
- }
-
- if( f->rawBufferPos == f->rawBuffer->samples )
- {
- HBBufferClose( &f->rawBuffer );
- }
- }
-
- return 1;
-}
diff --git a/core/Work.c b/core/Work.c
index f2f05030a..e23af2421 100644
--- a/core/Work.c
+++ b/core/Work.c
@@ -1,4 +1,4 @@
-/* $Id: Work.c,v 1.12 2004/01/05 16:50:25 titer Exp $
+/* $Id: Work.c,v 1.14 2004/04/27 19:30:00 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://handbrake.m0k.org/>.
@@ -53,6 +53,7 @@ HBWorkThread * HBWorkThreadInit( HBHandle * handle, HBTitle * title,
{
audio = HBListItemAt( title->ripAudioList, i );
HBListAdd( t->workList, audio->decoder );
+ HBListAdd( t->workList, audio->resample );
HBListAdd( t->workList, audio->encoder );
}
@@ -105,7 +106,7 @@ void HBWorkThreadClose( HBWorkThread ** _t )
for( i = 0; i < HBListCount( t->workList ); i++ )
{
w = (HBWork*) HBListItemAt( t->workList, i );
- HBLog( "HBWorkThreadClose: %- 9s = %05.2f %%", w->name,
+ HBLog( "HBWorkThread: %- 9s = %05.2f %%", w->name,
100.0 * w->time / total );
}
@@ -126,7 +127,7 @@ static void WorkThread( void * _t )
uint64_t date;
didSomething = 0;
-
+
for( i = 0; !t->die; i++ )
{
HBCheckPaused( t->handle );
diff --git a/core/X264Enc.c b/core/X264Enc.c
index 50b9ab8bf..be8d76709 100644
--- a/core/X264Enc.c
+++ b/core/X264Enc.c
@@ -1,4 +1,4 @@
-/* $Id: X264Enc.c,v 1.3 2003/12/26 20:03:27 titer Exp $
+/* $Id: X264Enc.c,v 1.8 2004/05/02 16:25:00 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://handbrake.m0k.org/>.
@@ -9,79 +9,69 @@
/* x264 */
#include "x264.h"
-typedef struct HBX264Enc
+struct HBWork
{
HB_WORK_COMMON_MEMBERS
HBHandle *handle;
HBTitle *title;
- HBBuffer *buffer;
-
x264_t *h;
x264_picture_t picture;
-} HBX264Enc;
+};
/* Local prototypes */
static int HBX264EncWork( HBWork * );
-HBWork *HBX264EncInit( HBHandle * handle, HBTitle * title )
+HBWork * HBX264EncInit( HBHandle * handle, HBTitle * title )
{
- HBX264Enc *f = malloc( sizeof( HBX264Enc ) );
+ HBWork * w = malloc( sizeof( HBWork ) );
- if( f )
+ if( w )
{
x264_param_t param;
- f->name = strdup( "X264Enc" );
- f->work = HBX264EncWork;
-
- f->handle = handle;
- f->title = title;
+ w->name = strdup( "X264Enc" );
+ w->work = HBX264EncWork;
- f->buffer = NULL;
+ w->handle = handle;
+ w->title = title;
x264_param_default( &param );
param.i_width = title->outWidth;
param.i_height= title->outHeight;
- param.i_iframe = 5 * title->rate / title->rateBase;
- /* FIXME */
- param.b_deblocking_filter = 0;
- param.i_me = 1;
-
- if( ( f->h = x264_encoder_open( &param ) ) == NULL )
+ param.i_iframe = 20 * title->rate / title->rateBase;
+ param.i_idrframe = 1;
+ param.b_cabac = 0;
+ param.analyse.inter =
+ X264_ANALYSE_I16x16|X264_ANALYSE_I4x4|X264_ANALYSE_P16x16|
+ X264_ANALYSE_P16x8|X264_ANALYSE_P8x16|X264_ANALYSE_P8x8|
+ X264_ANALYSE_SMART_PSUB;
+
+ if( ( w->h = x264_encoder_open( &param ) ) == NULL )
{
HBLog( "x264: x264_encoder_new failed" );
return NULL;
}
- memset( &f->picture, 0, sizeof( x264_picture_t ) );
- f->picture.i_width = param.i_width;
- f->picture.i_height = param.i_height;
- f->picture.i_plane = 3;
+ memset( &w->picture, 0, sizeof( x264_picture_t ) );
+ w->picture.i_width = param.i_width;
+ w->picture.i_height = param.i_height;
+ w->picture.i_plane = 3;
HBLog( "x264: opening with %dx%d iframes=%d", param.i_width, param.i_height, param.i_iframe );
}
- return (HBWork*) f;
+ return w;
}
-void HBX264EncClose( HBWork **_f )
+void HBX264EncClose( HBWork ** _w )
{
- HBX264Enc *f = (HBX264Enc*) *_f;
-
- x264_encoder_close( f->h );
-
- if( f->buffer )
- {
- HBBufferClose( &f->buffer );
- }
-
- free( f->name );
-
- free( f );
-
- *_f = NULL;
+ HBWork * w = *_w;
+ x264_encoder_close( w->h );
+ free( w->name );
+ free( w );
+ *_w = NULL;
}
/* TODO trash buffer->pass == 1
@@ -90,29 +80,22 @@ void HBX264EncClose( HBWork **_f )
*/
static int HBX264EncWork( HBWork * w )
{
- HBX264Enc * f = (HBX264Enc*) w;
- HBTitle * title = f->title;
+ HBTitle * title = w->title;
- HBBuffer * frame;
- int didSomething = 0;
+ HBBuffer * frame, * buffer;
x264_nal_t *nal;
int i_nal;
int i;
- if( f->buffer )
+ if( HBFifoIsHalfFull( title->outFifo ) )
{
- if( !HBFifoPush( title->outFifo, &f->buffer ) )
- {
- /* nothing done */
- return 0;
- }
- didSomething = 1;
+ return 0;
}
- if( ( frame = HBFifoPop( title->scaledFifo ) ) == NULL )
+ if( !( frame = HBFifoPop( title->scaledFifo ) ) )
{
- return didSomething;
+ return 0;
}
if( frame->pass == 1 )
@@ -122,46 +105,51 @@ static int HBX264EncWork( HBWork * w )
return 1;
}
- f->picture.i_stride[0] = title->outWidth;
- f->picture.i_stride[1] = title->outWidth/2;
- f->picture.i_stride[2] = title->outWidth/2;
+ w->picture.i_stride[0] = title->outWidth;
+ w->picture.i_stride[1] = title->outWidth/2;
+ w->picture.i_stride[2] = title->outWidth/2;
- f->picture.plane[0] = frame->data;
- f->picture.plane[1] = &f->picture.plane[0][title->outWidth*title->outHeight];
- f->picture.plane[2] = &f->picture.plane[1][title->outWidth*title->outHeight/4];
+ w->picture.plane[0] = frame->data;
+ w->picture.plane[1] = &w->picture.plane[0][title->outWidth*title->outHeight];
+ w->picture.plane[2] = &w->picture.plane[1][title->outWidth*title->outHeight/4];
- x264_encoder_encode( f->h, &nal, &i_nal, &f->picture );
+ x264_encoder_encode( w->h, &nal, &i_nal, &w->picture );
- f->buffer = HBBufferInit( 3 * title->outWidth * title->outHeight / 2 ); /* FIXME */
- f->buffer->keyFrame = 0;
- f->buffer->position = frame->position;
- f->buffer->size = 0;
+ buffer = HBBufferInit( 3 * title->outWidth * title->outHeight / 2 ); /* FIXME */
+ buffer->keyFrame = 0;
+ buffer->position = frame->position;
+ buffer->size = 0;
for( i = 0; i < i_nal; i++ )
{
- int i_data = f->buffer->alloc - f->buffer->size;
+ int i_data = buffer->alloc - buffer->size;
int i_size;
- i_size = x264_nal_encode( &f->buffer->data[f->buffer->size],
+ i_size = x264_nal_encode( &buffer->data[buffer->size],
&i_data, 1, &nal[i] );
if( i_size <= 0 )
{
fprintf( stderr, "#################### error" );
}
- f->buffer->size += i_size;
+ buffer->size += i_size;
if( nal[i].i_ref_idc == NAL_PRIORITY_HIGH ||
nal[i].i_ref_idc == NAL_PRIORITY_HIGHEST )
{
- f->buffer->keyFrame = 1;
+ buffer->keyFrame = 1;
}
}
/* Inform the GUI about the current position */
- HBPosition( f->handle, frame->position );
+ HBPosition( w->handle, frame->position );
HBBufferClose( &frame );
+ if( !HBFifoPush( title->outFifo, &buffer ) )
+ {
+ HBLog( "HBX264Enc: HBFifoPush failed" );
+ }
+
return 1;
}
diff --git a/core/XvidEnc.c b/core/XvidEnc.c
index 8bf841f36..4c06da69e 100644
--- a/core/XvidEnc.c
+++ b/core/XvidEnc.c
@@ -1,4 +1,4 @@
-/* $Id: XvidEnc.c,v 1.20 2004/03/01 21:36:36 titer Exp $
+/* $Id: XvidEnc.c,v 1.26 2004/05/12 17:21:24 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://handbrake.m0k.org/>.
@@ -8,7 +8,7 @@
#include "xvid.h"
-typedef struct HBXvidEnc
+struct HBWork
{
HB_WORK_COMMON_MEMBERS
@@ -18,120 +18,82 @@ typedef struct HBXvidEnc
char file[1024];
void * xvid;
xvid_enc_frame_t frame;
- HBBuffer * mpeg4Buffer;
int pass;
- int frames;
- int64_t bytes;
-} HBXvidEnc;
+};
/* Local prototypes */
static int XvidEncWork( HBWork * );
HBWork * HBXvidEncInit( HBHandle * handle, HBTitle * title )
{
- HBXvidEnc * x;
- if( !( x = malloc( sizeof( HBXvidEnc ) ) ) )
+ HBWork * w;
+ if( !( w = malloc( sizeof( HBWork ) ) ) )
{
HBLog( "HBXvidEncInit: malloc() failed, gonna crash" );
return NULL;
}
- x->name = strdup( "XvidEnc" );
- x->work = XvidEncWork;
+ w->name = strdup( "XvidEnc" );
+ w->work = XvidEncWork;
- x->handle = handle;
- x->title = title;
+ w->handle = handle;
+ w->title = title;
- memset( x->file, 0, 1024 );
- snprintf( x->file, 1023, "/tmp/HB.%d.xvid.log",
- HBGetPid( x->handle ) );
+ memset( w->file, 0, 1024 );
+#ifndef HB_CYGWIN
+ snprintf( w->file, 1023, "/tmp/HB.%d.xvid.log",
+ HBGetPid( w->handle ) );
+#else
+ snprintf( w->file, 1023, "C:\\HB.%d.xvid.log",
+ HBGetPid( w->handle ) );
+#endif
- x->xvid = NULL;
- x->mpeg4Buffer = NULL;
- x->pass = 42;
- x->frames = 0;
- x->bytes = 0;
+ w->xvid = NULL;
+ w->pass = 42;
- return (HBWork*) x;
+ return w;
}
-void HBXvidEncClose( HBWork ** _x )
+void HBXvidEncClose( HBWork ** _w )
{
- HBXvidEnc * x = (HBXvidEnc*) *_x;
+ HBWork * w = *_w;
- if( x->xvid )
+ if( w->xvid )
{
HBLog( "HBXvidEnc: closing libxvidcore (pass %d)",
- x->pass );
- xvid_encore( x->xvid, XVID_ENC_DESTROY, NULL, NULL);
- }
- if( x->title->esConfig )
- {
- free( x->title->esConfig );
- x->title->esConfig = NULL;
- x->title->esConfigLength = 0;
+ w->pass );
+ xvid_encore( w->xvid, XVID_ENC_DESTROY, NULL, NULL);
}
- if( x->frames )
+ if( w->title->esConfig )
{
- float bitrate = (float) x->bytes * x->title->rate / x->frames /
- x->title->rateBase / 128;
- int64_t bytes = (int64_t) x->frames * x->title->bitrate * 128 *
- x->title->rateBase / x->title->rate;
-
- HBLog( "HBXvidEnc: %d frames encoded (%lld bytes), %.2f kbps",
- x->frames, x->bytes, bitrate );
-
- if( x->bytes > bytes )
- {
- HBLog( "HBXvidEnc: %lld more bytes than expected "
- "(error=%.2f %%)", x->bytes - bytes,
- 100.0 * ( x->bytes - bytes ) / bytes );
- }
- else if( x->bytes < bytes )
- {
- HBLog( "HBXvidEnc: %lld less bytes than expected "
- "(error=%.2f %%)", bytes - x->bytes,
- 100.0 * ( bytes - x->bytes ) / bytes );
- }
+ free( w->title->esConfig );
+ w->title->esConfig = NULL;
+ w->title->esConfigLength = 0;
}
- free( x->name );
- free( x );
- *_x = NULL;
+ free( w->name );
+ free( w );
+ *_w = NULL;
}
static int XvidEncWork( HBWork * w )
{
- HBXvidEnc * x = (HBXvidEnc*) w;
- HBTitle * title = x->title;
+ HBTitle * title = w->title;
HBBuffer * scaledBuffer;
HBBuffer * mpeg4Buffer;
- int didSomething = 0;
-
- if( x->mpeg4Buffer )
+ if( HBFifoIsHalfFull( title->outFifo ) )
{
- if( HBFifoPush( title->outFifo, &x->mpeg4Buffer ) )
- {
- didSomething = 1;
- }
- else
- {
- return didSomething;
- }
+ return 0;
}
- if( ( scaledBuffer = HBFifoPop( title->scaledFifo ) ) )
- {
- didSomething = 1;
- }
- else
+ if( !( scaledBuffer = HBFifoPop( title->scaledFifo ) ) )
{
- return didSomething;
+ return 0;
}
/* Init or re-init if needed */
- if( scaledBuffer->pass != x->pass )
+ if( scaledBuffer->pass != w->pass )
{
xvid_gbl_init_t xvid_gbl_init;
xvid_enc_create_t xvid_enc_create;
@@ -140,15 +102,15 @@ static int XvidEncWork( HBWork * w )
xvid_plugin_2pass2_t rc2pass2;
xvid_enc_plugin_t plugins[7];
- if( x->xvid )
+ if( w->xvid )
{
HBLog( "HBXvidEnc: closing libxvidcore (pass %d)",
- x->pass );
- xvid_encore( x->xvid, XVID_ENC_DESTROY, NULL, NULL);
+ w->pass );
+ xvid_encore( w->xvid, XVID_ENC_DESTROY, NULL, NULL);
}
- x->pass = scaledBuffer->pass;
- HBLog( "HBXvidEnc: opening libxvidcore (pass %d)", x->pass );
+ w->pass = scaledBuffer->pass;
+ HBLog( "HBXvidEnc: opening libxvidcore (pass %d)", w->pass );
memset( &xvid_gbl_init, 0, sizeof( xvid_gbl_init ) );
xvid_gbl_init.version = XVID_VERSION;
@@ -163,7 +125,7 @@ static int XvidEncWork( HBWork * w )
xvid_enc_create.plugins = plugins;
xvid_enc_create.num_plugins = 0;
- if( !x->pass )
+ if( !w->pass )
{
memset( &single, 0, sizeof( single ) );
single.version = XVID_VERSION;
@@ -172,20 +134,20 @@ static int XvidEncWork( HBWork * w )
plugins[xvid_enc_create.num_plugins].param = &single;
xvid_enc_create.num_plugins++;
}
- else if( x->pass == 1 )
+ else if( w->pass == 1 )
{
memset( &rc2pass1, 0, sizeof( rc2pass1 ) );
rc2pass1.version = XVID_VERSION;
- rc2pass1.filename = x->file;
+ rc2pass1.filename = w->file;
plugins[xvid_enc_create.num_plugins].func = xvid_plugin_2pass1;
plugins[xvid_enc_create.num_plugins].param = &rc2pass1;
xvid_enc_create.num_plugins++;
}
- else if( x->pass == 2 )
+ else if( w->pass == 2 )
{
memset(&rc2pass2, 0, sizeof(xvid_plugin_2pass2_t));
rc2pass2.version = XVID_VERSION;
- rc2pass2.filename = x->file;
+ rc2pass2.filename = w->file;
rc2pass2.bitrate = 1024 * title->bitrate;
plugins[xvid_enc_create.num_plugins].func = xvid_plugin_2pass2;
plugins[xvid_enc_create.num_plugins].param = &rc2pass2;
@@ -203,83 +165,83 @@ static int XvidEncWork( HBWork * w )
xvid_enc_create.global = 0;
xvid_encore( NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL );
- x->xvid = xvid_enc_create.handle;
+ w->xvid = xvid_enc_create.handle;
}
mpeg4Buffer = HBBufferInit( title->outWidth *
title->outHeight * 3 / 2 );
mpeg4Buffer->position = scaledBuffer->position;
- memset( &x->frame, 0, sizeof( x->frame ) );
- x->frame.version = XVID_VERSION;
- x->frame.bitstream = mpeg4Buffer->data;
- x->frame.length = -1;
- x->frame.input.plane[0] = scaledBuffer->data;
- x->frame.input.csp = XVID_CSP_I420;
- x->frame.input.stride[0] = title->outWidth;
- x->frame.vol_flags = 0;
- x->frame.vop_flags = XVID_VOP_HALFPEL | XVID_VOP_INTER4V |
+ memset( &w->frame, 0, sizeof( w->frame ) );
+ w->frame.version = XVID_VERSION;
+ w->frame.bitstream = mpeg4Buffer->data;
+ w->frame.length = -1;
+ w->frame.input.plane[0] = scaledBuffer->data;
+ w->frame.input.csp = XVID_CSP_I420;
+ w->frame.input.stride[0] = title->outWidth;
+ w->frame.vol_flags = 0;
+ w->frame.vop_flags = XVID_VOP_HALFPEL | XVID_VOP_INTER4V |
XVID_VOP_TRELLISQUANT | XVID_VOP_HQACPRED;
- x->frame.type = XVID_TYPE_AUTO;
- x->frame.quant = 0;
- x->frame.motion = XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16 |
+ w->frame.type = XVID_TYPE_AUTO;
+ w->frame.quant = 0;
+ w->frame.motion = XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16 |
XVID_ME_EXTSEARCH16 | XVID_ME_ADVANCEDDIAMOND8 |
XVID_ME_HALFPELREFINE8 | XVID_ME_EXTSEARCH8 |
XVID_ME_CHROMA_PVOP | XVID_ME_CHROMA_BVOP;
- x->frame.quant_intra_matrix = NULL;
- x->frame.quant_inter_matrix = NULL;
+ w->frame.quant_intra_matrix = NULL;
+ w->frame.quant_inter_matrix = NULL;
- mpeg4Buffer->size = xvid_encore( x->xvid, XVID_ENC_ENCODE,
- &x->frame, NULL );
- mpeg4Buffer->keyFrame = ( x->frame.out_flags & XVID_KEYFRAME );
+ mpeg4Buffer->size = xvid_encore( w->xvid, XVID_ENC_ENCODE,
+ &w->frame, NULL );
+ mpeg4Buffer->keyFrame = ( w->frame.out_flags & XVID_KEYFRAME );
/* Inform the GUI about the current position */
- HBPosition( x->handle, scaledBuffer->position );
+ HBPosition( w->handle, scaledBuffer->position );
HBBufferClose( &scaledBuffer );
- if( x->pass == 1 )
+ if( w->pass == 1 )
{
HBBufferClose( &mpeg4Buffer );
- return didSomething;
+ return 1;
}
- else
+
+ if( !title->esConfig )
{
- if( !title->esConfig )
+ int volStart, vopStart;
+ for( volStart = 0; ; volStart++ )
{
- int volStart, vopStart;
- for( volStart = 0; ; volStart++ )
+ if( mpeg4Buffer->data[volStart] == 0x0 &&
+ mpeg4Buffer->data[volStart+1] == 0x0 &&
+ mpeg4Buffer->data[volStart+2] == 0x1 &&
+ mpeg4Buffer->data[volStart+3] == 0x20 )
{
- if( mpeg4Buffer->data[volStart] == 0x0 &&
- mpeg4Buffer->data[volStart+1] == 0x0 &&
- mpeg4Buffer->data[volStart+2] == 0x1 &&
- mpeg4Buffer->data[volStart+3] == 0x20 )
- {
- break;
- }
+ break;
}
- for( vopStart = volStart + 4; ; vopStart++ )
+ }
+ for( vopStart = volStart + 4; ; vopStart++ )
+ {
+ if( mpeg4Buffer->data[vopStart] == 0x0 &&
+ mpeg4Buffer->data[vopStart+1] == 0x0 &&
+ mpeg4Buffer->data[vopStart+2] == 0x1 &&
+ mpeg4Buffer->data[vopStart+3] == 0xB6 )
{
- if( mpeg4Buffer->data[vopStart] == 0x0 &&
- mpeg4Buffer->data[vopStart+1] == 0x0 &&
- mpeg4Buffer->data[vopStart+2] == 0x1 &&
- mpeg4Buffer->data[vopStart+3] == 0xB6 )
- {
- break;
- }
+ break;
}
-
- HBLog( "XvidEnc: VOL size is %d bytes", vopStart - volStart );
- title->esConfig = malloc( vopStart - volStart );
- title->esConfigLength = vopStart - volStart;
- memcpy( title->esConfig, mpeg4Buffer->data + volStart,
- vopStart - volStart );
}
- x->frames++;
- x->bytes += mpeg4Buffer->size;
- x->mpeg4Buffer = mpeg4Buffer;
+
+ HBLog( "XvidEnc: VOL size is %d bytes", vopStart - volStart );
+ title->esConfig = malloc( vopStart - volStart );
+ title->esConfigLength = vopStart - volStart;
+ memcpy( title->esConfig, mpeg4Buffer->data + volStart,
+ vopStart - volStart );
+ }
+
+ if( !HBFifoPush( title->outFifo, &mpeg4Buffer ) )
+ {
+ HBLog( "HBXvidEnc: HBFifoPush failed" );
}
- return didSomething;
+ return 1;
}