summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/Ac3Decoder.cpp193
-rw-r--r--core/Ac3Decoder.h46
-rw-r--r--core/AviMuxer.cpp8
-rw-r--r--core/Common.cpp70
-rw-r--r--core/Common.h45
-rw-r--r--core/DVDReader.cpp10
-rw-r--r--core/Fifo.cpp5
-rw-r--r--core/Manager.cpp399
-rw-r--r--core/Manager.h11
-rw-r--r--core/Mp3Encoder.cpp172
-rw-r--r--core/Mp3Encoder.h19
-rw-r--r--core/Mpeg2Decoder.cpp119
-rw-r--r--core/Mpeg2Decoder.h13
-rw-r--r--core/Mpeg4Encoder.cpp114
-rw-r--r--core/Mpeg4Encoder.h15
-rw-r--r--core/MpegDemux.cpp230
-rw-r--r--core/MpegDemux.h19
-rw-r--r--core/Resizer.cpp122
-rw-r--r--core/Resizer.h23
-rw-r--r--core/Scanner.cpp66
-rw-r--r--core/Thread.cpp73
-rw-r--r--core/Thread.h11
-rw-r--r--core/Worker.cpp150
-rw-r--r--core/Worker.h27
24 files changed, 1246 insertions, 714 deletions
diff --git a/core/Ac3Decoder.cpp b/core/Ac3Decoder.cpp
index 12eed05df..95030d810 100644
--- a/core/Ac3Decoder.cpp
+++ b/core/Ac3Decoder.cpp
@@ -1,4 +1,4 @@
-/* $Id: Ac3Decoder.cpp,v 1.12 2003/09/30 14:38:15 titer Exp $
+/* $Id: Ac3Decoder.cpp,v 1.20 2003/10/13 10:58:24 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -13,101 +13,160 @@ extern "C" {
}
HBAc3Decoder::HBAc3Decoder( HBManager * manager, HBAudio * audio )
- : HBThread( "ac3decoder" )
{
- fManager = manager;
- fAudio = audio;
+ fManager = manager;
+ fAudio = audio;
+ fLock = new HBLock();
+ fUsed = false;
+
+ /* Init liba52 */
+ fState = a52_init( 0 );
+ fInFlags = 0;
+ fOutFlags = A52_STEREO;
+
+ /* Lame wants samples from -32768 to 32768 */
+ fSampleLevel = 32768.0;
+
/* Max size for a A52 frame is 3840 bytes */
- fAc3Frame = new HBBuffer( 3840 );
- fAc3Buffer = NULL;
- fPosInBuffer = 0;
- fPosition = 0;
+ fAc3Frame = new HBBuffer( 3840 );
+ fAc3Frame->fSize = 0;
+ fAc3Buffer = NULL;
+ fPosInBuffer = 0;
+ fRawBuffer = NULL;
}
HBAc3Decoder::~HBAc3Decoder()
{
+ if( fRawBuffer ) delete fRawBuffer;
+ if( fAc3Buffer ) delete fAc3Buffer;
delete fAc3Frame;
+ a52_free( fState );
+ delete fLock;
}
-void HBAc3Decoder::DoWork()
+bool HBAc3Decoder::Work()
{
- /* Init liba52 */
- a52_state_t * state = a52_init( 0 );
- int inFlags = 0;
- int outFlags = A52_STEREO;
-
- /* Lame wants samples from -32768 to 32768 */
- float sampleLevel = 32768;
-
- int frameSize;
- HBBuffer * rawBuffer;
- sample_t * samples;
-
- /* Main loop */
+ if( !Lock() )
+ {
+ return false;
+ }
+
+ bool didSomething = false;
+
+ sample_t * samples;
for( ;; )
{
- while( fSuspend )
+ /* Try to push the latest decoded buffer */
+ if( fRawBuffer )
{
- Snooze( 10000 );
+ if( fAudio->fRawFifo->Push( fRawBuffer ) )
+ {
+ fRawBuffer = NULL;
+ }
+ else
+ {
+ break;
+ }
}
- fAc3Frame->fSize = 0;
-
- /* Get a frame header (7 bytes) */
- if( !( GetBytes( 7 ) ) )
+ /* Get a new frame */
+ if( fAc3Frame->fSize < 7 )
{
- break;
- }
-
- /* Get the size of the current frame */
- frameSize = a52_syncinfo( fAc3Frame->fData, &inFlags,
- &fAudio->fInSampleRate,
- &fAudio->fInBitrate );
+ /* Get a frame header (7 bytes) */
+ if( !( GetBytes( 7 ) ) )
+ {
+ break;
+ }
- if( !frameSize )
- {
- Log( "HBAc3Decoder : a52_syncinfo failed" );
- fManager->Error();
- break;
+ /* Get the size of the current frame */
+ fFrameSize = a52_syncinfo( fAc3Frame->fData, &fInFlags,
+ &fAudio->fInSampleRate,
+ &fAudio->fInBitrate );
+ if( !fFrameSize )
+ {
+ Log( "HBAc3Decoder : a52_syncinfo failed" );
+ fManager->Error( HB_ERROR_A52_SYNC );
+ return false;
+ }
}
- /* Get the whole frame */
- if( !( GetBytes( (uint32_t) frameSize ) ) )
+ /* In case the audio should start later than the video,
+ insert some silence */
+ if( fAudio->fDelay > 3 * 256 * 1000 / fAudio->fInSampleRate )
{
- break;
+ fRawBuffer = new HBBuffer( 12 * 256 * sizeof( float ) );
+ for( uint32_t i = 0; i < 12 * 256; i++ )
+ {
+ ((float*)fRawBuffer->fData)[i] = 0;
+ }
+ fAudio->fDelay -= 6 * 256 * 1000 / fAudio->fInSampleRate;
+ continue;
}
+
+ if( fAc3Frame->fSize >= 7 )
+ {
+ /* Get the whole frame */
+ if( !( GetBytes( (uint32_t) fFrameSize ) ) )
+ {
+ break;
+ }
- /* Feed liba52 */
- a52_frame( state, fAc3Frame->fData, &outFlags, &sampleLevel, 0 );
+ /* Feed liba52 */
+ a52_frame( fState, fAc3Frame->fData, &fOutFlags,
+ &fSampleLevel, 0 );
- /* 6 blocks per frame, 256 samples per block */
- rawBuffer = new HBBuffer( 12 * 256 * sizeof( float ) );
- rawBuffer->fPosition = fPosition;
- for( int i = 0; i < 6; i++ )
- {
- /* Decode a block */
- a52_block( state );
+ /* 6 blocks per frame, 256 samples per block */
+ fRawBuffer = new HBBuffer( 12 * 256 * sizeof( float ) );
+ fRawBuffer->fPosition = fPosition;
+ for( int i = 0; i < 6; i++ )
+ {
+ /* Decode a block */
+ a52_block( fState );
- /* Get a pointer to the raw data */
- samples = a52_samples( state );
+ /* Get a pointer to the raw data */
+ samples = a52_samples( fState );
- /* Copy left channel data */
- memcpy( (float*) rawBuffer->fData + i * 256,
- samples,
- 256 * sizeof( float ) );
+ /* Copy left channel data */
+ memcpy( (float*) fRawBuffer->fData + i * 256,
+ samples,
+ 256 * sizeof( float ) );
- /* Copy right channel data */
- memcpy( (float*) rawBuffer->fData + ( 6 + i ) * 256,
- samples + 256,
- 256 * sizeof( float ) );
- }
+ /* Copy right channel data */
+ memcpy( (float*) fRawBuffer->fData + ( 6 + i ) * 256,
+ samples + 256,
+ 256 * sizeof( float ) );
+ }
- if( !Push( fAudio->fRawFifo, rawBuffer ) )
- {
- break;
+ fAc3Frame->fSize = 0;
+
+ didSomething = true;
}
}
+
+ Unlock();
+
+ return didSomething;
+}
+
+bool HBAc3Decoder::Lock()
+{
+ fLock->Lock();
+ if( fUsed )
+ {
+ fLock->Unlock();
+ return false;
+ }
+ fUsed = true;
+ fLock->Unlock();
+ return true;
+}
+
+void HBAc3Decoder::Unlock()
+{
+ fLock->Lock();
+ fUsed = false;
+ fLock->Unlock();
}
/* GetBytes() : pops buffers from the AC3 fifo until fAc3Frame
@@ -118,7 +177,7 @@ bool HBAc3Decoder::GetBytes( uint32_t size )
{
if( !fAc3Buffer )
{
- if( !( fAc3Buffer = Pop( fAudio->fAc3Fifo ) ) )
+ if( !( fAc3Buffer = fAudio->fAc3Fifo->Pop() ) )
{
return false;
}
diff --git a/core/Ac3Decoder.h b/core/Ac3Decoder.h
index 8226bb365..41ac48395 100644
--- a/core/Ac3Decoder.h
+++ b/core/Ac3Decoder.h
@@ -1,4 +1,4 @@
-/* $Id: Ac3Decoder.h,v 1.6 2003/09/30 14:38:15 titer Exp $
+/* $Id: Ac3Decoder.h,v 1.10 2003/10/07 20:58:12 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -8,26 +8,40 @@
#define HB_AC3_DECODER_H
#include "Common.h"
-#include "Thread.h"
-class HBAc3Decoder : public HBThread
+class HBAc3Decoder
{
public:
- HBAc3Decoder( HBManager * manager,
- HBAudio * audio );
- ~HBAc3Decoder();
+ HBAc3Decoder( HBManager * manager,
+ HBAudio * audio );
+ ~HBAc3Decoder();
+ bool Work();
private:
- void DoWork();
- bool GetBytes( uint32_t size );
-
- HBManager * fManager;
- HBAudio * fAudio;
-
- HBBuffer * fAc3Frame;
- HBBuffer * fAc3Buffer;
- uint32_t fPosInBuffer;
- float fPosition;
+ bool Lock();
+ void Unlock();
+ bool GetBytes( uint32_t size );
+
+ HBManager * fManager;
+ HBAudio * fAudio;
+
+ HBLock * fLock;
+ bool fUsed;
+
+ /* liba52 */
+ a52_state_t * fState;
+ int fInFlags;
+ int fOutFlags;
+ float fSampleLevel;
+
+ /* buffers */
+ HBBuffer * fAc3Frame;
+ HBBuffer * fAc3Buffer;
+ uint32_t fPosInBuffer;
+ HBBuffer * fRawBuffer;
+
+ float fPosition;
+ int fFrameSize;
};
#endif
diff --git a/core/AviMuxer.cpp b/core/AviMuxer.cpp
index 3b77b9c53..4a84fe8b8 100644
--- a/core/AviMuxer.cpp
+++ b/core/AviMuxer.cpp
@@ -1,4 +1,4 @@
-/* $Id: AviMuxer.cpp,v 1.14 2003/09/30 14:38:15 titer Exp $
+/* $Id: AviMuxer.cpp,v 1.17 2003/10/09 23:33:36 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -149,7 +149,7 @@ void HBAviIndex::WriteInt32( uint32_t val )
HBAviMuxer::HBAviMuxer( HBManager * manager, HBTitle * title,
HBAudio * audio1, HBAudio * audio2,
char * fileName )
- : HBThread( "avimuxer" )
+ : HBThread( "avimuxer", HB_NORMAL_PRIORITY )
{
fManager = manager;
fTitle = title;
@@ -163,6 +163,8 @@ HBAviMuxer::HBAviMuxer( HBManager * manager, HBTitle * title,
fRiffBytesCount = 2040;
fMoviBytesCount = 4;
+
+ Run();
}
void HBAviMuxer::DoWork()
@@ -171,7 +173,7 @@ void HBAviMuxer::DoWork()
if( !( fFile = fopen( fFileName, "w" ) ) )
{
Log( "HBAviMuxer: fopen failed" );
- fManager->Error();
+ fManager->Error( HB_ERROR_AVI_WRITE );
return;
}
diff --git a/core/Common.cpp b/core/Common.cpp
index b9bb3e062..4087a001d 100644
--- a/core/Common.cpp
+++ b/core/Common.cpp
@@ -1,4 +1,4 @@
-/* $Id: Common.cpp,v 1.29 2003/09/30 21:21:32 titer Exp $
+/* $Id: Common.cpp,v 1.31 2003/10/07 22:48:31 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -92,6 +92,74 @@ uint64_t GetDate()
return( (uint64_t) tv.tv_sec * 1000000 + (uint64_t) tv.tv_usec );
}
+int GetCPUCount()
+{
+ int CPUCount = 1;
+
+#if defined( SYS_BEOS )
+ system_info info;
+ get_system_info( &info );
+ CPUCount = info.cpu_count;
+
+#elif defined( SYS_MACOSX )
+ FILE * info;
+ char buffer[256];
+
+ if( ( info = popen( "/usr/sbin/sysctl hw.ncpu", "r" ) ) )
+ {
+ if( fgets( buffer, 256, info ) )
+ {
+ int count;
+ if( sscanf( buffer, "hw.ncpu: %d", &count ) == 1 )
+ {
+ CPUCount = count;
+ }
+ else
+ {
+ Log( "GetCPUCount: sscanf() failed" );
+ }
+ }
+ else
+ {
+ Log( "GetCPUCount: fgets() failed" );
+ }
+ fclose( info );
+ }
+ else
+ {
+ Log( "GetCPUCount: popen() failed" );
+ }
+
+#elif defined( SYS_LINUX )
+ FILE * info;
+ char buffer[256];
+
+ if( ( info = fopen( "/proc/cpuinfo", "r" ) ) )
+ {
+ int count = 0;
+ while( fgets( buffer, 256, info ) )
+ {
+ if( !memcmp( buffer, "processor",
+ sizeof( "processor" ) - 1 ) )
+ {
+ count++;
+ }
+ }
+ CPUCount = count;
+ fclose( info );
+ }
+ else
+ {
+ Log( "GetCPUCount: fopen() failed" );
+ }
+
+#endif
+ CPUCount = MAX( 1, CPUCount );
+ CPUCount = MIN( CPUCount, 8 );
+
+ return CPUCount;
+}
+
#define HBLIST_DEFAULT_SIZE 20
HBList::HBList()
diff --git a/core/Common.h b/core/Common.h
index f4d40c8bd..3c138e2a1 100644
--- a/core/Common.h
+++ b/core/Common.h
@@ -1,4 +1,4 @@
-/* $Id: Common.h,v 1.28 2003/10/03 16:18:08 titer Exp $
+/* $Id: Common.h,v 1.34 2003/10/13 17:49:58 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -16,6 +16,8 @@
typedef uint8_t byte_t;
/* Misc structures */
+typedef struct a52_state_s a52_state_t;
+typedef struct lame_global_struct lame_global_flags;
typedef struct dvdplay_s * dvdplay_ptr;
typedef struct mpeg2dec_s mpeg2dec_t;
typedef struct AVPicture AVPicture;
@@ -43,6 +45,7 @@ class HBScanner;
class HBStatus;
class HBThread;
class HBTitle;
+class HBWorker;
/* Handy macros */
#ifndef MIN
@@ -61,22 +64,36 @@ void Snooze( uint64_t time );
void Log( char * log, ... );
char * LanguageForCode( int code );
uint64_t GetDate();
+int GetCPUCount();
/* Possible states */
typedef enum
{
- HB_MODE_UNDEF = 0000,
- HB_MODE_NEED_VOLUME = 0001,
- HB_MODE_SCANNING = 0002,
- HB_MODE_INVALID_VOLUME = 0004,
- HB_MODE_READY_TO_RIP = 0010,
- HB_MODE_ENCODING = 0020,
- HB_MODE_SUSPENDED = 0040,
- HB_MODE_DONE = 0100,
- HB_MODE_CANCELED = 0200,
- HB_MODE_ERROR = 0400
+ HB_MODE_UNDEF = 00000,
+ HB_MODE_NEED_VOLUME = 00001,
+ HB_MODE_SCANNING = 00002,
+ HB_MODE_INVALID_VOLUME = 00004,
+ HB_MODE_READY_TO_RIP = 00010,
+ HB_MODE_ENCODING = 00020,
+ HB_MODE_SUSPENDED = 00040,
+ HB_MODE_STOPPING = 00100,
+ HB_MODE_DONE = 00200,
+ HB_MODE_CANCELED = 00400,
+ HB_MODE_ERROR = 01000
} HBMode;
+/* Possible errors */
+typedef enum
+{
+ HB_ERROR_A52_SYNC = 0,
+ HB_ERROR_AVI_WRITE,
+ HB_ERROR_DVD_OPEN,
+ HB_ERROR_DVD_READ,
+ HB_ERROR_MP3_INIT,
+ HB_ERROR_MP3_ENCODE,
+ HB_ERROR_MPEG4_INIT
+} HBError;
+
class HBStatus
{
public:
@@ -96,6 +113,9 @@ class HBStatus
uint64_t fStartDate;
uint32_t fRemainingTime; /* in seconds */
uint64_t fSuspendDate;
+
+ /* HB_MODE_ERROR */
+ HBError fError;
};
class HBList
@@ -130,6 +150,8 @@ class HBAudio
int fInBitrate;
int fOutBitrate;
+ int64_t fDelay; /* in ms */
+
/* Fifos */
HBFifo * fAc3Fifo;
HBFifo * fRawFifo;
@@ -187,6 +209,7 @@ class HBTitle
HBResizer * fResizer;
HBMpeg4Encoder * fMpeg4Encoder;
HBAviMuxer * fAviMuxer;
+ HBWorker * fWorkers[4];
};
#endif
diff --git a/core/DVDReader.cpp b/core/DVDReader.cpp
index 27c20d08a..8f7835f51 100644
--- a/core/DVDReader.cpp
+++ b/core/DVDReader.cpp
@@ -1,4 +1,4 @@
-/* $Id: DVDReader.cpp,v 1.12 2003/10/03 16:49:19 titer Exp $
+/* $Id: DVDReader.cpp,v 1.17 2003/10/09 23:33:36 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -15,10 +15,12 @@
#include <dvdplay/nav.h>
HBDVDReader::HBDVDReader( HBManager * manager, HBTitle * title )
- : HBThread( "dvdreader" )
+ : HBThread( "dvdreader", HB_NORMAL_PRIORITY )
{
fManager = manager;
fTitle = title;
+
+ Run();
}
void HBDVDReader::DoWork()
@@ -29,7 +31,7 @@ void HBDVDReader::DoWork()
if( !vmg )
{
Log( "HBDVDReader: dvdplay_open() failed" );
- fManager->Error();
+ fManager->Error( HB_ERROR_DVD_OPEN );
return;
}
@@ -69,7 +71,7 @@ void HBDVDReader::DoWork()
{
Log( "HBDVDReader: could not dvdplay_read()" );
delete dvdBuffer;
- fManager->Error();
+ fManager->Error( HB_ERROR_DVD_READ );
break;
}
diff --git a/core/Fifo.cpp b/core/Fifo.cpp
index 35bcb0449..d1d051c33 100644
--- a/core/Fifo.cpp
+++ b/core/Fifo.cpp
@@ -1,4 +1,4 @@
-/* $Id: Fifo.cpp,v 1.14 2003/10/02 15:44:52 titer Exp $
+/* $Id: Fifo.cpp,v 1.15 2003/10/13 14:12:18 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -51,7 +51,8 @@ HBFifo::HBFifo( int capacity )
HBFifo::~HBFifo()
{
- Log( "HBFifo::~HBFifo : trashing %d buffers", Size() );
+ Log( "HBFifo::~HBFifo: trashing %d buffer%s",
+ Size(), Size() ? "s" : "" );
/* Empty the fifo */
while( fWhereToPush != fWhereToPop )
diff --git a/core/Manager.cpp b/core/Manager.cpp
index 583bda36a..826ceea58 100644
--- a/core/Manager.cpp
+++ b/core/Manager.cpp
@@ -1,72 +1,103 @@
-/* $Id: Manager.cpp,v 1.47 2003/10/05 14:28:40 titer Exp $
+/* $Id: Manager.cpp,v 1.68 2003/10/13 23:42:03 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
It may be used under the terms of the GNU General Public License. */
-#include "Manager.h"
-#include "Fifo.h"
-#include "Scanner.h"
+#include "Ac3Decoder.h"
+#include "AviMuxer.h"
#include "DVDReader.h"
-#include "MpegDemux.h"
+#include "Fifo.h"
+#include "Manager.h"
+#include "Mp3Encoder.h"
#include "Mpeg2Decoder.h"
#include "Mpeg4Encoder.h"
-#include "Ac3Decoder.h"
-#include "Mp3Encoder.h"
-#include "AviMuxer.h"
+#include "MpegDemux.h"
#include "Resizer.h"
+#include "Scanner.h"
+#include "Worker.h"
#include <ffmpeg/avcodec.h>
/* Public methods */
-HBManager::HBManager( bool debug )
- : HBThread( "manager" )
+HBManager::HBManager( bool debug, int cpuCount )
+ : HBThread( "manager", HB_NORMAL_PRIORITY )
{
- fPid = 0;
-
- fStopScan = false;
- fStopRip = false;
- fRipDone = false;
- fError = false;
-
- fScanner = NULL;
-
- fStatus.fMode = HB_MODE_NEED_VOLUME;
- fNeedUpdate = true;
-
/* See Log() in Common.cpp */
if( debug )
{
- setenv( "HB_DEBUG", "1", 1 );
+ putenv( "HB_DEBUG=1" );
+ }
+
+ /* Check CPU count */
+ if( !cpuCount )
+ {
+ fCPUCount = GetCPUCount();
+ Log( "HBManager::HBManager: %d CPU%s detected", fCPUCount,
+ ( fCPUCount > 1 ) ? "s" : "" );
}
else
{
- unsetenv( "HB_DEBUG" );
+ fCPUCount = cpuCount;
+ if( fCPUCount < 1 )
+ {
+ Log( "HBManager::HBManager: invalid CPU count (%d), "
+ "using 1", fCPUCount );
+ fCPUCount = 1;
+ }
+ else if( fCPUCount > 8 )
+ {
+ Log( "HBManager::HBManager: invalid CPU count (%d), "
+ "using 8", fCPUCount );
+ fCPUCount = 8;
+ }
+ Log( "HBManager::HBManager: user specified %d CPU%s",
+ fCPUCount, ( fCPUCount > 1 ) ? "s" : "" );
}
- fCurTitle = NULL;
- fCurAudio1 = NULL;
- fCurAudio2 = NULL;
-
/* Init ffmpeg's libavcodec */
avcodec_init();
// register_avcodec( &mpeg4_encoder );
avcodec_register_all();
+ /* Initialization */
+ fStopScan = false;
+ fStopRip = false;
+ fRipDone = false;
+ fError = false;
+
+ fScanner = NULL;
+
+ fStatusLock = new HBLock();
+ fStatus.fMode = HB_MODE_NEED_VOLUME;
+ fNeedUpdate = true;
+
+ fCurTitle = NULL;
+ fCurAudio1 = NULL;
+ fCurAudio2 = NULL;
+
Run();
}
HBManager::~HBManager()
{
/* Stop ripping if needed */
- StopRip();
- while( fStopRip )
+ fStatusLock->Lock();
+ if( fStatus.fMode == HB_MODE_ENCODING )
{
- Snooze( 10000 );
- }
+ fStatusLock->Unlock();
- Stop();
+ StopRip();
+ while( fStopRip )
+ {
+ Snooze( 10000 );
+ }
+ }
+ else
+ {
+ fStatusLock->Unlock();
+ }
/* Stop scanning if needed */
if( fScanner )
@@ -76,24 +107,24 @@ HBManager::~HBManager()
/* Remove temp files */
char command[1024]; memset( command, 0, 1024 );
- sprintf( command, "rm -f /tmp/HB.%d.*", fPid );
+ sprintf( command, "rm -f /tmp/HB.%d.*", GetPid() );
system( command );
+
+ delete fStatusLock;
}
void HBManager::DoWork()
{
- fPid = (int) getpid();
-
while( !fDie )
{
- /* Terminate dying threads */
if( fStopScan )
{
- fStopScan = false;
-
+ /* Destroy the thread */
delete fScanner;
fScanner = NULL;
+ /* Update interface */
+ fStatusLock->Lock();
if( fStatus.fTitleList && fStatus.fTitleList->CountItems() )
{
fStatus.fMode = HB_MODE_READY_TO_RIP;
@@ -103,83 +134,47 @@ void HBManager::DoWork()
fStatus.fMode = HB_MODE_INVALID_VOLUME;
}
fNeedUpdate = true;
+ fStatusLock->Unlock();
+
+ fStopScan = false;
}
- if( fStopRip || fError )
+ if( fStopRip || fError || fRipDone )
{
- delete fCurTitle->fDVDReader;
- delete fCurTitle->fMpegDemux;
- delete fCurTitle->fMpeg2Decoder;
- delete fCurTitle->fResizer;
- delete fCurTitle->fMpeg4Encoder;
- delete fCurTitle->fAviMuxer;
-
- if( fCurAudio1 )
+ if( fRipDone )
{
- delete fCurAudio1->fAc3Decoder;
- delete fCurAudio1->fMp3Encoder;
+ /* Wait a bit to avoid trashing frames in fifos -
+ That's kinda ugly */
+ while( fCurTitle->fPSFifo->Size() ||
+ ( fCurTitle->fMpeg2Fifo->Size() &&
+ ( !fCurAudio1 || fCurAudio1->fAc3Fifo->Size() ) &&
+ ( !fCurAudio2 || fCurAudio2->fAc3Fifo->Size() ) ) )
+ {
+ Snooze( 10000 );
+ }
+ Snooze( 500000 );
}
-
- if( fCurAudio2 )
- {
- delete fCurAudio2->fAc3Decoder;
- delete fCurAudio2->fMp3Encoder;
- }
-
- delete fCurTitle->fPSFifo;
- delete fCurTitle->fMpeg2Fifo;
- delete fCurTitle->fRawFifo;
- delete fCurTitle->fResizedFifo;
- delete fCurTitle->fMpeg4Fifo;
-
- if( fCurAudio1 )
- {
- delete fCurAudio1->fAc3Fifo;
- delete fCurAudio1->fRawFifo;
- delete fCurAudio1->fMp3Fifo;
- }
-
- if( fCurAudio2 )
- {
- delete fCurAudio2->fAc3Fifo;
- delete fCurAudio2->fRawFifo;
- delete fCurAudio2->fMp3Fifo;
- }
-
- fStatus.fMode = fError ? HB_MODE_ERROR : HB_MODE_CANCELED;
- fStopRip = false;
- fError = false;
- fNeedUpdate = true;
- }
-
- if( fRipDone )
- {
- /* This is UGLY ! */
- while( fCurTitle->fPSFifo->Size() ||
- fCurTitle->fMpeg2Fifo->Size() ||
- fCurTitle->fRawFifo->Size() ||
- fCurTitle->fResizedFifo->Size() ||
- ( fCurAudio1 && fCurAudio1->fAc3Fifo->Size() ) ||
- ( fCurAudio1 && fCurAudio1->fRawFifo->Size() ) ||
- ( fCurAudio2 && fCurAudio2->fAc3Fifo->Size() ) ||
- ( fCurAudio2 && fCurAudio2->fRawFifo->Size() ) )
+ else
{
- Snooze( 10000 );
+ fStatusLock->Lock();
+ fStatus.fMode = HB_MODE_STOPPING;
+ fNeedUpdate = true;
+ fStatusLock->Unlock();
}
-
- while( fCurTitle->fMpeg4Fifo->Size() &&
- ( !fCurAudio1 || fCurAudio1->fMp3Fifo->Size() ) &&
- ( !fCurAudio2 || fCurAudio2->fMp3Fifo->Size() ) )
+
+ /* Stop threads */
+ delete fCurTitle->fDVDReader;
+ delete fCurTitle->fAviMuxer;
+ for( int i = 0; i < fCPUCount; i++ )
{
- Snooze( 10000 );
+ delete fCurTitle->fWorkers[i];
}
- delete fCurTitle->fDVDReader;
+ /* Clean up */
delete fCurTitle->fMpegDemux;
delete fCurTitle->fMpeg2Decoder;
delete fCurTitle->fResizer;
delete fCurTitle->fMpeg4Encoder;
- delete fCurTitle->fAviMuxer;
if( fCurAudio1 )
{
@@ -193,6 +188,7 @@ void HBManager::DoWork()
delete fCurAudio2->fMp3Encoder;
}
+ /* Destroy fifos */
delete fCurTitle->fPSFifo;
delete fCurTitle->fMpeg2Fifo;
delete fCurTitle->fRawFifo;
@@ -213,9 +209,16 @@ void HBManager::DoWork()
delete fCurAudio2->fMp3Fifo;
}
- fStatus.fMode = HB_MODE_DONE;
- fRipDone = false;
+ /* Update interface */
+ fStatusLock->Lock();
+ fStatus.fMode = fStopRip ? HB_MODE_CANCELED :
+ ( fError ? HB_MODE_ERROR : HB_MODE_DONE );
fNeedUpdate = true;
+ fStatusLock->Unlock();
+
+ fStopRip = false;
+ fError = false;
+ fRipDone = false;
}
Snooze( 10000 );
@@ -224,23 +227,25 @@ void HBManager::DoWork()
bool HBManager::NeedUpdate()
{
+ fStatusLock->Lock();
if( fNeedUpdate )
{
fNeedUpdate = false;
+ fStatusLock->Unlock();
return true;
}
-
+ fStatusLock->Unlock();
+
return false;
}
HBStatus HBManager::GetStatus()
{
- return fStatus;
-}
-
-int HBManager::GetPid()
-{
- return fPid;
+ fStatusLock->Lock();
+ HBStatus status = fStatus;
+ fStatusLock->Unlock();
+
+ return status;
}
void HBManager::ScanVolumes( char * device )
@@ -254,12 +259,13 @@ void HBManager::ScanVolumes( char * device )
}
fScanner = new HBScanner( this, device );
- fScanner->Run();
+ fStatusLock->Lock();
fStatus.fMode = HB_MODE_SCANNING;
fStatus.fScannedVolume = strdup( device );
fStatus.fScannedTitle = 0;
fNeedUpdate = true;
+ fStatusLock->Unlock();
}
void HBManager::StartRip( HBTitle * title, HBAudio * audio1,
@@ -282,86 +288,77 @@ void HBManager::StartRip( HBTitle * title, HBAudio * audio1,
FixPictureSettings( title );
- Log( "HBManager::StartRip : device: %s, title: %d",
- title->fDevice, title->fIndex );
- Log( " - video : %dx%d -> %dx%d, bitrate = %d, 2-pass = %s",
+ Log( "HBManager::StartRip:" );
+ Log( "- device: %s, title: %d", title->fDevice, title->fIndex );
+ Log( "- video: %dx%d->%dx%d, bitrate=%d, 2-pass=%s, deinterlace=%s",
title->fInWidth, title->fInHeight,
title->fOutWidth, title->fOutHeight,
- title->fBitrate, title->fTwoPass ? "yes" : "no" );
- Log( " - cropping: top=%d, bottom=%d, left=%d, right=%d",
+ title->fBitrate, title->fTwoPass ? "yes" : "no",
+ title->fDeinterlace ? "yes" : "no" );
+ Log( "- cropping: top=%d, bottom=%d, left=%d, right=%d",
title->fTopCrop, title->fBottomCrop,
title->fLeftCrop, title->fRightCrop );
if( audio1 )
{
- Log( " - audio 1: lang = %s (%x), bitrate = %d",
- audio1->fDescription, audio1->fId, audio1->fOutBitrate );
+ Log( "- audio 1: lang = %s (%x), bitrate = %d",
+ audio1->fDescription, audio1->fId, audio1->fOutBitrate );
}
if( audio2 )
{
- Log( " - audio 2: lang = %s (%x), bitrate = %d",
- audio2->fDescription, audio1->fId, audio2->fOutBitrate );
+ Log( "- audio 2: lang = %s (%x), bitrate = %d",
+ audio2->fDescription, audio2->fId, audio2->fOutBitrate );
}
- /* Create fifos & threads */
-
- title->fPSFifo = new HBFifo();
- title->fMpeg2Fifo = new HBFifo();
- title->fRawFifo = new HBFifo();
- title->fResizedFifo = new HBFifo();
- title->fMpeg4Fifo = new HBFifo();
+ /* Create fifos */
+ title->fPSFifo = new HBFifo( 256 );
+ title->fMpeg2Fifo = new HBFifo( 256 );
+ title->fRawFifo = new HBFifo( 4 );
+ title->fResizedFifo = new HBFifo( 4 );
+ title->fMpeg4Fifo = new HBFifo( 4 );
+ if( audio1 )
+ {
+ audio1->fAc3Fifo = new HBFifo( 256 );
+ audio1->fRawFifo = new HBFifo( 4 );
+ audio1->fMp3Fifo = new HBFifo( 4 );
+ }
+ if( audio2 )
+ {
+ audio2->fAc3Fifo = new HBFifo( 256 );
+ audio2->fRawFifo = new HBFifo( 4 );
+ audio2->fMp3Fifo = new HBFifo( 4 );
+ }
- title->fDVDReader = new HBDVDReader( this, title );
+ /* Create decoders & encoders objects */
title->fMpegDemux = new HBMpegDemux( this, title, audio1,
audio2 );
title->fMpeg2Decoder = new HBMpeg2Decoder( this, title );
title->fResizer = new HBResizer( this, title );
title->fMpeg4Encoder = new HBMpeg4Encoder( this, title );
- title->fAviMuxer = new HBAviMuxer( this, title, audio1, audio2,
- file );
-
if( audio1 )
{
- audio1->fAc3Fifo = new HBFifo();
- audio1->fRawFifo = new HBFifo();
- audio1->fMp3Fifo = new HBFifo();
audio1->fAc3Decoder = new HBAc3Decoder( this, audio1 );
audio1->fMp3Encoder = new HBMp3Encoder( this, audio1 );
}
-
if( audio2 )
{
- audio2->fAc3Fifo = new HBFifo();
- audio2->fRawFifo = new HBFifo();
- audio2->fMp3Fifo = new HBFifo();
audio2->fAc3Decoder = new HBAc3Decoder( this, audio2 );
audio2->fMp3Encoder = new HBMp3Encoder( this, audio2 );
}
- /* Launch the threads */
-
- title->fDVDReader->Run();
- title->fMpegDemux->Run();
- title->fMpeg2Decoder->Run();
- title->fResizer->Run();
- title->fMpeg4Encoder->Run();
- title->fAviMuxer->Run();
-
- if( audio1 )
- {
- audio1->fAc3Decoder->Run();
- audio1->fMp3Encoder->Run();
- }
-
- if( audio2 )
+ /* Create and launch the threads */
+ title->fDVDReader = new HBDVDReader( this, title );
+ title->fAviMuxer = new HBAviMuxer( this, title, audio1, audio2,
+ file );
+ for( int i = 0; i < fCPUCount; i++ )
{
- audio2->fAc3Decoder->Run();
- audio2->fMp3Encoder->Run();
+ title->fWorkers[i] = new HBWorker( title, audio1, audio2 );
}
-
+
fCurTitle = title;
fCurAudio1 = audio1;
fCurAudio2 = audio2;
+ fStatusLock->Lock();
fStatus.fMode = HB_MODE_ENCODING;
fStatus.fPosition = 0;
fStatus.fFrameRate = 0;
@@ -370,6 +367,7 @@ void HBManager::StartRip( HBTitle * title, HBAudio * audio1,
fStatus.fRemainingTime = 0;
fStatus.fSuspendDate = 0;
fNeedUpdate = true;
+ fStatusLock->Unlock();
}
void HBManager::SuspendRip()
@@ -382,27 +380,17 @@ void HBManager::SuspendRip()
}
fCurTitle->fDVDReader->Suspend();
- fCurTitle->fMpegDemux->Suspend();
- fCurTitle->fMpeg2Decoder->Suspend();
- fCurTitle->fResizer->Suspend();
- fCurTitle->fMpeg4Encoder->Suspend();
fCurTitle->fAviMuxer->Suspend();
-
- if( fCurAudio1 )
+ for( int i = 0; i < fCPUCount; i++ )
{
- fCurAudio1->fAc3Decoder->Suspend();
- fCurAudio1->fMp3Encoder->Suspend();
- }
-
- if( fCurAudio2 )
- {
- fCurAudio2->fAc3Decoder->Suspend();
- fCurAudio2->fMp3Encoder->Suspend();
+ fCurTitle->fWorkers[i]->Suspend();
}
+ fStatusLock->Lock();
fStatus.fMode = HB_MODE_SUSPENDED;
fStatus.fSuspendDate = GetDate();
fNeedUpdate = true;
+ fStatusLock->Unlock();
}
void HBManager::ResumeRip()
@@ -415,27 +403,17 @@ void HBManager::ResumeRip()
}
fCurTitle->fDVDReader->Resume();
- fCurTitle->fMpegDemux->Resume();
- fCurTitle->fMpeg2Decoder->Resume();
- fCurTitle->fResizer->Resume();
- fCurTitle->fMpeg4Encoder->Resume();
fCurTitle->fAviMuxer->Resume();
-
- if( fCurAudio1 )
- {
- fCurAudio1->fAc3Decoder->Resume();
- fCurAudio1->fMp3Encoder->Resume();
- }
-
- if( fCurAudio2 )
+ for( int i = 0; i < fCPUCount; i++ )
{
- fCurAudio2->fAc3Decoder->Resume();
- fCurAudio2->fMp3Encoder->Resume();
+ fCurTitle->fWorkers[i]->Resume();
}
+ fStatusLock->Lock();
fStatus.fMode = HB_MODE_ENCODING;
fStatus.fStartDate += GetDate() - fStatus.fSuspendDate;
fNeedUpdate = true;
+ fStatusLock->Unlock();
}
void HBManager::StopRip()
@@ -448,25 +426,6 @@ void HBManager::StopRip()
}
/* Stop the threads */
-
- fCurTitle->fDVDReader->Stop();
- fCurTitle->fMpegDemux->Stop();
- fCurTitle->fMpeg2Decoder->Stop();
- fCurTitle->fMpeg4Encoder->Stop();
- fCurTitle->fAviMuxer->Stop();
-
- if( fCurAudio1 )
- {
- fCurAudio1->fAc3Decoder->Stop();
- fCurAudio1->fMp3Encoder->Stop();
- }
-
- if( fCurAudio2 )
- {
- fCurAudio2->fAc3Decoder->Stop();
- fCurAudio2->fMp3Encoder->Stop();
- }
-
fStopRip = true;
}
@@ -545,7 +504,7 @@ uint8_t * HBManager::GetPreview( HBTitle * title, uint32_t image )
/* Get the original image from the temp file */
char fileName[1024]; memset( fileName, 0, 1024 );
- sprintf( fileName, "/tmp/HB.%d.%x.%d", fPid, (uint32_t) title,
+ sprintf( fileName, "/tmp/HB.%d.%x.%d", GetPid(), (uint32_t) title,
image);
FILE * file = fopen( fileName, "r" );
fread( buf1, 3 * fInWidth * fInHeight / 2, 1, file );
@@ -632,10 +591,12 @@ uint8_t * HBManager::GetPreview( HBTitle * title, uint32_t image )
void HBManager::Scanning( char * volume, int title )
{
+ fStatusLock->Lock();
fStatus.fMode = HB_MODE_SCANNING;
fStatus.fScannedVolume = volume;
fStatus.fScannedTitle = title;
fNeedUpdate = true;
+ fStatusLock->Unlock();
}
void HBManager::ScanDone( HBList * titleList )
@@ -650,34 +611,14 @@ void HBManager::Done()
fRipDone = true;
}
-void HBManager::Error()
+void HBManager::Error( HBError error )
{
if( fStatus.fMode != HB_MODE_ENCODING )
{
return;
}
- /* Stop the threads */
-
- fCurTitle->fDVDReader->Stop();
- fCurTitle->fMpegDemux->Stop();
- fCurTitle->fMpeg2Decoder->Stop();
- fCurTitle->fResizer->Stop();
- fCurTitle->fMpeg4Encoder->Stop();
- fCurTitle->fAviMuxer->Stop();
-
- if( fCurAudio1 )
- {
- fCurAudio1->fAc3Decoder->Stop();
- fCurAudio1->fMp3Encoder->Stop();
- }
-
- if( fCurAudio2 )
- {
- fCurAudio2->fAc3Decoder->Stop();
- fCurAudio2->fMp3Encoder->Stop();
- }
-
+ fStatus.fError = error;
fError = true;
}
@@ -695,6 +636,7 @@ void HBManager::SetPosition( float pos )
return;
}
+ fStatusLock->Lock();
fStatus.fPosition = pos;
fStatus.fFrameRate = (float) fStatus.fFrames /
( ( (float) ( GetDate() - fStatus.fStartDate ) ) / 1000000 ) ;
@@ -703,5 +645,6 @@ void HBManager::SetPosition( float pos )
( 1 - fStatus.fPosition ) /
( 1000000 * fStatus.fPosition ) );
fNeedUpdate = true;
+ fStatusLock->Unlock();
}
diff --git a/core/Manager.h b/core/Manager.h
index 8aa6cec3a..dc885e5f5 100644
--- a/core/Manager.h
+++ b/core/Manager.h
@@ -1,4 +1,4 @@
-/* $Id: Manager.h,v 1.27 2003/09/30 21:21:32 titer Exp $
+/* $Id: Manager.h,v 1.32 2003/10/08 22:20:36 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -13,7 +13,8 @@
class HBManager : public HBThread
{
public:
- HBManager( bool debug = false );
+ HBManager( bool debug = false,
+ int cpuCount = 0 );
~HBManager();
void DoWork();
@@ -29,17 +30,17 @@ class HBManager : public HBThread
uint8_t * GetPreview( HBTitle * title, uint32_t image );
/* Methods called by the working threads */
- int GetPid();
void Scanning( char * volume, int title );
void ScanDone( HBList * titleList );
void Done();
- void Error();
+ void Error( HBError error );
void SetPosition( float pos );
private:
void FixPictureSettings( HBTitle * title );
int fPid;
+ int fCPUCount;
/* Booleans used in DoWork() */
bool fStopScan;
@@ -51,8 +52,10 @@ class HBManager : public HBThread
HBScanner * fScanner;
/* Status infos */
+ HBLock * fStatusLock;
bool fNeedUpdate;
HBStatus fStatus;
+
HBTitle * fCurTitle;
HBAudio * fCurAudio1;
HBAudio * fCurAudio2;
diff --git a/core/Mp3Encoder.cpp b/core/Mp3Encoder.cpp
index b4e9fe860..06d96af29 100644
--- a/core/Mp3Encoder.cpp
+++ b/core/Mp3Encoder.cpp
@@ -1,4 +1,4 @@
-/* $Id: Mp3Encoder.cpp,v 1.7 2003/09/30 14:38:15 titer Exp $
+/* $Id: Mp3Encoder.cpp,v 1.13 2003/10/08 15:00:20 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -11,113 +11,153 @@
#include <lame/lame.h>
HBMp3Encoder::HBMp3Encoder( HBManager * manager, HBAudio * audio )
- : HBThread( "mp3encoder" )
{
- fManager = manager;
- fAudio = audio;
+ fManager = manager;
+ fAudio = audio;
+
+ fLock = new HBLock();
+ fUsed = false;
fRawBuffer = NULL;
fPosInBuffer = 0;
+ fSamplesNb = 0;
fLeftSamples = NULL;
fRightSamples = NULL;
fPosition = 0;
+ fInitDone = false;
+ fMp3Buffer = NULL;
}
-void HBMp3Encoder::DoWork()
+bool HBMp3Encoder::Work()
{
- /* Wait a first buffer so we are sure that
- fAudio->fInSampleRate (set the AC3 decoder) is not garbage */
- while( !fDie && !fAudio->fRawFifo->Size() )
+ if( !Lock() )
{
- Snooze( 5000 );
+ return false;
}
-
- if( fDie )
+
+ if( !fInitDone )
{
- return;
- }
+ /* Wait for a first buffer so we know fAudio->fInSampleRate
+ is correct */
+ if( !fAudio->fRawFifo->Size() )
+ {
+ Unlock();
+ return false;
+ }
+
+ /* The idea is to have exactly one mp3 frame (i.e. 1152 samples) by
+ output buffer. As we are resampling from fInSampleRate to
+ fOutSampleRate, we will give ( 1152 * fInSampleRate ) /
+ ( 2 * fOutSampleRate ) to libmp3lame so we are sure we will
+ never get more than 1 frame at a time */
+ fCount = ( 1152 * fAudio->fInSampleRate ) /
+ ( 2 * fAudio->fOutSampleRate );
+
+ /* Init libmp3lame */
+ fGlobalFlags = lame_init();
+ lame_set_in_samplerate( fGlobalFlags, fAudio->fInSampleRate );
+ lame_set_out_samplerate( fGlobalFlags, fAudio->fOutSampleRate );
+ lame_set_brate( fGlobalFlags, fAudio->fOutBitrate );
+
+ if( lame_init_params( fGlobalFlags ) == -1 )
+ {
+ Log( "HBMp3Encoder: lame_init_params() failed" );
+ fManager->Error( HB_ERROR_MP3_INIT );
+ return false;
+ }
- /* The idea is to have exactly one mp3 frame (i.e. 1152 samples) by
- output buffer. As we are resampling from fInSampleRate to
- fOutSampleRate, we will give ( 1152 * fInSampleRate ) /
- ( 2 * fOutSampleRate ) to libmp3lame so we are sure we will
- never get more than 1 frame at a time */
- uint32_t count = ( 1152 * fAudio->fInSampleRate ) /
- ( 2 * fAudio->fOutSampleRate );
-
- /* Init libmp3lame */
- lame_global_flags * globalFlags = lame_init();
- lame_set_in_samplerate( globalFlags, fAudio->fInSampleRate );
- lame_set_out_samplerate( globalFlags, fAudio->fOutSampleRate );
- lame_set_brate( globalFlags, fAudio->fOutBitrate );
-
- if( lame_init_params( globalFlags ) == -1 )
- {
- Log( "HBMp3Encoder::DoWork() : lame_init_params() failed" );
- fManager->Error();
- return;
- }
+ fLeftSamples = (float*) malloc( fCount * sizeof( float ) );
+ fRightSamples = (float*) malloc( fCount * sizeof( float ) );
- fLeftSamples = (float*) malloc( count * sizeof( float ) );
- fRightSamples = (float*) malloc( count * sizeof( float ) );
+ fInitDone = true;
+ }
- HBBuffer * mp3Buffer = new HBBuffer( LAME_MAXMP3BUFFER );
+ bool didSomething = false;
- int ret;
for( ;; )
{
- while( fSuspend )
+ if( fMp3Buffer )
{
- Snooze( 10000 );
+ if( fAudio->fMp3Fifo->Push( fMp3Buffer ) )
+ {
+ fMp3Buffer = NULL;
+ }
+ else
+ {
+ break;
+ }
}
-
+
/* Get new samples */
- if( !GetSamples( count ) )
+ if( !GetSamples() )
{
break;
}
- ret = lame_encode_buffer_float( globalFlags,
- fLeftSamples, fRightSamples,
- count, mp3Buffer->fData,
- mp3Buffer->fSize );
+ int ret;
+ fMp3Buffer = new HBBuffer( LAME_MAXMP3BUFFER );
+ ret = lame_encode_buffer_float( fGlobalFlags, fLeftSamples,
+ fRightSamples, fCount,
+ fMp3Buffer->fData,
+ fMp3Buffer->fSize );
if( ret < 0 )
{
/* Something wrong happened */
- Log( "HBMp3Encoder : lame_encode_buffer_float() failed (%d)", ret );
- fManager->Error();
- break;
+ Log( "HBMp3Encoder : lame_encode_buffer_float() failed "
+ "(%d)", ret );
+ fManager->Error( HB_ERROR_MP3_ENCODE );
+ return false;
}
else if( ret > 0 )
{
/* We got something, send it to the muxer */
- mp3Buffer->fSize = ret;
- mp3Buffer->fKeyFrame = true;
- mp3Buffer->fPosition = fPosition;
- Push( fAudio->fMp3Fifo, mp3Buffer );
- mp3Buffer = new HBBuffer( LAME_MAXMP3BUFFER );
+ fMp3Buffer->fSize = ret;
+ fMp3Buffer->fKeyFrame = true;
+ fMp3Buffer->fPosition = fPosition;
}
+ else
+ {
+ delete fMp3Buffer;
+ fMp3Buffer = NULL;
+ }
+ fSamplesNb = 0;
+
+ didSomething = true;
}
- /* Clean up */
- delete mp3Buffer;
- free( fLeftSamples );
- free( fRightSamples );
+ Unlock();
+ return didSomething;
+}
- lame_close( globalFlags );
+bool HBMp3Encoder::Lock()
+{
+ fLock->Lock();
+ if( fUsed )
+ {
+ fLock->Unlock();
+ return false;
+ }
+ fUsed = true;
+ fLock->Unlock();
+ return true;
}
-bool HBMp3Encoder::GetSamples( uint32_t count )
+void HBMp3Encoder::Unlock()
{
- uint32_t samplesNb = 0;
+ fLock->Lock();
+ fUsed = false;
+ fLock->Unlock();
+}
- while( samplesNb < count )
+bool HBMp3Encoder::GetSamples()
+{
+ while( fSamplesNb < fCount )
{
if( !fRawBuffer )
{
- if( !( fRawBuffer = Pop( fAudio->fRawFifo ) ) )
+ if( !( fRawBuffer = fAudio->fRawFifo->Pop() ) )
{
return false;
}
@@ -126,16 +166,16 @@ bool HBMp3Encoder::GetSamples( uint32_t count )
fPosition = fRawBuffer->fPosition;
}
- int willCopy = MIN( count - samplesNb, 6 * 256 - fPosInBuffer );
+ int willCopy = MIN( fCount - fSamplesNb, 6 * 256 - fPosInBuffer );
- memcpy( fLeftSamples + samplesNb,
+ memcpy( fLeftSamples + fSamplesNb,
(float*) fRawBuffer->fData + fPosInBuffer,
willCopy * sizeof( float ) );
- memcpy( fRightSamples + samplesNb,
+ memcpy( fRightSamples + fSamplesNb,
(float*) fRawBuffer->fData + 6 * 256 + fPosInBuffer,
willCopy * sizeof( float ) );
- samplesNb += willCopy;
+ fSamplesNb += willCopy;
fPosInBuffer += willCopy;
if( fPosInBuffer == 6 * 256 )
diff --git a/core/Mp3Encoder.h b/core/Mp3Encoder.h
index 67b8647d5..fb8348961 100644
--- a/core/Mp3Encoder.h
+++ b/core/Mp3Encoder.h
@@ -1,4 +1,4 @@
-/* $Id: Mp3Encoder.h,v 1.5 2003/09/30 14:38:15 titer Exp $
+/* $Id: Mp3Encoder.h,v 1.9 2003/10/07 22:48:31 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -8,27 +8,36 @@
#define HB_MP3_ENCODER_H
#include "Common.h"
-#include "Thread.h"
-class HBMp3Encoder : public HBThread
+class HBMp3Encoder
{
public:
HBMp3Encoder( HBManager * manager,
HBAudio * audio );
+ bool Work();
private:
- void DoWork();
- bool GetSamples( uint32_t count );
+ bool Lock();
+ void Unlock();
+ bool GetSamples();
HBManager * fManager;
HBAudio * fAudio;
+ HBLock * fLock;
+ bool fUsed;
+
HBBuffer * fRawBuffer;
uint32_t fPosInBuffer; /* in samples */
+ uint32_t fSamplesNb;
float * fLeftSamples;
float * fRightSamples;
float fPosition;
+ lame_global_flags * fGlobalFlags;
+ bool fInitDone;
+ HBBuffer * fMp3Buffer;
+ uint32_t fCount;
};
#endif
diff --git a/core/Mpeg2Decoder.cpp b/core/Mpeg2Decoder.cpp
index 1ba4945bc..3149931e8 100644
--- a/core/Mpeg2Decoder.cpp
+++ b/core/Mpeg2Decoder.cpp
@@ -1,4 +1,4 @@
-/* $Id: Mpeg2Decoder.cpp,v 1.14 2003/09/30 14:38:15 titer Exp $
+/* $Id: Mpeg2Decoder.cpp,v 1.21 2003/10/09 14:21:21 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -14,55 +14,91 @@ extern "C" {
#include <ffmpeg/avcodec.h>
HBMpeg2Decoder::HBMpeg2Decoder( HBManager * manager, HBTitle * title )
- : HBThread( "mpeg2decoder" )
{
- fManager = manager;
- fTitle = title;
+ fManager = manager;
+ fTitle = title;
+
+ fLock = new HBLock();
+ fUsed = false;
+
+ fPass = 42;
+ fRawBuffer = NULL;
+ fRawBufferList = new HBList();
+ fHandle = NULL;
}
-void HBMpeg2Decoder::DoWork()
+bool HBMpeg2Decoder::Work()
{
- if( !( fMpeg2Buffer = Pop( fTitle->fMpeg2Fifo ) ) )
+ fLock->Lock();
+ if( fUsed )
{
- return;
+ fLock->Unlock();
+ return true;
}
+ fUsed = true;
+ fLock->Unlock();
- fPass = fMpeg2Buffer->fPass;
- Init();
-
- do
+ bool didSomething = false;
+
+ for( ;; )
{
- while( fSuspend )
+ /* Push decoded buffers */
+ while( ( fRawBuffer =
+ (HBBuffer*) fRawBufferList->ItemAt( 0 ) ) )
+ {
+ if( fTitle->fRawFifo->Push( fRawBuffer ) )
+ {
+ fRawBufferList->RemoveItem( fRawBuffer );
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if( fRawBufferList->CountItems() )
{
- Snooze( 10000 );
+ break;
+ }
+
+ /* Get a new buffer to decode */
+ if( !( fMpeg2Buffer = fTitle->fMpeg2Fifo->Pop() ) )
+ {
+ break;
}
+ /* (Re)init if needed */
if( fMpeg2Buffer->fPass != fPass )
{
- Close();
fPass = fMpeg2Buffer->fPass;
Init();
}
+ /* Do the job */
DecodeBuffer();
+
+ didSomething = true;
}
- while( ( fMpeg2Buffer = Pop( fTitle->fMpeg2Fifo ) ) );
+
+ fLock->Lock();
+ fUsed = false;
+ fLock->Unlock();
+
+ return didSomething;
}
void HBMpeg2Decoder::Init()
{
+ if( fHandle )
+ {
+ mpeg2_close( fHandle );
+ }
+
fLateField = false;
- /* Init libmpeg2 */
fHandle = mpeg2_init();
}
-void HBMpeg2Decoder::Close()
-{
- /* Close libmpeg2 */
- mpeg2_close( fHandle );
-}
-
void HBMpeg2Decoder::DecodeBuffer()
{
const mpeg2_info_t * info = mpeg2_info( fHandle );
@@ -83,55 +119,52 @@ void HBMpeg2Decoder::DecodeBuffer()
else if( ( state == STATE_SLICE || state == STATE_END ) &&
info->display_fbuf )
{
- HBBuffer * rawBuffer = new HBBuffer( 3 * fTitle->fInWidth *
- fTitle->fInHeight / 2 );
+ fRawBuffer = new HBBuffer( 3 * fTitle->fInWidth *
+ fTitle->fInHeight / 2 );
/* TODO : make libmpeg2 write directly in our buffer */
- memcpy( rawBuffer->fData,
+ memcpy( fRawBuffer->fData,
info->display_fbuf->buf[0],
fTitle->fInWidth * fTitle->fInHeight );
- memcpy( rawBuffer->fData + fTitle->fInWidth *
+ memcpy( fRawBuffer->fData + fTitle->fInWidth *
fTitle->fInHeight,
info->display_fbuf->buf[1],
fTitle->fInWidth * fTitle->fInHeight / 4 );
- memcpy( rawBuffer->fData + fTitle->fInWidth *
+ memcpy( fRawBuffer->fData + fTitle->fInWidth *
fTitle->fInHeight + fTitle->fInWidth *
fTitle->fInHeight / 4,
info->display_fbuf->buf[2],
fTitle->fInWidth * fTitle->fInHeight / 4 );
- rawBuffer->fPosition = fMpeg2Buffer->fPosition;
- rawBuffer->fPass = fPass;
+ fRawBuffer->fPosition = fMpeg2Buffer->fPosition;
+ fRawBuffer->fPass = fMpeg2Buffer->fPass;
+
+ fRawBufferList->AddItem( fRawBuffer );
/* NTSC pulldown kludge */
if( info->display_picture->nb_fields == 3 )
{
if( fLateField )
{
- HBBuffer * buffer =
- new HBBuffer( rawBuffer->fSize );
- buffer->fPosition = rawBuffer->fPosition;
- buffer->fPass = rawBuffer->fPass;
- memcpy( buffer->fData, rawBuffer->fData,
- buffer->fSize );
- Push( fTitle->fRawFifo, buffer );
+ HBBuffer * pulldownBuffer;
+ pulldownBuffer = new HBBuffer( fRawBuffer->fSize );
+ pulldownBuffer->fPosition = fRawBuffer->fPosition;
+ pulldownBuffer->fPass = fRawBuffer->fPass;
+ memcpy( pulldownBuffer->fData, fRawBuffer->fData,
+ pulldownBuffer->fSize );
+ fRawBufferList->AddItem( pulldownBuffer );
}
fLateField = !fLateField;
}
-
- /* Send it to the encoder */
- if( !( Push( fTitle->fRawFifo, rawBuffer ) ) )
- {
- break;
- }
}
else if( state == STATE_INVALID )
{
/* Shouldn't happen on a DVD */
- Log( "HBMpeg2Decoder : STATE_INVALID" );
+ Log( "HBMpeg2Decoder: STATE_INVALID" );
}
}
delete fMpeg2Buffer;
+ fMpeg2Buffer = NULL;
}
diff --git a/core/Mpeg2Decoder.h b/core/Mpeg2Decoder.h
index 2e1a46b3d..9d1f27f8f 100644
--- a/core/Mpeg2Decoder.h
+++ b/core/Mpeg2Decoder.h
@@ -1,4 +1,4 @@
-/* $Id: Mpeg2Decoder.h,v 1.10 2003/09/30 14:38:15 titer Exp $
+/* $Id: Mpeg2Decoder.h,v 1.15 2003/10/09 14:21:21 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -8,25 +8,28 @@
#define HB_MPEG2_DECODER_H
#include "Common.h"
-#include "Thread.h"
-class HBMpeg2Decoder : public HBThread
+class HBMpeg2Decoder
{
public:
HBMpeg2Decoder( HBManager * manager,
HBTitle * title );
+ bool Work();
private:
- void DoWork();
void Init();
- void Close();
void DecodeBuffer();
HBManager * fManager;
HBTitle * fTitle;
+ HBLock * fLock;
+ bool fUsed;
+
uint32_t fPass;
HBBuffer * fMpeg2Buffer;
+ HBBuffer * fRawBuffer;
+ HBList * fRawBufferList;
mpeg2dec_t * fHandle;
bool fLateField;
};
diff --git a/core/Mpeg4Encoder.cpp b/core/Mpeg4Encoder.cpp
index 42fb38b9e..4ef0a4c3f 100644
--- a/core/Mpeg4Encoder.cpp
+++ b/core/Mpeg4Encoder.cpp
@@ -1,4 +1,4 @@
-/* $Id: Mpeg4Encoder.cpp,v 1.15 2003/09/30 14:38:15 titer Exp $
+/* $Id: Mpeg4Encoder.cpp,v 1.23 2003/10/09 13:24:48 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -11,49 +11,97 @@
#include <ffmpeg/avcodec.h>
HBMpeg4Encoder::HBMpeg4Encoder( HBManager * manager, HBTitle * title )
- : HBThread( "mpeg4encoder" )
{
fManager = manager;
fTitle = title;
+
+ fLock = new HBLock();
+ fUsed = false;
+
+ fPass = 42;
+ fMpeg4Buffer = NULL;
+ fFile = NULL;
+ fFrame = avcodec_alloc_frame();
+ fLog = NULL;
}
-void HBMpeg4Encoder::DoWork()
+bool HBMpeg4Encoder::Work()
{
- if( !( fResizedBuffer = Pop( fTitle->fResizedFifo ) ) )
+ if( !Lock() )
{
- return;
+ return false;
}
- fPass = fResizedBuffer->fPass;
- Init();
+ bool didSomething = false;
- do
+ for( ;; )
{
- while( fSuspend )
+ if( fMpeg4Buffer )
{
- Snooze( 10000 );
+ if( fTitle->fMpeg4Fifo->Push( fMpeg4Buffer ) )
+ {
+ fMpeg4Buffer = NULL;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if( !( fResizedBuffer = fTitle->fResizedFifo->Pop() ) )
+ {
+ break;
}
if( fResizedBuffer->fPass != fPass )
{
- Close();
fPass = fResizedBuffer->fPass;
Init();
}
fManager->SetPosition( fResizedBuffer->fPosition );
EncodeBuffer();
+
+ didSomething = true;
+ }
+
+ Unlock();
+ return didSomething;
+}
+
+bool HBMpeg4Encoder::Lock()
+{
+ fLock->Lock();
+ if( fUsed )
+ {
+ fLock->Unlock();
+ return false;
}
- while( ( fResizedBuffer = Pop( fTitle->fResizedFifo ) ) );
+ fUsed = true;
+ fLock->Unlock();
+ return true;
+}
+
+void HBMpeg4Encoder::Unlock()
+{
+ fLock->Lock();
+ fUsed = false;
+ fLock->Unlock();
}
void HBMpeg4Encoder::Init()
{
+ /* Clean up if needed */
+ if( fFile )
+ {
+ fclose( fFile );
+ }
+
AVCodec * codec = avcodec_find_encoder( CODEC_ID_MPEG4 );
if( !codec )
{
Log( "HBMpeg4Encoder: avcodec_find_encoder() failed" );
- fManager->Error();
+ fManager->Error( HB_ERROR_MPEG4_INIT );
return;
}
@@ -94,19 +142,9 @@ void HBMpeg4Encoder::Init()
if( avcodec_open( fContext, codec ) < 0 )
{
Log( "HBMpeg4Encoder: avcodec_open() failed" );
- fManager->Error();
+ fManager->Error( HB_ERROR_MPEG4_INIT );
return;
}
-
- fFrame = avcodec_alloc_frame();
-}
-
-void HBMpeg4Encoder::Close()
-{
- if( fPass == 1 )
- {
- fclose( fFile );
- }
}
void HBMpeg4Encoder::EncodeBuffer()
@@ -120,31 +158,27 @@ void HBMpeg4Encoder::EncodeBuffer()
fFrame->linesize[1] = fTitle->fOutWidth / 2;
fFrame->linesize[2] = fTitle->fOutWidth / 2;
- HBBuffer * mpeg4Buffer;
- mpeg4Buffer = new HBBuffer( 3 * fTitle->fOutWidth *
+ fMpeg4Buffer = new HBBuffer( 3 * fTitle->fOutWidth *
fTitle->fOutHeight / 2 );
/* Should be really too much... */
- mpeg4Buffer->fPosition = fResizedBuffer->fPosition;
- mpeg4Buffer->fSize =
- avcodec_encode_video( fContext, mpeg4Buffer->fData,
- mpeg4Buffer->fAllocSize, fFrame );
- mpeg4Buffer->fKeyFrame = ( fContext->coded_frame->key_frame != 0 );
-
- delete fResizedBuffer;
+ fMpeg4Buffer->fPosition = fResizedBuffer->fPosition;
+ fMpeg4Buffer->fSize =
+ avcodec_encode_video( fContext, fMpeg4Buffer->fData,
+ fMpeg4Buffer->fAllocSize, fFrame );
+ fMpeg4Buffer->fKeyFrame = ( fContext->coded_frame->key_frame != 0 );
- if( fPass == 1 )
+ if( fResizedBuffer->fPass == 1 )
{
if( fContext->stats_out )
{
fprintf( fFile, "%s", fContext->stats_out );
}
- delete mpeg4Buffer;
- }
- else
- {
- /* Mux it */
- Push( fTitle->fMpeg4Fifo, mpeg4Buffer );
+ delete fMpeg4Buffer;
+ fMpeg4Buffer = NULL;
}
+
+ delete fResizedBuffer;
+ fResizedBuffer = NULL;
}
diff --git a/core/Mpeg4Encoder.h b/core/Mpeg4Encoder.h
index 1bdb29434..3d20f315a 100644
--- a/core/Mpeg4Encoder.h
+++ b/core/Mpeg4Encoder.h
@@ -1,4 +1,4 @@
-/* $Id: Mpeg4Encoder.h,v 1.8 2003/09/30 14:38:15 titer Exp $
+/* $Id: Mpeg4Encoder.h,v 1.11 2003/10/08 11:56:40 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -8,29 +8,34 @@
#define HB_MPEG4_ENCODER_H
#include "Common.h"
-#include "Thread.h"
-class HBMpeg4Encoder : public HBThread
+class HBMpeg4Encoder
{
public:
HBMpeg4Encoder( HBManager * manager,
HBTitle * title );
+ bool Work();
private:
- void DoWork();
+ bool Lock();
+ void Unlock();
+
void Init();
- void Close();
void EncodeBuffer();
HBManager * fManager;
HBTitle * fTitle;
+ HBLock * fLock;
+ bool fUsed;
+
uint32_t fPass;
HBBuffer * fResizedBuffer;
AVCodecContext * fContext;
AVFrame * fFrame;
FILE * fFile;
char * fLog;
+ HBBuffer * fMpeg4Buffer;
};
#endif
diff --git a/core/MpegDemux.cpp b/core/MpegDemux.cpp
index d3fd6b089..c01647a3a 100644
--- a/core/MpegDemux.cpp
+++ b/core/MpegDemux.cpp
@@ -1,4 +1,4 @@
-/* $Id: MpegDemux.cpp,v 1.10 2003/10/04 12:12:48 titer Exp $
+/* $Id: MpegDemux.cpp,v 1.18 2003/10/13 15:14:01 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -14,146 +14,176 @@ extern "C" {
HBMpegDemux::HBMpegDemux( HBManager * manager, HBTitle * title,
HBAudio * audio1, HBAudio * audio2 )
- : HBThread( "mpegdemux" )
{
- fManager = manager;
- fTitle = title;
- fAudio1 = audio1;
- fAudio2 = audio2;
+ fManager = manager;
+ fTitle = title;
+ fAudio1 = audio1;
+ fAudio2 = audio2;
- fPSBuffer = NULL;
- fESBuffer = NULL;
- fESBufferList = NULL;
+ fLock = new HBLock();
+ fUsed = false;
+
+ fPSBuffer = NULL;
+ fESBuffer = NULL;
+ fESBufferList = NULL;
fFirstVideoPTS = -1;
fFirstAudio1PTS = -1;
fFirstAudio2PTS = -1;
}
-void HBMpegDemux::DoWork()
+HBMpegDemux::~HBMpegDemux()
{
- for( ;; )
+ /* Free memory */
+ if( fESBufferList )
{
- while( fSuspend )
- {
- Snooze( 10000 );
- }
-
- /* Get a PS packet */
- if( !( fPSBuffer = Pop( fTitle->fPSFifo ) ) )
+ while( ( fESBuffer = (HBBuffer*) fESBufferList->ItemAt( 0 ) ) )
{
- break;
+ fESBufferList->RemoveItem( fESBuffer );
+ delete fESBuffer;
}
+ }
+ delete fLock;
+}
- /* Get the ES data in it */
- PStoES( fPSBuffer, &fESBufferList );
-
- if( !fESBufferList )
- {
- continue;
- }
+bool HBMpegDemux::Work()
+{
+ if( !Lock() )
+ {
+ return false;
+ }
+
+ bool didSomething = false;
- while( ( fESBuffer = (HBBuffer*) fESBufferList->ItemAt( 0 ) ) )
+ for( ;; )
+ {
+ /* If we have buffers waiting, try to push them */
+ if( fESBufferList )
{
- fESBufferList->RemoveItem( fESBuffer );
-
- if( fESBuffer->fPass == 1 && fESBuffer->fStreamId != 0xE0 )
+ for( uint32_t i = 0; i < fESBufferList->CountItems(); )
{
- delete fESBuffer;
- continue;
- }
+ fESBuffer = (HBBuffer*) fESBufferList->ItemAt( i );
+
+ if( fESBuffer->fPass == 1 && fESBuffer->fStreamId != 0xE0 )
+ {
+ fESBufferList->RemoveItem( fESBuffer );
+ delete fESBuffer;
+ continue;
+ }
- /* Look for a decoder for this ES */
- if( fESBuffer->fStreamId == 0xE0 )
- {
- if( fFirstVideoPTS < 0 )
+ /* Look for a decoder for this ES */
+
+ if( fESBuffer->fStreamId == 0xE0 )
{
- fFirstVideoPTS = fESBuffer->fPTS;
+ if( fFirstVideoPTS < 0 )
+ {
+ fFirstVideoPTS = fESBuffer->fPTS;
+ Log( "HBMpegDemux: got first 0xE0 packet (%lld)",
+ fFirstVideoPTS );
+ }
+ if( fTitle->fMpeg2Fifo->Push( fESBuffer ) )
+ {
+ fESBufferList->RemoveItem( fESBuffer );
+ }
+ else
+ {
+ i++;
+ }
}
- Push( fTitle->fMpeg2Fifo, fESBuffer );
- }
- else if( fAudio1 &&
- fESBuffer->fStreamId == fAudio1->fId )
- {
- /* If the audio track starts later than the video,
- repeat the first frame as long as needed */
- if( fFirstAudio1PTS < 0 )
+ else if( fAudio1 &&
+ fESBuffer->fStreamId == fAudio1->fId )
{
- fFirstAudio1PTS = fESBuffer->fPTS;
+ if( fFirstAudio1PTS < 0 )
+ {
+ fFirstAudio1PTS = fESBuffer->fPTS;
+ Log( "HBMpegDemux: got first 0x%x packet (%lld)",
+ fAudio1->fId, fFirstAudio1PTS );
- if( fFirstAudio1PTS > fFirstVideoPTS )
+ fAudio1->fDelay =
+ ( fFirstAudio1PTS - fFirstVideoPTS ) / 90;
+ }
+ if( fAudio1->fAc3Fifo->Push( fESBuffer ) )
+ {
+ fESBufferList->RemoveItem( fESBuffer );
+ }
+ else
{
- Log( "HBMpegDemux::DoWork() : audio track %x "
- "is late (%lld)", fAudio1->fId,
- fFirstAudio1PTS - fFirstVideoPTS );
- InsertSilence( fFirstAudio1PTS - fFirstVideoPTS,
- fAudio1->fAc3Fifo,
- fESBuffer );
+ i++;
}
}
- Push( fAudio1->fAc3Fifo, fESBuffer );
- }
- else if( fAudio2 &&
- fESBuffer->fStreamId == fAudio2->fId )
- {
- if( fFirstAudio2PTS < 0 )
+ else if( fAudio2 &&
+ fESBuffer->fStreamId == fAudio2->fId )
{
- fFirstAudio2PTS = fESBuffer->fPTS;
+ if( fFirstAudio2PTS < 0 )
+ {
+ fFirstAudio2PTS = fESBuffer->fPTS;
+ Log( "HBMpegDemux: got first 0x%x packet (%lld)",
+ fAudio2->fId, fFirstAudio2PTS );
- if( fFirstAudio2PTS > fFirstVideoPTS )
+ fAudio2->fDelay =
+ ( fFirstAudio2PTS - fFirstVideoPTS ) / 90;
+ }
+ if( fAudio2->fAc3Fifo->Push( fESBuffer ) )
{
- Log( "HBMpegDemux::DoWork() : audio track %x "
- "is late (%lld)", fAudio2->fId,
- fFirstAudio2PTS - fFirstVideoPTS );
- InsertSilence( fFirstAudio2PTS - fFirstVideoPTS,
- fAudio2->fAc3Fifo,
- fESBuffer );
+ fESBufferList->RemoveItem( fESBuffer );
}
+ else
+ {
+ i++;
+ }
+ }
+ else
+ {
+ fESBufferList->RemoveItem( fESBuffer );
+ delete fESBuffer;
}
- Push( fAudio2->fAc3Fifo, fESBuffer );
+ }
+
+ if( !fESBufferList->CountItems() )
+ {
+ delete fESBufferList;
+ fESBufferList = NULL;
}
else
{
- delete fESBuffer;
+ break;
}
}
- delete fESBufferList;
- }
-}
-void HBMpegDemux::InsertSilence( int64_t time, HBFifo * fifo,
- HBBuffer * buffer )
-{
- int flags = 0;
- int sampleRate = 0;
- int bitrate = 0;
- int frameSize = a52_syncinfo( buffer->fData, &flags,
- &sampleRate, &bitrate );
-
- if( !frameSize )
- {
- Log( "HBMpegDemux::InsertSilence() : a52_syncinfo() failed" );
- return;
- }
+ /* Get a PS packet */
+ if( !( fPSBuffer = fTitle->fPSFifo->Pop() ) )
+ {
+ break;
+ }
- uint32_t frames = ( ( sampleRate * time / 90000 ) + ( 3 * 256 ) )
- / ( 6 * 256 );
+ /* Get the ES data in it */
+ PStoES( fPSBuffer, &fESBufferList );
- if( !frames )
- {
- return;
+ didSomething = true;
}
- Log( "HBMpegDemux::InsertSilence() : adding %d frames", frames );
+ Unlock();
+ return didSomething;
+}
- HBBuffer * buffer2;
- for( uint32_t i = 0; i < frames; i++ )
+bool HBMpegDemux::Lock()
+{
+ fLock->Lock();
+ if( fUsed )
{
- buffer2 = new HBBuffer( frameSize );
- buffer2->fPosition = buffer->fPosition;
- memcpy( buffer2->fData, buffer->fData, frameSize );
- Push( fifo, buffer2 );
- }
+ fLock->Unlock();
+ return false;
+ }
+ fUsed = true;
+ fLock->Unlock();
+ return true;
+}
+
+void HBMpegDemux::Unlock()
+{
+ fLock->Lock();
+ fUsed = false;
+ fLock->Unlock();
}
bool PStoES( HBBuffer * psBuffer, HBList ** _esBufferList )
diff --git a/core/MpegDemux.h b/core/MpegDemux.h
index ef5b1b3d9..187a08de9 100644
--- a/core/MpegDemux.h
+++ b/core/MpegDemux.h
@@ -1,4 +1,4 @@
-/* $Id: MpegDemux.h,v 1.6 2003/10/04 12:12:48 titer Exp $
+/* $Id: MpegDemux.h,v 1.11 2003/10/09 13:24:48 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -8,26 +8,29 @@
#define HB_MPEG_DEMUX_H
#include "Common.h"
-#include "Thread.h"
bool PStoES( HBBuffer * psBuffer, HBList ** _esBufferList );
-class HBMpegDemux : public HBThread
+class HBMpegDemux
{
public:
- HBMpegDemux( HBManager * manager, HBTitle * title,
- HBAudio * audio1, HBAudio * audio2 );
+ HBMpegDemux( HBManager * manager, HBTitle * title,
+ HBAudio * audio1, HBAudio * audio2 );
+ ~HBMpegDemux();
+ bool Work();
private:
- void DoWork();
- void InsertSilence( int64_t time, HBFifo * fifo,
- HBBuffer * buffer );
+ bool Lock();
+ void Unlock();
HBManager * fManager;
HBTitle * fTitle;
HBAudio * fAudio1;
HBAudio * fAudio2;
+ HBLock * fLock;
+ bool fUsed;
+
HBBuffer * fPSBuffer;
HBBuffer * fESBuffer;
HBList * fESBufferList;
diff --git a/core/Resizer.cpp b/core/Resizer.cpp
index e3cae3986..0b9c794db 100644
--- a/core/Resizer.cpp
+++ b/core/Resizer.cpp
@@ -1,4 +1,4 @@
-/* $Id: Resizer.cpp,v 1.3 2003/09/30 14:38:15 titer Exp $
+/* $Id: Resizer.cpp,v 1.8 2003/10/09 13:24:48 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -11,79 +11,131 @@
#include <ffmpeg/avcodec.h>
HBResizer::HBResizer( HBManager * manager, HBTitle * title )
- : HBThread( "resizer" )
{
- fManager = manager;
- fTitle = title;
-}
+ fManager = manager;
+ fTitle = title;
+
+ /* Lock */
+ fLock = new HBLock();
+ fUsed = false;
-void HBResizer::DoWork()
-{
/* Init libavcodec */
- ImgReSampleContext * resampleContext =
+ fResampleContext =
img_resample_full_init( fTitle->fOutWidth, fTitle->fOutHeight,
fTitle->fInWidth, fTitle->fInHeight,
fTitle->fTopCrop, fTitle->fBottomCrop,
fTitle->fLeftCrop, fTitle->fRightCrop );
/* Buffers & pictures */
- HBBuffer * rawBuffer, * deinterlacedBuffer, * resizedBuffer;
- AVPicture rawPicture, deinterlacedPicture, resizedPicture;
-
- deinterlacedBuffer = new HBBuffer( 3 * fTitle->fInWidth *
- fTitle->fInHeight / 2 );
- avpicture_fill( &deinterlacedPicture, deinterlacedBuffer->fData,
+ fRawBuffer = NULL;
+ fDeinterlacedBuffer = new HBBuffer( 3 * fTitle->fInWidth *
+ fTitle->fInHeight / 2 );
+ fResizedBuffer = NULL;
+ fRawPicture = (AVPicture*) malloc( sizeof( AVPicture ) );
+ fDeinterlacedPicture = (AVPicture*) malloc( sizeof( AVPicture ) );
+ fResizedPicture = (AVPicture*) malloc( sizeof( AVPicture ) );
+
+ avpicture_fill( fDeinterlacedPicture, fDeinterlacedBuffer->fData,
PIX_FMT_YUV420P, fTitle->fInWidth,
fTitle->fInHeight );
+}
+
+HBResizer::~HBResizer()
+{
+ /* Free memory */
+ free( fResizedPicture );
+ free( fDeinterlacedPicture );
+ free( fRawPicture );
+ if( fResizedBuffer ) delete fResizedBuffer;
+ delete fDeinterlacedBuffer;
+ img_resample_close( fResampleContext );
+ delete fLock;
+}
+bool HBResizer::Work()
+{
+ if( !Lock() )
+ {
+ return false;
+ }
+
+ bool didSomething = false;
+
for( ;; )
{
- while( fSuspend )
+ /* Push the latest resized buffer */
+ if( fResizedBuffer )
{
- Snooze( 10000 );
+ if( fTitle->fResizedFifo->Push( fResizedBuffer ) )
+ {
+ fResizedBuffer = NULL;
+ }
+ else
+ {
+ break;
+ }
}
-
- if( !( rawBuffer = Pop( fTitle->fRawFifo ) ) )
+
+ /* Get a new raw picture */
+ if( !( fRawBuffer = fTitle->fRawFifo->Pop() ) )
{
break;
}
- avpicture_fill( &rawPicture, rawBuffer->fData,
+ /* Do the job */
+ avpicture_fill( fRawPicture, fRawBuffer->fData,
PIX_FMT_YUV420P, fTitle->fInWidth,
fTitle->fInHeight );
- resizedBuffer = new HBBuffer( 3 * fTitle->fOutWidth *
+ fResizedBuffer = new HBBuffer( 3 * fTitle->fOutWidth *
fTitle->fOutHeight / 2 );
- resizedBuffer->fPosition = rawBuffer->fPosition;
- resizedBuffer->fPass = rawBuffer->fPass;
- avpicture_fill( &resizedPicture, resizedBuffer->fData,
+ fResizedBuffer->fPosition = fRawBuffer->fPosition;
+ fResizedBuffer->fPass = fRawBuffer->fPass;
+ avpicture_fill( fResizedPicture, fResizedBuffer->fData,
PIX_FMT_YUV420P, fTitle->fOutWidth,
fTitle->fOutHeight );
-
if( fTitle->fDeinterlace )
{
- avpicture_deinterlace( &deinterlacedPicture, &rawPicture,
+ avpicture_deinterlace( fDeinterlacedPicture, fRawPicture,
PIX_FMT_YUV420P,
fTitle->fInWidth,
fTitle->fInHeight );
- img_resample( resampleContext, &resizedPicture,
- &deinterlacedPicture );
+ img_resample( fResampleContext, fResizedPicture,
+ fDeinterlacedPicture );
}
else
{
- img_resample( resampleContext, &resizedPicture,
- &rawPicture );
+ img_resample( fResampleContext, fResizedPicture,
+ fRawPicture );
}
+ delete fRawBuffer;
+ fRawBuffer = NULL;
- Push( fTitle->fResizedFifo, resizedBuffer );
- delete rawBuffer;
+ didSomething = true;
}
- /* Free memory */
- delete deinterlacedBuffer;
+ Unlock();
+ return didSomething;
+}
- /* Close libavcodec */
- img_resample_close( resampleContext );
+bool HBResizer::Lock()
+{
+ fLock->Lock();
+ if( fUsed )
+ {
+ fLock->Unlock();
+ return false;
+ }
+ fUsed = true;
+ fLock->Unlock();
+ return true;
+}
+
+void HBResizer::Unlock()
+{
+ fLock->Lock();
+ fUsed = false;
+ fLock->Unlock();
}
diff --git a/core/Resizer.h b/core/Resizer.h
index 1fdde85d3..f6d4a4568 100644
--- a/core/Resizer.h
+++ b/core/Resizer.h
@@ -1,4 +1,4 @@
-/* $Id: Resizer.h,v 1.2 2003/09/30 14:38:15 titer Exp $
+/* $Id: Resizer.h,v 1.5 2003/10/07 22:48:31 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -8,18 +8,31 @@
#define HB_RESIZER_H
#include "Common.h"
-#include "Thread.h"
-class HBResizer : public HBThread
+class HBResizer
{
public:
HBResizer( HBManager * manager, HBTitle * title );
+ ~HBResizer();
+ bool Work();
private:
- void DoWork();
-
+ bool Lock();
+ void Unlock();
+
HBManager * fManager;
HBTitle * fTitle;
+
+ HBLock * fLock;
+ bool fUsed;
+
+ ImgReSampleContext * fResampleContext;
+ HBBuffer * fRawBuffer;
+ HBBuffer * fDeinterlacedBuffer;
+ HBBuffer * fResizedBuffer;
+ AVPicture * fRawPicture;
+ AVPicture * fDeinterlacedPicture;
+ AVPicture * fResizedPicture;
};
#endif
diff --git a/core/Scanner.cpp b/core/Scanner.cpp
index 575b25573..44ff6be3a 100644
--- a/core/Scanner.cpp
+++ b/core/Scanner.cpp
@@ -1,4 +1,4 @@
-/* $Id: Scanner.cpp,v 1.18 2003/10/04 12:12:48 titer Exp $
+/* $Id: Scanner.cpp,v 1.23 2003/10/13 14:12:18 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -20,21 +20,23 @@ extern "C" {
}
HBScanner::HBScanner( HBManager * manager, char * device )
- : HBThread( "scanner" )
+ : HBThread( "scanner", HB_NORMAL_PRIORITY )
{
fManager = manager;
fDevice = strdup( device );
+
+ Run();
}
void HBScanner::DoWork()
{
- Log( "HBScanner::DoWork() : opening device %s", fDevice );
+ Log( "HBScanner: opening device %s", fDevice );
dvdplay_ptr vmg;
vmg = dvdplay_open( fDevice, NULL, NULL );
if( !vmg )
{
- Log( "HBScanner::DoWork() : dvdplay_open() failed (%s)",
+ Log( "HBScanner: dvdplay_open() failed (%s)",
fDevice );
fManager->ScanDone( NULL );
return;
@@ -50,7 +52,7 @@ void HBScanner::DoWork()
break;
}
- Log( "HBScanner::DoWork() : scanning title %d", i + 1 );
+ Log( "HBScanner: scanning title %d", i + 1 );
fManager->Scanning( fDevice, i + 1 );
title = new HBTitle( fDevice, i + 1 );
@@ -61,12 +63,12 @@ void HBScanner::DoWork()
}
else
{
- Log( "HBScanner::DoWork() : ignoring title %d", i + 1 );
+ Log( "HBScanner: ignoring title %d", i + 1 );
delete title;
}
}
- Log( "HBScanner::DoWork() : closing device %s", fDevice );
+ Log( "HBScanner: closing device %s", fDevice );
dvdplay_close( vmg );
fManager->ScanDone( titleList );
@@ -78,7 +80,7 @@ bool HBScanner::ScanTitle( HBTitle * title, dvdplay_ptr vmg )
/* Length */
title->fLength = dvdplay_title_time( vmg );
- Log( "HBScanner::ScanTitle() : title length is %lld seconds",
+ Log( "HBScanner::ScanTitle: title length is %lld seconds",
title->fLength );
/* Discard titles under 10 seconds */
@@ -101,20 +103,46 @@ bool HBScanner::ScanTitle( HBTitle * title, dvdplay_ptr vmg )
}
int id = dvdplay_audio_id( vmg, i );
- if( id > 0 )
+
+ if( id < 1 )
{
- if( ( id & 0xFF ) != 0xBD )
+ continue;
+ }
+
+ if( ( id & 0xFF ) != 0xBD )
+ {
+ Log( "HBScanner::ScanTitle: non-AC3 audio track "
+ "detected, ignoring" );
+ continue;
+ }
+
+ /* Check if we don't already found an track with the same id */
+ audio = NULL;
+ for( uint32_t j = 0; j < title->fAudioList->CountItems(); j++ )
+ {
+ audio = (HBAudio*) title->fAudioList->ItemAt( j );
+ if( (uint32_t) id == audio->fId )
+ {
+ break;
+ }
+ else
{
- Log( "HBScanner::ScanTitle() : non-AC3 audio track "
- "detected, ignoring" );
- continue;
+ audio = NULL;
}
- attr = dvdplay_audio_attr( vmg, i );
- audio = new HBAudio( id, LanguageForCode( attr->lang_code ) );
- Log( "HBScanner::ScanTitle() : new language (%x, %s)",
- id, audio->fDescription );
- title->fAudioList->AddItem( audio );
}
+
+ if( audio )
+ {
+ Log( "HBScanner::ScanTitle: discarding duplicate track %x",
+ id );
+ continue;
+ }
+
+ attr = dvdplay_audio_attr( vmg, i );
+ audio = new HBAudio( id, LanguageForCode( attr->lang_code ) );
+ Log( "HBScanner::ScanTitle: new language (%x, %s)",
+ id, audio->fDescription );
+ title->fAudioList->AddItem( audio );
}
/* Discard titles with no audio tracks */
@@ -206,7 +234,7 @@ bool HBScanner::DecodeFrame( HBTitle * title, dvdplay_ptr vmg, int i )
if( dvdplay_read( vmg, psBuffer->fData, 1 ) != 1 ||
!PStoES( psBuffer, &esBufferList ) )
{
- Log( "HBScanner::DecodeFrame : failed to get "
+ Log( "HBScanner::DecodeFrame: failed to get "
"a valid PS packet" );
mpeg2_close( handle );
fclose( file );
diff --git a/core/Thread.cpp b/core/Thread.cpp
index 43f058cad..8f7e6c971 100644
--- a/core/Thread.cpp
+++ b/core/Thread.cpp
@@ -1,4 +1,4 @@
-/* $Id: Thread.cpp,v 1.19 2003/10/01 21:17:17 titer Exp $
+/* $Id: Thread.cpp,v 1.23 2003/10/09 23:33:36 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -34,61 +34,35 @@ HBThread::~HBThread()
pthread_join( fThread, NULL );
#endif
- Log( "Thread %d stopped (\"%s\")", fThread, fName );
+ Log( "HBThread: thread %d stopped (\"%s\")", fThread, fName );
free( fName );
}
-void HBThread::Run()
+void HBThread::Suspend()
{
-#if defined( SYS_BEOS )
- fThread = spawn_thread( (int32 (*)(void *)) ThreadFunc,
- fName, fPriority, this );
- resume_thread( fThread );
-#elif defined( SYS_MACOSX ) || defined( SYS_LINUX )
- pthread_create( &fThread, NULL,
- (void * (*)(void *)) ThreadFunc, this );
-#if 0
-#if defined( SYS_MACOSX )
- int policy;
- struct sched_param param;
- memset( &param, 0, sizeof( struct sched_param ) );
- if( fPriority < 0 )
- {
- param.sched_priority = (-1) * fPriority;
- policy = SCHED_OTHER;
- }
- else
- {
- param.sched_priority = fPriority;
- policy = SCHED_RR;
- }
- if ( pthread_setschedparam( fThread, policy, &param ) )
- {
- Log( "HBThread::Run : couldn't set thread priority" );
- }
-#endif
-#endif
-#endif
-
- Log( "Thread %d started (\"%s\")", fThread, fName );
+ fSuspend = true;
}
-void HBThread::Stop()
+void HBThread::Resume()
{
- Log( "Stopping thread %d (\"%s\")", fThread, fName );
-
- fDie = true;
fSuspend = false;
}
-void HBThread::Suspend()
+int HBThread::GetPid()
{
- fSuspend = true;
+ return fPid;
}
-void HBThread::Resume()
+void HBThread::Run()
{
- fSuspend = false;
+#if defined( SYS_BEOS )
+ fThread = spawn_thread( (int32 (*)(void *)) ThreadFunc,
+ fName, fPriority, this );
+ resume_thread( fThread );
+#elif defined( SYS_MACOSX ) || defined( SYS_LINUX )
+ pthread_create( &fThread, NULL,
+ (void * (*)(void *)) ThreadFunc, this );
+#endif
}
bool HBThread::Push( HBFifo * fifo, HBBuffer * buffer )
@@ -126,6 +100,21 @@ HBBuffer * HBThread::Pop( HBFifo * fifo )
void HBThread::ThreadFunc( HBThread * _this )
{
+#if defined( SYS_MACOSX )
+ struct sched_param param;
+ memset( &param, 0, sizeof( struct sched_param ) );
+ param.sched_priority = _this->fPriority;
+ if ( pthread_setschedparam( _this->fThread, SCHED_OTHER, &param ) )
+ {
+ Log( "HBThread: couldn't set thread priority" );
+ }
+#endif
+
+ _this->fPid = (int) getpid();
+
+ Log( "HBThread: thread %d started (\"%s\")",
+ _this->fThread, _this->fName );
+
_this->DoWork();
}
diff --git a/core/Thread.h b/core/Thread.h
index 6afd59f53..0a09fabc9 100644
--- a/core/Thread.h
+++ b/core/Thread.h
@@ -1,4 +1,4 @@
-/* $Id: Thread.h,v 1.16 2003/10/01 21:17:17 titer Exp $
+/* $Id: Thread.h,v 1.19 2003/10/09 16:03:51 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -13,8 +13,8 @@
# define HB_LOW_PRIORITY 5
# define HB_NORMAL_PRIORITY 10
#elif defined( SYS_MACOSX )
-# define HB_LOW_PRIORITY (-47)
-# define HB_NORMAL_PRIORITY (-47) /* FIXME */
+# define HB_LOW_PRIORITY 0
+# define HB_NORMAL_PRIORITY 31
#elif defined( SYS_LINUX )
/* Actually unused */
# define HB_LOW_PRIORITY 0
@@ -27,12 +27,12 @@ class HBThread
HBThread( char * name,
int priority = HB_LOW_PRIORITY );
virtual ~HBThread();
- void Run();
- void Stop();
void Suspend();
void Resume();
+ int GetPid();
protected:
+ void Run();
bool Push( HBFifo * fifo, HBBuffer * buffer );
HBBuffer * Pop( HBFifo * fifo );
@@ -51,6 +51,7 @@ class HBThread
#elif defined( SYS_MACOSX ) || defined( SYS_LINUX )
pthread_t fThread;
#endif
+ int fPid;
};
#if defined( SYS_BEOS )
diff --git a/core/Worker.cpp b/core/Worker.cpp
new file mode 100644
index 000000000..5f1352026
--- /dev/null
+++ b/core/Worker.cpp
@@ -0,0 +1,150 @@
+/* $Id: Worker.cpp,v 1.9 2003/10/13 17:59:40 titer Exp $
+
+ This file is part of the HandBrake source code.
+ Homepage: <http://beos.titer.org/handbrake/>.
+ It may be used under the terms of the GNU General Public License. */
+
+#include "Ac3Decoder.h"
+#include "Mp3Encoder.h"
+#include "Mpeg2Decoder.h"
+#include "Mpeg4Encoder.h"
+#include "MpegDemux.h"
+#include "Resizer.h"
+#include "Worker.h"
+
+HBWorker::HBWorker( HBTitle * title, HBAudio * audio1,
+ HBAudio * audio2 )
+ : HBThread( "worker")
+{
+ fTitle = title;
+ fAudio1 = audio1;
+ fAudio2 = audio2;
+
+ Run();
+}
+
+void HBWorker::DoWork()
+{
+ bool didSomething;
+ uint64_t mpegDemux = 0;
+ uint64_t mpeg2Decoder = 0;
+ uint64_t resizer = 0;
+ uint64_t mpeg4Encoder = 0;
+ uint64_t ac3Decoder1 = 0;
+ uint64_t mp3Encoder1 = 0;
+ uint64_t ac3Decoder2 = 0;
+ uint64_t mp3Encoder2 = 0;
+ uint64_t tmpDate;
+
+ while( !fDie )
+ {
+ didSomething = false;
+
+ tmpDate = GetDate();
+ if( fTitle->fMpegDemux->Work() )
+ {
+ mpegDemux += ( GetDate() - tmpDate );
+ didSomething = true;
+ }
+
+ if( fDie ) break;
+
+ tmpDate = GetDate();
+ if( fTitle->fMpeg2Decoder->Work() )
+ {
+ mpeg2Decoder += ( GetDate() - tmpDate );
+ didSomething = true;
+ }
+
+ if( fDie ) break;
+
+ tmpDate = GetDate();
+ if( fTitle->fResizer->Work() )
+ {
+ resizer += ( GetDate() - tmpDate );
+ didSomething = true;
+ }
+
+ if( fDie ) break;
+
+ tmpDate = GetDate();
+ if( fTitle->fMpeg4Encoder->Work() )
+ {
+ mpeg4Encoder += ( GetDate() - tmpDate );
+ didSomething = true;
+ }
+
+ if( fDie ) break;
+
+ if( fAudio1 )
+ {
+ tmpDate = GetDate();
+ if( fAudio1->fAc3Decoder->Work() )
+ {
+ ac3Decoder1 += ( GetDate() - tmpDate );
+ didSomething = true;
+ }
+
+ if( fDie ) break;
+
+ tmpDate = GetDate();
+ if( fAudio1->fMp3Encoder->Work() )
+ {
+ mp3Encoder1 += ( GetDate() - tmpDate );
+ didSomething = true;
+ }
+
+ if( fDie ) break;
+ }
+
+ if( fAudio2 )
+ {
+ tmpDate = GetDate();
+ if( fAudio2->fAc3Decoder->Work() )
+ {
+ ac3Decoder2 += ( GetDate() - tmpDate );
+ didSomething = true;
+ }
+
+ if( fDie ) break;
+
+ tmpDate = GetDate();
+ if( fAudio2->fMp3Encoder->Work() )
+ {
+ mp3Encoder2 += ( GetDate() - tmpDate );
+ didSomething = true;
+ }
+
+ if( fDie ) break;
+ }
+
+ if( !didSomething )
+ {
+ Snooze( 10000 );
+ }
+
+ while( fSuspend )
+ {
+ Snooze( 10000 );
+ }
+ }
+
+ tmpDate = mpegDemux + mpeg2Decoder + resizer + mpeg4Encoder +
+ ac3Decoder1 + mp3Encoder1 + ac3Decoder2 + mp3Encoder2;
+ Log( "HBWorker stopped. CPU utilization:" );
+ Log( "- MPEG demuxer: %.2f %%", 100 * (float) mpegDemux / tmpDate );
+ Log( "- MPEG-2 decoder: %.2f %%", 100 * (float) mpeg2Decoder / tmpDate );
+ Log( "- Resizer: %.2f %%", 100 * (float) resizer / tmpDate );
+ Log( "- MPEG-4 encoder: %.2f %%", 100 * (float) mpeg4Encoder / tmpDate );
+ if( fAudio1 )
+ {
+ Log( "- AC3 decoder 1: %.2f %%", 100 * (float) ac3Decoder1 / tmpDate );
+ Log( "- MP3 encoder 1: %.2f %%", 100 * (float) mp3Encoder1 / tmpDate );
+ }
+ if( fAudio2 )
+ {
+ Log( "- AC3 decoder 2: %.2f %%", 100 * (float) ac3Decoder2 / tmpDate );
+ Log( "- MP3 encoder 2: %.2f %%", 100 * (float) mp3Encoder2 / tmpDate );
+ }
+}
+
diff --git a/core/Worker.h b/core/Worker.h
new file mode 100644
index 000000000..d2d0324d8
--- /dev/null
+++ b/core/Worker.h
@@ -0,0 +1,27 @@
+/* $Id: Worker.h,v 1.1 2003/10/07 17:40:06 titer Exp $
+
+ This file is part of the HandBrake source code.
+ Homepage: <http://beos.titer.org/handbrake/>.
+ It may be used under the terms of the GNU General Public License. */
+
+#ifndef HB_WORKER_H
+#define HB_WORKER_H
+
+#include "Common.h"
+#include "Thread.h"
+
+class HBWorker : public HBThread
+{
+ public:
+ HBWorker( HBTitle * title, HBAudio * audio1,
+ HBAudio * audio2 );
+
+ private:
+ void DoWork();
+
+ HBTitle * fTitle;
+ HBAudio * fAudio1;
+ HBAudio * fAudio2;
+};
+
+#endif