OSDN Git Service

HandBrake 0.6.2
authorroot <root@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Sat, 14 Jan 2006 13:34:42 +0000 (13:34 +0000)
committerroot <root@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Sat, 14 Jan 2006 13:34:42 +0000 (13:34 +0000)
git-svn-id: svn://localhost/HandBrake/trunk@15 b64f7644-9d1e-0410-96f1-a4d463321fa5

43 files changed:
CREDITS
Jamfile
Jamrules
NEWS
THANKS
TODO
core/Ac3Dec.c
core/AviMux.c
core/DVDRead.c
core/FaacEnc.c
core/FfmpegEnc.c
core/Fifo.c
core/Fifo.h
core/HBInternal.h
core/HandBrake.c
core/Jamfile
core/LpcmDec.c
core/MadDec.c [deleted file]
core/Mp3Enc.c
core/Mp4Mux.c
core/Mpeg2Dec.c
core/MpgaDec.c [new file with mode: 0644]
core/Mux.c [new file with mode: 0644]
core/Mux.h [new file with mode: 0644]
core/OgmMux.c
core/Resample.c [new file with mode: 0644]
core/Scale.c
core/Scan.c
core/Thread.c
core/Utils.c
core/Utils.h
core/VorbisEnc.c
core/Work.c
core/X264Enc.c
core/XvidEnc.c
doc/faq.txt
gtk2/main.c
macosx/Controller.mm
macosx/English.lproj/MainMenu.nib/info.nib
macosx/English.lproj/MainMenu.nib/objects.nib
macosx/HandBrake.xcode/project.pbxproj
macosx/i18n/de.strings
macosx/i18n/ja.strings [new file with mode: 0644]

diff --git a/CREDITS b/CREDITS
index 9843cb1..4310c76 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -1,4 +1,4 @@
-$Id: CREDITS,v 1.5 2004/03/01 19:09:38 titer Exp $
+$Id: CREDITS,v 1.7 2004/04/24 10:49:56 titer Exp $
 
 CREDITS file for HandBrake <http://handbrake.m0k.org/>
 
@@ -58,11 +58,6 @@ libdvdread authors:
   Billy Biggs
   Christian Wolff
 
-libdvdplay authors:
-  Håkan Hjort
-  Martin Norbäck
-  Stéphane Borel
-
 libfaac authors:
   M. Bakker
   Tony Lenox
@@ -140,6 +135,9 @@ libmpeg2 authors:
 libogg authors:
   Christopher Montgomery
 
+libsamplerate authors:
+  Erik de Castro Lopo
+
 libvorbis authors:
   Christopher Montgomery
 
diff --git a/Jamfile b/Jamfile
index 026b344..2399c91 100644 (file)
--- a/Jamfile
+++ b/Jamfile
@@ -1,4 +1,4 @@
-# $Id: Jamfile,v 1.42 2004/03/29 00:28:39 titer Exp $
+# $Id: Jamfile,v 1.46 2004/04/26 09:02:07 titer Exp $
 #
 # This file is part of the HandBrake source code.
 # Homepage: <http://handbrake.m0k.org/>.
@@ -7,9 +7,10 @@
 SubDir TOP ;
 
 # libhb + contrib libraries
-HB_LIBS = libhb.a liba52.a libavcodec.a libdvdplay.a libdvdread.a
+HB_LIBS = libhb.a liba52.a libavcodec.a libdvdread.a
           libdvdcss.a libfaac.a libmp3lame.a libmp4v2.a libmpeg2.a
-          libvorbis.a libvorbisenc.a libogg.a libx264.a libxvidcore.a ;
+          libvorbis.a libvorbisenc.a libogg.a libsamplerate.a
+         libx264.a libxvidcore.a ;
 
 # Interfaces
 TEST_BIN = HBTest ;
@@ -26,15 +27,10 @@ Main $(TEST_BIN) : $(TEST_SRC) ;
 
 if $(OS) = BEOS
 {
-    # Avoid multichar warnings caused by BeOS system headers
-    CCFLAGS  = -Wno-multichar ;
-    C++FLAGS = -Wno-multichar ;
-
     SystemLibraries HandBrake : -lbe ;
     # BeOS GUI is broken at the moment
     # Main            HandBrake : $(SRC_BEOS) ;
 }
-
 if $(OS) = MACOSX
 {
     # Needed to clean HandBrake.app
@@ -49,9 +45,8 @@ if $(OS) = MACOSX
     
     # Package
     OSXPackage HandBrake-$(HB_VERSION)-OSX.zip : HandBrake.app ;
-    PACKAGES += HandBrake-$(HB_VERSION)-OSX.zip ;
+    HB_PACKAGES += HandBrake-$(HB_VERSION)-OSX.zip ;
 }
-
 if $(OS) = LINUX
 {
     SystemLibraries $(TEST_BIN) : -lpthread ;
@@ -59,6 +54,10 @@ if $(OS) = LINUX
     ObjectCcFlags   $(GTK2_SRC) : `pkg-config gtk+-2.0 --cflags` ;
     Main            $(GTK2_BIN) : $(GTK2_SRC) ;
 }
+if $(OS) = CYGWIN
+{
+    SystemLibraries $(TEST_BIN) : -lws2_32 ;
+}
 
 ObjectHdrs     $(GUI_SRC) : $(TOP)/core ;
 ObjectCcFlags  $(GUI_SRC) : -g -Wall ;
index a82ee7a..ff970c2 100644 (file)
--- a/Jamrules
+++ b/Jamrules
@@ -1,13 +1,46 @@
+# $Id: Jamrules,v 1.38 2004/05/25 17:50:12 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.
+
+HB_VERSION = 0.6.2 ;
+LANGUAGES  = fr de it pl ru nl es pt ja ;
+
 # Compilers & flags
-CC    = gcc ;
-C++   = g++ ;
-AS    = nasm -f elf ;
-LINK  = g++ ;
-OPTIM = -O3 -funroll-loops ;
+CC      = gcc ;
+C++     = g++ ;
+AS      = nasm ;
+LINK    = g++ ;
+OPTIM   = -O3 -funroll-loops ;
+DEFINES = HB_$(OS) HB_VERSION=\\\"$(HB_VERSION)\\\" ;
 
-HB_VERSION = 0.6.1 ;
-DEFINES    = HB_$(OS) HB_VERSION=\\\"$(HB_VERSION)\\\" ;
-LANGUAGES  = fr de it pl ru nl es pt ;
+if $(OS) = BEOS
+{
+    # Avoid multichar warnings caused by BeOS system headers
+    CCFLAGS   = -Wno-multichar ;
+    C++FLAGS  = -Wno-multichar ;
+    # BeOS' gcc tends to crash with -funroll-loops
+    OPTIM     = -O3 ;
+    ASFLAGS   = -f elf ;
+}
+if $(OS) = MACOSX
+{
+    # For libdvdread
+    DEFINES  += WORDS_BIGENDIAN ;
+}
+if $(OS) = LINUX
+{
+    ASFLAGS   = -f elf ;
+}
+if $(OS) = CYGWIN
+{
+    # Build under cygwin but without the emulation layer
+    CCFLAGS   = -mno-cygwin ;
+    C++FLAGS  = -mno-cygwin ;
+    LINKFLAGS = -mno-cygwin ;
+    ASFLAGS   = -f win32 ;
+}
 
 NotFile clean-contrib clean-all ;
 Always  clean-contrib ;
@@ -89,7 +122,7 @@ rule OSXApp
 }
 actions BuildOSXApp
 {
-    $(RM) $(<) && \
+    $(RM) $(<) macosx/build/HandBrake.app && \
       ( cd macosx && xcodebuild ) && \
       cp -r macosx/build/HandBrake.app $(<) && \
       for i in $(LANGUAGES) ; do \
diff --git a/NEWS b/NEWS
index 0930a1e..5251428 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,16 @@
-$Id: NEWS,v 1.13 2004/03/29 00:28:39 titer Exp $
+$Id: NEWS,v 1.15 2004/05/25 17:48:52 titer Exp $
 
 NEWS file for HandBrake <http://handbrake.m0k.org/>
 
+Changes between 0.6.1 and 0.6.2
+ + Support for DVDs with MPEG audio tracks
+ + Rewrote the DVD navigation code
+ + High quality resampler included
+ + Better AVI compliance
+ + Updated encoders
+ + Internal improvements
+ + Bugfixes
+
 Changes between 0.6.0 and 0.6.1
  + Fixed LPCM endianness issue
 
diff --git a/THANKS b/THANKS
index 4644df0..ec543c2 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -1,4 +1,4 @@
-$Id: THANKS,v 1.11 2004/03/22 19:54:04 titer Exp $
+$Id: THANKS,v 1.13 2004/04/22 22:49:07 titer Exp $
 
 THANKS file for HandBrake <http://handbrake.m0k.org/>
 
@@ -6,14 +6,13 @@ Several people noticeably contributed to HandBrake development without
 writing code (submitting/checking translations, DVD samples, etc).
 Let's thank them here!
 
-Sorted by chronological order:
-
 Omar Ahmad Bhatti
  + Intensive beta testing, suggestions. Convinced me to port HandBrake
    to OS X, which finally was a pretty good idea.
 
 Hanna Bauer
 Adrien Marquette
+Norbert Rittel
  + German translation
 
 Paul Bénéchet
@@ -40,3 +39,6 @@ migol Superkid
 pgjw
  + Portuguese translation
 
+cygma
+ + Japanese translation
+
diff --git a/TODO b/TODO
index c6542e0..cfa765a 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,4 +1,4 @@
-$Id: TODO,v 1.33 2004/03/12 14:22:19 titer Exp $
+$Id: TODO,v 1.36 2004/05/25 17:48:52 titer Exp $
 
 TODO file for HandBrake <http://handbrake.m0k.org/>
 
@@ -9,28 +9,25 @@ as an indication, as it may change as any time.
  + Up-to-date BeOS GUI
 
 0.7.x
- + Homemade resampler
  + Audio volume normalizing
  + AC3 pass-through
  + Subtitle support
  + Rip only a few chapters or rip X seconds from a given starting point
  + Allow to launch rips of several titles
- + Drop libdvdplay
 
 Maybe in 0.7.x
- + MPEG audio decoding [if I have a DVD to test it]
  + B-frames, bla bla
  + MKV muxing support
  + Manual aspect ratio
  + Better remaining time calculation
  + Nice 'About...' box with link to homepage & faq
  + [OSX] Progress bar in the dock icon
+ + Custom framerate
 
 After 0.7.0
  + Preview the latest encoded picture in GUI
  + Split output file in x parts
  + Picture rotation
- + Custom framerate
  + Network shared processing (using RendezVous?)
  + VCD/DVD-R output
  + Theora encoding
@@ -40,6 +37,7 @@ After 0.7.0
  + Send a mail when rip is done
  + Turn the computer off when done
  + Collapse interface when rip starts
+ + MJPEG output, or something
 
 Misc known bugs:
  + [OSX] crash when trying to encode a DVD from mounted toast image
index 3fb4cc0..ef80558 100644 (file)
@@ -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" );
         }
     }
 
index 444d77a..c0209dd 100644 (file)
@@ -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 )
index 08e5139..4c36f39 100644 (file)
@@ -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 );
index b55a9de..689e6e1 100644 (file)
@@ -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" );
         }
     }
 
index 7d909a7..ae474d0 100644 (file)
@@ -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/>.
 /* 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;
     }
 }
 
index 5c32c59..ae0c412 100644 (file)
@@ -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 )
index 264a7ee..26c4b55 100644 (file)
@@ -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
index a8adb4d..4fa45f8 100644 (file)
@@ -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 ** );
index 9c88b37..6d16b46 100644 (file)
@@ -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 );
index 992dc5c..3c68353 100644 (file)
@@ -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 ;
index 519b486..425f429 100644 (file)
@@ -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 (file)
index da79ad8..0000000
+++ /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"
-
index bd62df4..c1aae34 100644 (file)
@@ -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/>.
 /* 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;
 }
+
index c545c96..d48c1ad 100644 (file)
@@ -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/>.
 /* 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;
 }
 
index ea3ffa2..043c416 100644 (file)
@@ -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/>.
 
 #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 (file)
index 0000000..e397a72
--- /dev/null
@@ -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 (file)
index 0000000..c9449e7
--- /dev/null
@@ -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 (file)
index 0000000..fbd1fd9
--- /dev/null
@@ -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
index fef1ae0..e99a494 100644 (file)
@@ -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/>.
 
 #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 (file)
index 0000000..f3632b3
--- /dev/null
@@ -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;
+}
+
index 5278825..2908d64 100644 (file)
@@ -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
 
index 8f19a13..9315e59 100644 (file)
@@ -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 );
index 8c63b24..9379223 100644 (file)
@@ -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;
     }
 
index 81aeebe..45ebf7b 100644 (file)
@@ -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/>.
 #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;
 }
 
index 2d1a06b..fce20e5 100644 (file)
@@ -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
index c75b368..8b7b10f 100644 (file)
@@ -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;
-}
index f2f0503..e23af24 100644 (file)
@@ -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 );
index 50b9ab8..be8d767 100644 (file)
@@ -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;
 }
index 8bf841f..4c06da6 100644 (file)
@@ -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;
 }
 
index 049dd57..6375637 100644 (file)
@@ -1,4 +1,4 @@
-$Id: faq.txt,v 1.12 2004/03/16 15:57:03 titer Exp $
+$Id: faq.txt,v 1.14 2004/04/22 22:22:07 titer Exp $
 
 <h2>HandBrake FAQ</h2>
 
@@ -9,7 +9,6 @@ get any sound</a></p>
 HandBrake</a></p>
 <p><a href="#A001003">1.3. Rip exits after a while with a AC3 error.
 What does that mean?</a></p>
-<p><a href="#A001004">1.4. Why does HandBrake get stuck at 100%?</a></p>
 
 <h4>2. Features</h4>
 <p><a href="#A002001">2.1 I want to convert a movie so I can burn it on
@@ -58,18 +57,9 @@ mean?</h4>
 happens when your DVD drive is over-heating after a X-hours long rip.
 Though it is handy to directly rip from the DVD, I recommend that you
 copy it first to the hard drive whenever possible (for example with
-OSEx, using the "DVD Folders" fmt) then you can open the folder with
-HandBrake. You have to keep the DVD folder organization (multiple VOB
-and IFO files), HandBrake won't open single VOB files.</p>
-
-<a name="A001004"></a>
-<h4>1.4. Why does HandBrake get stuck at 100%?</h4>
-<p>When ripping to an mp4 file, HandBrake (actually libmp4v2) optimizes
-the file and makes it compliant at the end of the rip. This might take
-some time with big files (usually, a few minutes for a 700 MB file).
-Also, make sure you have enough space available on your hard drive
-before you start (twice the asked size) or you might end with an
-unreadable file.</p>
+MacTheRipper, using "Extract Complete Disc") then you can open the
+folder with HandBrake. You have to keep the DVD folder organization
+(multiple VOB and IFO files), HandBrake won't open single VOB files.</p>
 
 <h3>2. Features</h3>
 
@@ -103,8 +93,12 @@ it to the list.</p>
 
 <a name="A002004"></a>
 <h4>2.4 Any plan to include 3ivx / DivX 5 encoding?</h4>
-<p>No. 3ivx/DivX aren't free software and have no multi-platform
-API.</p>
+
+<p>No. 3ivx/DivX aren't free software and have no multi-platform API.
+Moreover, they don't bring any noticeable quality improvement to XviD
+or FFmpeg. Though, you might consider using the 3ivX decoder to play
+the created files as its post-processing engine is known to be pretty
+good.</p>
 
 <h3>3. Technical</h3>
 
index f0d5b40..d4e4d5d 100644 (file)
@@ -205,9 +205,8 @@ static int HBMain( void *data )
                     char string[1024];
 
                     sprintf( string, "%d - %02dh%02dm%02ds",
-                             title->index, title->length / 3600,
-                             ( title->length % 3600 ) / 60,
-                             title->length % 60 );
+                             title->title, title->hours, title->minutes,
+                             title->seconds );
 
                     item = gtk_menu_item_new_with_mnemonic( string );
                     gtk_widget_show( item );
index 8f6e94d..eb53a9d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: Controller.mm,v 1.30 2004/03/12 14:22:19 titer Exp $
+/* $Id: Controller.mm,v 1.31 2004/04/21 21:21:17 titer Exp $
 
    This file is part of the HandBrake source code.
    Homepage: <http://handbrake.m0k.org/>.
@@ -850,8 +850,8 @@ static void _ScanDone( void * data, HBList * titleList )
         title = (HBTitle*) HBListItemAt( fTitleList, i );
         [[fRipTitlePopUp menu] addItemWithTitle:
             [NSString stringWithFormat: @"%d - %02dh%02dm%02ds",
-            title->index, title->length / 3600, ( title->length % 3600 )
-            / 60, title->length % 60] action: nil keyEquivalent: @""];
+            title->title, title->hours, title->minutes,
+            title->seconds] action: nil keyEquivalent: @""];
     }
     [self TitlePopUpChanged: self];
 }
index fab9345..07d1cfa 100644 (file)
@@ -3,11 +3,11 @@
 <plist version="1.0">
 <dict>
        <key>IBDocumentLocation</key>
-       <string>43 111 381 380 0 0 1440 878 </string>
+       <string>37 177 381 380 0 0 1440 878 </string>
        <key>IBEditorPositions</key>
        <dict>
                <key>29</key>
-               <string>297 654 165 44 0 0 1440 878 </string>
+               <string>277 674 165 44 0 0 1440 878 </string>
                <key>556</key>
                <string>130 59 470 306 0 0 1440 878 </string>
                <key>583</key>
        <array>
                <integer>29</integer>
                <integer>365</integer>
+               <integer>583</integer>
                <integer>434</integer>
                <integer>21</integer>
-               <integer>583</integer>
        </array>
        <key>IBSystem Version</key>
-       <string>7D24</string>
+       <string>7F44</string>
 </dict>
 </plist>
index ba5fa1e..5a2d374 100644 (file)
Binary files a/macosx/English.lproj/MainMenu.nib/objects.nib and b/macosx/English.lproj/MainMenu.nib/objects.nib differ
index 4b5a911..c9ac3a6 100644 (file)
                };
                29B97317FDCFA39411CA2CEA = {
                        children = (
-                               4D194F36059E0FBC004A33A1,
-                               4D548205059E100C00AD5E02,
-                               4D194F37059E0FBC004A33A1,
-                               4D194F38059E0FBC004A33A1,
                                29B97318FDCFA39411CA2CEA,
-                               4D929FED0527907200A80101,
-                               4D69F5C80527944A00A80101,
-                               4D69F5C90527944A00A80101,
-                               4D69F5CA0527944A00A80101,
-                               4D69F5CB0527944A00A80101,
-                               4D69F5CC0527944A00A80101,
-                               4D69F5CD0527944A00A80101,
-                               4D69F5CE0527944A00A80101,
-                               4DDEF3B905474DCC002904DE,
                                4D118405053054CD00C39CA9,
                                089C165CFE840E0CC02AAC07,
-                               4D0AEC1805747B7A00FAB0FD,
-                               4D0AEC1C05747B8C00FAB0FD,
                        );
                        isa = PBXGroup;
                        name = Resources;
                                FRAMEWORK_SEARCH_PATHS = "";
                                GCC_TREAT_WARNINGS_AS_ERRORS = YES;
                                HEADER_SEARCH_PATHS = "";
-                               LIBRARY_SEARCH_PATHS = "../core ../contrib/liba52 ../contrib/libavcodec ../contrib/libdvdcss ../contrib/libdvdplay ../contrib/libdvdread ../contrib/libfaac ../contrib/libmp3lame ../contrib/libmp4v2 ../contrib/libmpeg2 ../contrib/libogg ../contrib/libvorbis ../contrib/libx264 ../contrib/libxvidcore";
+                               LIBRARY_SEARCH_PATHS = "";
                                OPTIMIZATION_CFLAGS = "-O3";
                                OTHER_CFLAGS = "";
-                               OTHER_LDFLAGS = "";
+                               OTHER_LDFLAGS = "../core/libhb.a ../contrib/liba52/liba52.a ../contrib/libavcodec/libavcodec.a ../contrib/libdvdread/libdvdread.a ../contrib/libdvdcss/libdvdcss.a ../contrib/libfaac/libfaac.a ../contrib/libmp3lame/libmp3lame.a ../contrib/libmp4v2/libmp4v2.a ../contrib/libmpeg2/libmpeg2.a ../contrib/libvorbis/libvorbis.a ../contrib/libvorbis/libvorbisenc.a ../contrib/libogg/libogg.a ../contrib/libsamplerate/libsamplerate.a ../contrib/libx264/libx264.a ../contrib/libxvidcore/libxvidcore.a";
                                PRODUCT_NAME = HandBrake;
                                SECTORDER_FLAGS = "";
                                WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
        <string>HandBrake</string>
        <key>CFBundleExecutable</key>
        <string>HandBrake</string>
+       <key>CFBundleGetInfoString</key>
+       <string>0.6.2</string>
        <key>CFBundleIconFile</key>
        <string>HandBrake.icns</string>
        <key>CFBundleIdentifier</key>
        <key>CFBundlePackageType</key>
        <string>APPL</string>
        <key>CFBundleShortVersionString</key>
-       <string>0.6.1</string>
+       <string>0.6.2</string>
        <key>CFBundleSignature</key>
        <string>HB##</string>
        <key>CFBundleVersion</key>
-       <string>0.6.1</string>
+       <string>0.6.2</string>
        <key>NSHumanReadableCopyright</key>
        <string>By Eric Petit &lt;titer@m0k.org&gt;</string>
        <key>NSMainNibFile</key>
                        buildActionMask = 2147483647;
                        files = (
                                1058C7A3FEA54F0111CA2CBB,
-                               4D929FEE0527907200A80101,
-                               4D69F5CF0527944A00A80101,
-                               4D69F5D00527944A00A80101,
-                               4D69F5D10527944A00A80101,
-                               4D69F5D20527944A00A80101,
-                               4D69F5D30527944A00A80101,
-                               4D69F5D40527944A00A80101,
-                               4D69F5D50527944A00A80101,
                                4DEB2025052B055F00C39CA9,
                                4DDE9725052B7B2B00C39CA9,
-                               4DDEF3BA05474DCC002904DE,
-                               4D0AEC1905747B7A00FAB0FD,
-                               4D0AEC1D05747B8C00FAB0FD,
-                               4D194F39059E0FBC004A33A1,
-                               4D194F3A059E0FBC004A33A1,
-                               4D194F3B059E0FBC004A33A1,
-                               4D548206059E100C00AD5E02,
                        );
                        isa = PBXFrameworksBuildPhase;
                        runOnlyForDeploymentPostprocessing = 0;
                        );
                        buildSettings = {
                                COPY_PHASE_STRIP = NO;
-                               CURRENT_PROJECT_VERSION = "0.6.1";
+                               CURRENT_PROJECT_VERSION = "0.6.2";
                                GCC_DYNAMIC_NO_PIC = YES;
                                GCC_ENABLE_FIX_AND_CONTINUE = NO;
                                GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
 //4D2
 //4D3
 //4D4
-               4D0AEC1805747B7A00FAB0FD = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = archive.ar;
-                       name = libfaac.a;
-                       path = ../contrib/libfaac/libfaac.a;
-                       refType = 2;
-                       sourceTree = SOURCE_ROOT;
-               };
-               4D0AEC1905747B7A00FAB0FD = {
-                       fileRef = 4D0AEC1805747B7A00FAB0FD;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4D0AEC1C05747B8C00FAB0FD = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = archive.ar;
-                       name = libmp4v2.a;
-                       path = ../contrib/libmp4v2/libmp4v2.a;
-                       refType = 2;
-                       sourceTree = SOURCE_ROOT;
-               };
-               4D0AEC1D05747B8C00FAB0FD = {
-                       fileRef = 4D0AEC1C05747B8C00FAB0FD;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
                4D118405053054CD00C39CA9 = {
                        isa = PBXFileReference;
                        lastKnownFileType = image.icns;
                        settings = {
                        };
                };
-               4D194F36059E0FBC004A33A1 = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = archive.ar;
-                       name = libvorbis.a;
-                       path = ../contrib/libvorbis/libvorbis.a;
-                       refType = 2;
-                       sourceTree = SOURCE_ROOT;
-               };
-               4D194F37059E0FBC004A33A1 = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = archive.ar;
-                       name = libvorbisenc.a;
-                       path = ../contrib/libvorbis/libvorbisenc.a;
-                       refType = 2;
-                       sourceTree = SOURCE_ROOT;
-               };
-               4D194F38059E0FBC004A33A1 = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = archive.ar;
-                       name = libx264.a;
-                       path = ../contrib/libx264/libx264.a;
-                       refType = 2;
-                       sourceTree = SOURCE_ROOT;
-               };
-               4D194F39059E0FBC004A33A1 = {
-                       fileRef = 4D194F36059E0FBC004A33A1;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4D194F3A059E0FBC004A33A1 = {
-                       fileRef = 4D194F37059E0FBC004A33A1;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4D194F3B059E0FBC004A33A1 = {
-                       fileRef = 4D194F38059E0FBC004A33A1;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
                4D358C000534A91300D654EB = {
                        fileEncoding = 30;
                        isa = PBXFileReference;
                        settings = {
                        };
                };
-               4D548205059E100C00AD5E02 = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = archive.ar;
-                       name = libogg.a;
-                       path = ../contrib/libogg/libogg.a;
-                       refType = 2;
-                       sourceTree = SOURCE_ROOT;
-               };
-               4D548206059E100C00AD5E02 = {
-                       fileRef = 4D548205059E100C00AD5E02;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
                4D6615EA05288C2300A80101 = {
                        fileRef = 4DF3C8CB052889CD00A80101;
                        isa = PBXBuildFile;
                        settings = {
                        };
                };
-               4D69F5C80527944A00A80101 = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = archive.ar;
-                       name = liba52.a;
-                       path = ../contrib/liba52/liba52.a;
-                       refType = 2;
-                       sourceTree = SOURCE_ROOT;
-               };
-               4D69F5C90527944A00A80101 = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = archive.ar;
-                       name = libavcodec.a;
-                       path = ../contrib/libavcodec/libavcodec.a;
-                       refType = 2;
-                       sourceTree = SOURCE_ROOT;
-               };
-               4D69F5CA0527944A00A80101 = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = archive.ar;
-                       name = libdvdcss.a;
-                       path = ../contrib/libdvdcss/libdvdcss.a;
-                       refType = 2;
-                       sourceTree = SOURCE_ROOT;
-               };
-               4D69F5CB0527944A00A80101 = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = archive.ar;
-                       name = libdvdplay.a;
-                       path = ../contrib/libdvdplay/libdvdplay.a;
-                       refType = 2;
-                       sourceTree = SOURCE_ROOT;
-               };
-               4D69F5CC0527944A00A80101 = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = archive.ar;
-                       name = libdvdread.a;
-                       path = ../contrib/libdvdread/libdvdread.a;
-                       refType = 2;
-                       sourceTree = SOURCE_ROOT;
-               };
-               4D69F5CD0527944A00A80101 = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = archive.ar;
-                       name = libmp3lame.a;
-                       path = ../contrib/libmp3lame/libmp3lame.a;
-                       refType = 2;
-                       sourceTree = SOURCE_ROOT;
-               };
-               4D69F5CE0527944A00A80101 = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = archive.ar;
-                       name = libmpeg2.a;
-                       path = ../contrib/libmpeg2/libmpeg2.a;
-                       refType = 2;
-                       sourceTree = SOURCE_ROOT;
-               };
-               4D69F5CF0527944A00A80101 = {
-                       fileRef = 4D69F5C80527944A00A80101;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4D69F5D00527944A00A80101 = {
-                       fileRef = 4D69F5C90527944A00A80101;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4D69F5D10527944A00A80101 = {
-                       fileRef = 4D69F5CA0527944A00A80101;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4D69F5D20527944A00A80101 = {
-                       fileRef = 4D69F5CB0527944A00A80101;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4D69F5D30527944A00A80101 = {
-                       fileRef = 4D69F5CC0527944A00A80101;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4D69F5D40527944A00A80101 = {
-                       fileRef = 4D69F5CD0527944A00A80101;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4D69F5D50527944A00A80101 = {
-                       fileRef = 4D69F5CE0527944A00A80101;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
                4D85758E052B78E300C39CA9 = {
                        fileEncoding = 30;
                        isa = PBXFileReference;
                        settings = {
                        };
                };
-               4D929FED0527907200A80101 = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = archive.ar;
-                       name = libhb.a;
-                       path = ../core/libhb.a;
-                       refType = 2;
-                       sourceTree = SOURCE_ROOT;
-               };
-               4D929FEE0527907200A80101 = {
-                       fileRef = 4D929FED0527907200A80101;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
                4DDE9724052B7B2B00C39CA9 = {
                        fallbackIsa = PBXFileReference;
                        isa = PBXFrameworkReference;
                        settings = {
                        };
                };
-               4DDEF3B905474DCC002904DE = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = archive.ar;
-                       name = libxvidcore.a;
-                       path = ../contrib/libxvidcore/libxvidcore.a;
-                       refType = 2;
-                       sourceTree = SOURCE_ROOT;
-               };
-               4DDEF3BA05474DCC002904DE = {
-                       fileRef = 4DDEF3B905474DCC002904DE;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
                4DEB2024052B055F00C39CA9 = {
                        fallbackIsa = PBXFileReference;
                        isa = PBXFrameworkReference;
index 7ab1757..c004689 100644 (file)
Binary files a/macosx/i18n/de.strings and b/macosx/i18n/de.strings differ
diff --git a/macosx/i18n/ja.strings b/macosx/i18n/ja.strings
new file mode 100644 (file)
index 0000000..fc457a7
Binary files /dev/null and b/macosx/i18n/ja.strings differ