OSDN Git Service

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

173 files changed:
AUTHORS
BUILD
Jamfile
Jamrules
NEWS
THANKS
TODO [deleted file]
beos/HBApp.cpp
beos/HBApp.h
beos/HBWindow.cpp [deleted file]
beos/HBWindow.h [deleted file]
beos/MainWindow.cpp [new file with mode: 0644]
beos/MainWindow.h [new file with mode: 0644]
beos/PicWindow.cpp [new file with mode: 0644]
beos/PicWindow.h [new file with mode: 0644]
beos/QueueWindow.cpp [new file with mode: 0644]
beos/QueueWindow.h [new file with mode: 0644]
beos/ScanWindow.cpp [new file with mode: 0644]
beos/ScanWindow.h [new file with mode: 0644]
beos/Stepper.cpp [new file with mode: 0644]
beos/Stepper.h [new file with mode: 0644]
beos/liblayout/HGroup.h [deleted file]
beos/liblayout/LayeredGroup.h [deleted file]
beos/liblayout/MApplication.h [deleted file]
beos/liblayout/MBViewWrapper.h [deleted file]
beos/liblayout/MBorder.h [deleted file]
beos/liblayout/MButton.h [deleted file]
beos/liblayout/MCheckBox.h [deleted file]
beos/liblayout/MDividable.h [deleted file]
beos/liblayout/MDragBar.h [deleted file]
beos/liblayout/MEject.h [deleted file]
beos/liblayout/MFFWD.h [deleted file]
beos/liblayout/MGroup.h [deleted file]
beos/liblayout/MListView.h [deleted file]
beos/liblayout/MMenuBar.h [deleted file]
beos/liblayout/MOutlineListView.h [deleted file]
beos/liblayout/MPictureButton.h [deleted file]
beos/liblayout/MPlayBW.h [deleted file]
beos/liblayout/MPlayFW.h [deleted file]
beos/liblayout/MPopup.h [deleted file]
beos/liblayout/MProgressBar.h [deleted file]
beos/liblayout/MRadioGroup.h [deleted file]
beos/liblayout/MRew.h [deleted file]
beos/liblayout/MScrollView.h [deleted file]
beos/liblayout/MSlider.h [deleted file]
beos/liblayout/MSplitter.h [deleted file]
beos/liblayout/MStop.h [deleted file]
beos/liblayout/MStringView.h [deleted file]
beos/liblayout/MTabView.h [deleted file]
beos/liblayout/MTextControl.h [deleted file]
beos/liblayout/MTextView.h [deleted file]
beos/liblayout/MVolume.h [deleted file]
beos/liblayout/MWindow.h [deleted file]
beos/liblayout/PropGadget.h [deleted file]
beos/liblayout/Space.h [deleted file]
beos/liblayout/SpinButton.h [deleted file]
beos/liblayout/TabGroup.h [deleted file]
beos/liblayout/VGroup.h [deleted file]
beos/liblayout/layout-all.h [deleted file]
beos/liblayout/layout.h [deleted file]
configure [new file with mode: 0755]
contrib/Jamfile [new file with mode: 0644]
contrib/version_a52dec.txt [new file with mode: 0644]
contrib/version_faac.txt [new file with mode: 0644]
contrib/version_ffmpeg.txt [new file with mode: 0644]
contrib/version_lame.txt [new file with mode: 0644]
contrib/version_libdvdcss.txt [new file with mode: 0644]
contrib/version_libdvdread.txt [new file with mode: 0644]
contrib/version_libogg.txt [new file with mode: 0644]
contrib/version_libsamplerate.txt [new file with mode: 0644]
contrib/version_libvorbis.txt [new file with mode: 0644]
contrib/version_mpeg2dec.txt [new file with mode: 0644]
contrib/version_mpeg4ip.txt [new file with mode: 0644]
contrib/version_x264.txt [new file with mode: 0644]
contrib/version_xvidcore.txt [new file with mode: 0644]
core/Ac3Dec.c [deleted file]
core/AviMux.c [deleted file]
core/DVDRead.c [deleted file]
core/FaacEnc.c [deleted file]
core/FfmpegEnc.c [deleted file]
core/Fifo.c [deleted file]
core/Fifo.h [deleted file]
core/HBInternal.h [deleted file]
core/HandBrake.c [deleted file]
core/HandBrake.h [deleted file]
core/Jamfile [deleted file]
core/LpcmDec.c [deleted file]
core/Mp3Enc.c [deleted file]
core/Mp4Mux.c [deleted file]
core/Mpeg2Dec.c [deleted file]
core/MpgaDec.c [deleted file]
core/Mux.c [deleted file]
core/Mux.h [deleted file]
core/OgmMux.c [deleted file]
core/Resample.c [deleted file]
core/Scale.c [deleted file]
core/Scan.c [deleted file]
core/Thread.c [deleted file]
core/Thread.h [deleted file]
core/Utils.c [deleted file]
core/Utils.h [deleted file]
core/VorbisEnc.c [deleted file]
core/Work.c [deleted file]
core/Work.h [deleted file]
core/X264Enc.c [deleted file]
core/XvidEnc.c [deleted file]
doc/faq.txt [deleted file]
doc/genhtml.sh [deleted file]
libhb/Jamfile [new file with mode: 0644]
libhb/common.c [new file with mode: 0644]
libhb/common.h [new file with mode: 0644]
libhb/deca52.c [new file with mode: 0644]
libhb/decavcodec.c [new file with mode: 0644]
libhb/declpcm.c [new file with mode: 0644]
libhb/decmpeg2.c [new file with mode: 0644]
libhb/decsub.c [new file with mode: 0644]
libhb/demuxmpeg.c [new file with mode: 0644]
libhb/dvd.c [new file with mode: 0644]
libhb/encavcodec.c [new file with mode: 0644]
libhb/encfaac.c [new file with mode: 0644]
libhb/enclame.c [new file with mode: 0644]
libhb/encvorbis.c [new file with mode: 0644]
libhb/encx264.c [new file with mode: 0644]
libhb/encxvid.c [new file with mode: 0644]
libhb/fifo.c [new file with mode: 0644]
libhb/hb.c [new file with mode: 0644]
libhb/hb.h [new file with mode: 0644]
libhb/internal.h [new file with mode: 0644]
libhb/lang.h [moved from core/Languages.h with 86% similarity]
libhb/muxavi.c [new file with mode: 0644]
libhb/muxcommon.c [new file with mode: 0644]
libhb/muxmp4.c [new file with mode: 0644]
libhb/muxogm.c [new file with mode: 0644]
libhb/ports.c [new file with mode: 0644]
libhb/ports.h [new file with mode: 0644]
libhb/reader.c [new file with mode: 0644]
libhb/render.c [new file with mode: 0644]
libhb/scan.c [new file with mode: 0644]
libhb/sync.c [new file with mode: 0644]
libhb/update.c [new file with mode: 0644]
libhb/work.c [new file with mode: 0644]
macosx/Controller.h
macosx/Controller.mm
macosx/English.lproj/MainMenu.nib/classes.nib
macosx/English.lproj/MainMenu.nib/info.nib
macosx/English.lproj/MainMenu.nib/keyedobjects.nib [new file with mode: 0644]
macosx/English.lproj/MainMenu.nib/objects.nib [deleted file]
macosx/HandBrake.icns
macosx/HandBrake.xcode/project.pbxproj [deleted file]
macosx/HandBrake.xcodeproj/project.pbxproj [new file with mode: 0644]
macosx/Info.plist [new file with mode: 0644]
macosx/PictureController.h [new file with mode: 0644]
macosx/PictureController.mm [new file with mode: 0644]
macosx/PictureGLView.h
macosx/PictureGLView.mm
macosx/PrefsController.h [new file with mode: 0644]
macosx/PrefsController.m [new file with mode: 0644]
macosx/QueueController.h [new file with mode: 0644]
macosx/QueueController.mm [new file with mode: 0644]
macosx/ScanController.h [new file with mode: 0644]
macosx/ScanController.mm [new file with mode: 0644]
macosx/TargetSizeField.h [deleted file]
macosx/TargetSizeField.mm [deleted file]
macosx/genstrings.sh
macosx/i18n/Localizable.strings
macosx/i18n/fr.strings
macosx/main.mm
test/test.c
wx/hb32x32.xpm [new file with mode: 0644]
wx/hbWizard.cpp [new file with mode: 0644]
wx/hbWizard.h [new file with mode: 0644]
wx/wxHB.cpp [new file with mode: 0644]
wx/wxHB.h [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
index d5fa5bf..744cdf8 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,14 +1,15 @@
-$Id: AUTHORS,v 1.3 2004/03/08 11:32:48 titer Exp $
+$Id: AUTHORS,v 1.5 2005/03/23 13:14:50 titer Exp $
 
 AUTHORS file for HandBrake <http://handbrake.m0k.org/>
 
 Eric Petit <titer@m0k.org>
  + Core (construct, multithreading, BeOS/OS X/Linux ports)
  + MPEG demuxer
- + MPEG-2 and AC3 decoders (w/ libmpeg2/liba52)
+ + MPEG-2, AC3 and MPGA decoders (w/ libmpeg2/liba52/libavcodec)
  + LPCM "decoder"
  + MPEG-4, MP3 and AAC encoders (w/ libavcodec/libxvidcore/libmp3lame/
    libfaac)
+ + AC-3 pass-through
  + AVI muxer
  + MP4 muxer (w/ libmp4v2)
  + BeOS interface
@@ -19,4 +20,5 @@ Laurent Aimar <fenrir@via.ecp.fr>
  + H264 and Vorbis encoders (w/ libx264/libvorbis)
  + OGG/OGM muxer (w/ libogg)
  + Gtk2 interface
+ + wxWidgets interface
 
diff --git a/BUILD b/BUILD
index 6eb184e..4136440 100644 (file)
--- a/BUILD
+++ b/BUILD
@@ -1,4 +1,4 @@
-$Id: BUILD,v 1.5 2004/03/29 00:28:39 titer Exp $
+$Id: BUILD,v 1.11 2005/10/23 01:35:59 titer Exp $
 
 BUILD file for HandBrake <http://handbrake.m0k.org/>
 
@@ -8,31 +8,21 @@ Building HandBrake
 You can build HandBrake on BeOS, MacOS X and Linux. If you'd like to
 port it to another OS, email me (titer@m0k.org).
 
-Step 1: get jam
-===============
-
-Jam <http://www.perforce.com/jam/jam.html> is a make replacement.
-Get it for your operating system:
- + BeOS: get <http://tfs.cs.tu-berlin.de/~bonefish/download/jam/jam.zip>
-   (the jam used by OBOS). Also, gcc 2.95.3 is needed.
- + OS X: get <http://handbrake.m0k.org/files/jam-2.5rc3-OSX.zip> and
-   copy jam to /usr/local/bin/. Do not use the modified jam shipped with
-   the developer tools (/Developer/Private/jam).
- + Debian: `apt-get install jam'
-Or get the sources from the link above and compile it yourself.
-
-Step 2 (optional): set custom compiler flags
-============================================
-
-If you want to optimize the build for a specific CPU, edit the Jamrules
-file and modify the "OPTIM = ..." line by adding the needed flags.
-
-In case you modify this line later: `jam clean' does not remove the
-compiled contrib librairies. Therefore, make sure you run
-`jam clean-all; jam' or `jam -a' in order to force jam to rebuild
-everything with the new flags.
-
-Step 3: build
+Step 1: get needed tools
+========================
+
++ gcc and g++
+    There are usually included in your OS' dev tools. On BeOS/Zeta, the
+    default gcc isn't enough, gcc 2.95.3 is required.
++ jam
+    I use 2.5rc3, earlier versions might cause issues.
+    On BeOS, you can download it at <http://www.haiku-os.org/develop.php>.
+    On OS X, you cannot use the modified jam shipped with the developer
+    tools, use this one instead:
+    <http://handbrake.m0k.org/files/jam-2.5rc3-OSX.zip>.
++ nasm (except for OS X)
+
+Step 2: build
 =============
 
 Run `jam'. This will build every library HandBrake requires, then
diff --git a/Jamfile b/Jamfile
index 2399c91..8066a1b 100644 (file)
--- a/Jamfile
+++ b/Jamfile
@@ -1,4 +1,4 @@
-# $Id: Jamfile,v 1.46 2004/04/26 09:02:07 titer Exp $
+# $Id: Jamfile,v 1.86 2005/11/04 13:09:40 titer Exp $
 #
 # This file is part of the HandBrake source code.
 # Homepage: <http://handbrake.m0k.org/>.
@@ -7,40 +7,49 @@
 SubDir TOP ;
 
 # libhb + contrib libraries
-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 libsamplerate.a
-         libx264.a libxvidcore.a ;
+HB_LIBS = libhb.a
+          contrib/lib/liba52.a        contrib/lib/libavcodec.a
+          contrib/lib/libavutil.a     contrib/lib/libdvdread.a
+          contrib/lib/libdvdcss.a     contrib/lib/libfaac.a
+          contrib/lib/libmp3lame.a    contrib/lib/libmp4v2.a
+          contrib/lib/libmpeg2.a      contrib/lib/libvorbis.a
+          contrib/lib/libvorbisenc.a  contrib/lib/libogg.a
+          contrib/lib/libsamplerate.a contrib/lib/libx264.a
+          contrib/lib/libxvidcore.a ;
 
 # Interfaces
 TEST_BIN = HBTest ;
 TEST_SRC = test/test.c ;
 BEOS_BIN = HandBrake ;
-BEOS_SRC = beos/HBApp.cpp beos/HBWindow.cpp ;
-GTK2_BIN = gtk2HB ;
-GTK2_SRC = gtk2/main.c gtk2/callbacks.c gtk2/interface.c gtk2/support.c ;
-GUI_BIN  = $(TEST_BIN) $(BEOS_BIN) $(GTK2_BIN) ;
-GUI_SRC  = $(TEST_SRC) $(BEOS_SRC) $(GTK2_SRC) ;
+BEOS_SRC = beos/HBApp.cpp beos/MainWindow.cpp beos/ScanWindow.cpp
+           beos/PicWindow.cpp beos/Stepper.cpp beos/QueueWindow.cpp ;
+WX_BIN   = wxHB ;
+WX_SRC   = wx/hbWizard.cpp wx/wxHB.cpp ;
+UI_BIN   = $(TEST_BIN) $(BEOS_BIN) $(WX_BIN) ;
+UI_SRC   = $(TEST_SRC) $(BEOS_SRC) $(WX_SRC) ;
 
 # CLI app
 Main $(TEST_BIN) : $(TEST_SRC) ;
 
 if $(OS) = BEOS
 {
-    SystemLibraries HandBrake : -lbe ;
-    # BeOS GUI is broken at the moment
-    # Main            HandBrake : $(SRC_BEOS) ;
+    Main HandBrake : $(BEOS_SRC) ;
+
+    BeOSPackage HandBrake-$(HB_VERSION)-BeOS.zip : HandBrake ;
+    HB_PACKAGES += HandBrake-$(HB_VERSION)-BeOS.zip ;
 }
 if $(OS) = MACOSX
 {
-    # Needed to clean HandBrake.app
-    RM = rm -rf ;
-
-    OSX_SRC = macosx/Controller.h macosx/Controller.mm
+    OSX_SRC = macosx/main.mm macosx/Controller.h macosx/Controller.mm
+              macosx/ScanController.h macosx/ScanController.mm
+              macosx/PictureController.h macosx/PictureController.mm
               macosx/PictureGLView.h macosx/PictureGLView.mm
-              macosx/TargetSizeField.h macosx/TargetSizeField.mm
-              macosx/main.mm ;
-
+              macosx/QueueController.h macosx/QueueController.mm
+              macosx/PrefsController.h macosx/PrefsController.m
+              macosx/English.lproj/InfoPlist.strings
+              macosx/English.lproj/MainMenu.nib/classes.nib
+              macosx/English.lproj/MainMenu.nib/info.nib
+              macosx/English.lproj/MainMenu.nib/keyedobjects.nib ;
     OSXApp HandBrake.app : $(OSX_SRC) $(HB_LIBS) ;
     
     # Package
@@ -49,25 +58,19 @@ if $(OS) = MACOSX
 }
 if $(OS) = LINUX
 {
-    SystemLibraries $(TEST_BIN) : -lpthread ;
-    SystemLibraries $(GTK2_BIN) : -lpthread `pkg-config gtk+-2.0 --libs` ;
-    ObjectCcFlags   $(GTK2_SRC) : `pkg-config gtk+-2.0 --cflags` ;
-    Main            $(GTK2_BIN) : $(GTK2_SRC) ;
-}
-if $(OS) = CYGWIN
-{
-    SystemLibraries $(TEST_BIN) : -lws2_32 ;
+    # WX UI outdated
+    #SystemLibraries $(WX_BIN) : -lpthread `wx-config --libs` ;
+    #ObjectC++Flags  $(WX_SRC) : `wx-config --cflags` ;
+    #Main            $(WX_BIN) : $(WX_SRC) ;
 }
 
-ObjectHdrs     $(GUI_SRC) : $(TOP)/core ;
-ObjectCcFlags  $(GUI_SRC) : -g -Wall ;
-ObjectC++Flags $(GUI_SRC) : -g -Wall ;
-LinkLibraries  $(GUI_BIN) : $(HB_LIBS) ;
+ObjectHdrs     $(UI_SRC) : $(TOP)/libhb ;
+LinkLibraries  $(UI_BIN) : $(HB_LIBS) ;
 
 # Packages
 NotFile package ;
 Depends package : $(HB_PACKAGES) ;
 
 SubInclude TOP contrib ;
-SubInclude TOP core ;
+SubInclude TOP libhb ;
 
index ff970c2..6b15be6 100644 (file)
--- a/Jamrules
+++ b/Jamrules
-# $Id: Jamrules,v 1.38 2004/05/25 17:50:12 titer Exp $
+# $Id: Jamrules,v 1.59 2005/11/04 16:06:21 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 ;
+include config.jam ;
 
-# Compilers & flags
-CC      = gcc ;
-C++     = g++ ;
-AS      = nasm ;
-LINK    = g++ ;
-OPTIM   = -O3 -funroll-loops ;
-DEFINES = HB_$(OS) HB_VERSION=\\\"$(HB_VERSION)\\\" ;
-
-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
+if ! $(DEFINES)
 {
-    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 ;
+    Exit "Please run ./configure first." ;
 }
 
-NotFile clean-contrib clean-all ;
-Always  clean-contrib ;
-Depends clean-all : clean clean-contrib ;
-
-# _Object: same as Jambase's Object, except
-#  * those aren't cleaned by 'jam clean' (to prevent from deleting
-#    every contrib library by accident)
-#  * it handles *.asm files
-rule _Object
-{
-    MakeLocate $(<) : $(LOCATE_TARGET) ;
-    SEARCH on $(>) = $(SEARCH_SOURCE) ;
-    HDRS on $(<) = $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ;
-    HDRRULE on $(>) = HdrRule ;
-    HDRSCAN on $(>) = $(HDRPATTERN) ;
-    HDRSEARCH on $(>) =
-            $(SEARCH_SOURCE:E) $(SUBDIRHDRS) $(HDRS) $(STDHDRS) ;
-    HDRGRIST on $(>) = $(HDRGRIST) ;
-    DEFINES on $(<) += $(DEFINES) ;
-    switch $(>:S)
-    {   
-        case .asm : As $(<) : $(>) ;
-        case .nas : As $(<) : $(>) ;
-        case .c :   Cc $(<) : $(>) ;
-        case .cpp : C++ $(<) : $(>) ;
-    }
-}
-# _Objects: use _Object
-rule _Objects
-{
-    local _i ;
-    for _i in [ FGristFiles $(<) ]
-    {
-        _Object $(_i:S=$(SUFOBJ)) : $(_i) ;
-        Depends obj : $(_i:S=$(SUFOBJ)) ;
-    }
-}
-
-# Simplified LibraryFromObjects which doesn't clean the target library
-# nor the temporary .o files
-rule _Library
-{
-    local _l _s ;
-    _s = [ FGristFiles $(>:S=$(SUFOBJ)) ] ;
-    _l = $(<:S=$(SUFLIB)) ;
-    _Objects $(>) ;
-    Depends obj : $(_s) ;
-    MakeLocate $(_l) $(_l)($(_s:BS)) : $(LOCATE_TARGET) ;
-    Depends $(_l) : $(_s) ;
-    Archive $(_l) : $(_s) ;
-    if $(RANLIB) { Ranlib $(_l) ; }
-    Depends lib : $(_l) ;
-}
-
-# ContribLibrary: library cleaned by 'jam clean-contrib'
-rule ContribLibrary
-{
-    _Library $(<) : $(>) ;
-    Clean clean-contrib : [ FGristFiles $(>:S=$(SUFOBJ)) ] ;
-    Clean clean-contrib : $(<:S=$(SUFLIB)) ;
-}
-
-# Library: library cleaned by 'jam clean'
-rule Library
-{
-    _Library $(<) : $(>) ;
-    Clean clean : [ FGristFiles $(>:S=$(SUFOBJ)) ] ;
-    Clean clean : $(<:S=$(SUFLIB)) ;
-}
+HB_VERSION  = 0.7.0 ;
+HB_BUILD    = 2005110400 ;
+DEFINES    += HB_VERSION=\\\"$(HB_VERSION)\\\" HB_BUILD=$(HB_BUILD) ;
+LANGUAGES   = fr de it pl ru nl es pt ja ;
+RM          = rm -rf ;
 
 # Build HandBrake.app using Xcode
 rule OSXApp
@@ -118,13 +23,12 @@ rule OSXApp
     Depends     exe   : $(<) ;
     Depends     $(<)  : $(>) ;
     Clean       clean : $(1) macosx/build ;
-    BuildOSXApp $(<) ;
 }
-actions BuildOSXApp
+actions OSXApp
 {
     $(RM) $(<) macosx/build/HandBrake.app && \
       ( cd macosx && xcodebuild ) && \
-      cp -r macosx/build/HandBrake.app $(<) && \
+      mv macosx/build/Default/HandBrake.app $(<) && \
       for i in $(LANGUAGES) ; do \
         ( cd $(<)/Contents/Resources && \
           cp -r English.lproj $i.lproj && \
@@ -134,10 +38,9 @@ actions BuildOSXApp
 }
 rule OSXPackage 
 {
-    Depends         $(<) : $(>) ;
-    BuildOSXPackage $(<) ;
+    Depends $(<) : $(>) ;
 }   
-actions BuildOSXPackage
+actions OSXPackage
 {                 
     rm -rf $(<) "HandBrake $(HB_VERSION)" && \
       mkdir "HandBrake $(HB_VERSION)" && \
@@ -145,26 +48,35 @@ actions BuildOSXPackage
       cp COPYING "HandBrake $(HB_VERSION)/COPYING.txt" && \
       cp CREDITS "HandBrake $(HB_VERSION)/CREDITS.txt" && \
       cp THANKS "HandBrake $(HB_VERSION)/THANKS.txt" && \
-      ( cd doc && ./genhtml.sh ) && \
-      cp doc/faq.html "HandBrake $(HB_VERSION)/FAQ.html" && \
+      ( echo "[InternetShortcut]" && \
+        echo "URL=http://handbrake.m0k.org/" ) > \
+        "HandBrake $(HB_VERSION)/HandBrake Homepage.url" && \
+      ( echo "[InternetShortcut]" && \
+        echo "URL=http://handbrake.m0k.org/forum/" ) > \
+        "HandBrake $(HB_VERSION)/HandBrake Forums.url" && \
+      ( echo "[InternetShortcut]" && \
+        echo "URL=http://handbrake.m0k.org/contribute.php" ) > \
+        "HandBrake $(HB_VERSION)/Contribute.url" && \
       cp -r HandBrake.app "HandBrake $(HB_VERSION)" && \
       zip -9 -r $(<) "HandBrake $(HB_VERSION)" && \
       rm -rf "HandBrake $(HB_VERSION)"
 }
 
-rule SystemLibraries
+rule BeOSPackage 
 {
-    LINKLIBS on [ FAppendSuffix $(<) : $(SUFEXE) ] +=  $(>) ;
-}
-
-# Jambase's ObjectHdrs doesn't seem to work when ObjectHdrs is called
-# several times on a file, and it doesn't works for asm files. Fixed
-# here.
-rule ObjectHdrs
-{
-    local s = [ FGristFiles $(<:S=$(SUFOBJ)) ] ;
-    HDRS   on $(s) += $(>) ;
-    ASHDRS on $(s) += [ FIncludes $(>) ] ;
-    CCHDRS on $(s) += [ FIncludes $(>) ] ;
+    Depends         $(<) : $(>) ;
+    BuildBeOSPackage $(<) ;
+}   
+actions BuildBeOSPackage
+{                 
+    rm -rf $(<) "HandBrake $(HB_VERSION)" && \
+      mkdir "HandBrake $(HB_VERSION)" && \
+      cp AUTHORS "HandBrake $(HB_VERSION)/AUTHORS.txt" && \
+      cp COPYING "HandBrake $(HB_VERSION)/COPYING.txt" && \
+      cp CREDITS "HandBrake $(HB_VERSION)/CREDITS.txt" && \
+      cp THANKS "HandBrake $(HB_VERSION)/THANKS.txt" && \
+      xres -o HandBrake beos/HandBrake.rsrc && \
+      cp HandBrake "HandBrake $(HB_VERSION)" && \
+      zip -9 -r $(<) "HandBrake $(HB_VERSION)" && \
+      rm -rf "HandBrake $(HB_VERSION)"
 }
-
diff --git a/NEWS b/NEWS
index 5251428..9f06cfe 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,30 @@
-$Id: NEWS,v 1.15 2004/05/25 17:48:52 titer Exp $
+$Id: NEWS,v 1.28 2005/11/04 16:01:19 titer Exp $
 
 NEWS file for HandBrake <http://handbrake.m0k.org/>
 
+Changed between 0.7.0-beta3 and 0.7.0
+ + Multithreaded H.264 encoding with x264
+ + Added option for H.264 Baseline (suitable for iPods)
+ + (Very) experimental queue support
+ + Fixes for some DVD titles HandBrake would not recognize
+ + Fixes audio gliches when encoding from LPCM tracks
+
+Changed between 0.6.2 and 0.7.0-beta3
+ + Chapters selection
+ + Custom framerate
+ + Subtitle support
+ + Check for updates
+ + Custom aspect ratio
+ + Audio samplerate selection
+ + mp4/H.264 output
+ + Proper NTSC support
+ + AC3 pass-through
+ + Progress bar in the dock icon (OS X)
+ + 2-pass H.264 encoding
+ + Constant quality encoding
+ + Grayscale encoding
+ + Up-to-date BeOS UI
+
 Changes between 0.6.1 and 0.6.2
  + Support for DVDs with MPEG audio tracks
  + Rewrote the DVD navigation code
diff --git a/THANKS b/THANKS
index ec543c2..81b04f4 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -1,4 +1,4 @@
-$Id: THANKS,v 1.13 2004/04/22 22:49:07 titer Exp $
+$Id: THANKS,v 1.16 2004/08/05 17:03:05 titer Exp $
 
 THANKS file for HandBrake <http://handbrake.m0k.org/>
 
@@ -31,7 +31,7 @@ Leendert
  + Dutch translation
 
 Eric Kornblum
- + Sent me a sample DVD with LPCM tracks so I could add support for it
+ + Sent me a sample DVD with LPCM tracks
 
 migol Superkid
  + Spanish translation
@@ -42,3 +42,14 @@ pgjw
 cygma
  + Japanese translation
 
+Michelle De Sio
+ + Sent me a sample DVD with MPEG audio tracks
+
+Ian Rickard
+ + Enhanced icon
+
+Sébastien Noël
+ + Debian packages (http://www.twolife.org/debian/repository.php)
+
+People who sent me an iTunes gift certificate: a BIG thanks!
+
diff --git a/TODO b/TODO
deleted file mode 100644 (file)
index cfa765a..0000000
--- a/TODO
+++ /dev/null
@@ -1,45 +0,0 @@
-$Id: TODO,v 1.36 2004/05/25 17:48:52 titer Exp $
-
-TODO file for HandBrake <http://handbrake.m0k.org/>
-
-This is a roadmap for future releases of HandBrake. It has to be taken
-as an indication, as it may change as any time.
-
-0.6.x
- + Up-to-date BeOS GUI
-
-0.7.x
- + 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
-
-Maybe in 0.7.x
- + 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
- + Network shared processing (using RendezVous?)
- + VCD/DVD-R output
- + Theora encoding
- + Raw MPEG/AC3 output
- + DVD folder output
- + Use the DVD name in popup and for the name of the created file
- + 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
- + [OSX] opengl effects somtimes mess up the picture's brightness
-
index add6259..702c74d 100644 (file)
@@ -1,5 +1,8 @@
 #include "HBApp.h"
-#include "HBWindow.h"
+#include "MainWindow.h"
+#include "ScanWindow.h"
+
+#include "hb.h"
 
 int main()
 {
@@ -10,9 +13,18 @@ int main()
 }
 
 HBApp::HBApp()
-    : MApplication( "application/x-vnd.titer-handbrake" )
+    : BApplication( "application/x-vnd.titer-handbrake" )
 {
-    fWindow = new HBWindow();
+    fHandle = hb_init( HB_DEBUG_ALL, 0 );
+    
+    fMainWin = new MainWindow( fHandle );
+    fScanWin = new ScanWindow( fHandle );
+    fScanWin->AddToSubset( fMainWin );
+
+    fMainWin->Show();
+    fScanWin->Show();
+
+    SetPulseRate( 200000 ); /* 0.2 second */
 }
 
 void HBApp::MessageReceived( BMessage * message )
@@ -20,7 +32,7 @@ void HBApp::MessageReceived( BMessage * message )
     switch( message->what )
     {
         default:
-            MApplication::MessageReceived( message );
+            BApplication::MessageReceived( message );
             break;
     }
 }
@@ -29,3 +41,45 @@ void HBApp::RefsReceived( BMessage * message )
 {
 }
 
+void HBApp::Pulse()
+{
+    hb_state_t s;
+    hb_get_state( fHandle, &s );
+
+    switch( s.state )
+    {
+        case HB_STATE_IDLE:
+            break;
+
+        case HB_STATE_SCANNING:
+            fScanWin->Update( &s );
+            break;
+
+        case HB_STATE_SCANDONE:
+            if( hb_list_count( hb_get_titles( fHandle ) ) )
+            {
+                /* Success */
+                fScanWin->Hide();
+                fMainWin->Update( &s );
+            }
+            else
+            {
+                /* Invalid volume */
+                fScanWin->Update( &s );
+            }
+            break;
+
+        case HB_STATE_WORKING:
+        case HB_STATE_PAUSED:
+        case HB_STATE_WORKDONE:
+            fMainWin->Update( &s );
+            break;
+    }
+}
+
+bool HBApp::QuitRequested()
+{
+    hb_close( &fHandle );
+    return BApplication::QuitRequested();
+}
+
index 75f3fc1..042a791 100644 (file)
@@ -1,19 +1,27 @@
-#ifndef HB_HB_APP_H
-#define HB_HB_APP_H
+#ifndef HB_APP_H
+#define HB_APP_H
 
-#include "layout-all.h"
+#include <Application.h>
 
-class HBWindow;
+#include "hb.h"
 
-class HBApp : public MApplication
+class MainWindow;
+class ScanWindow;
+
+class HBApp : public BApplication
 {
     public:
-             HBApp();
-        void MessageReceived( BMessage * message );
-        void RefsReceived( BMessage * message );
+                     HBApp();
+        void         MessageReceived( BMessage * message );
+        void         RefsReceived( BMessage * message );
+        void         Pulse();
+        bool         QuitRequested();
 
     private:
-        HBWindow * fWindow;
+        MainWindow * fMainWin;
+        ScanWindow * fScanWin;
+        
+        hb_handle_t * fHandle;
 };
 
 #endif
diff --git a/beos/HBWindow.cpp b/beos/HBWindow.cpp
deleted file mode 100644 (file)
index 4bb51d6..0000000
+++ /dev/null
@@ -1,283 +0,0 @@
-#include "HBWindow.h"
-
-#include <MenuItem.h>
-#include <Screen.h>
-
-#define SCAN_OPEN 'scop'
-#define RIP_RIP   'riri'
-
-static void _Scanning( void * data, int title, int titleCount )
-{
-    ((HBWindow*)data)->Scanning( title, titleCount );
-}
-static void _ScanDone( void * data, HBList * titleList )
-{
-    ((HBWindow*)data)->ScanDone( titleList );
-}
-static void _Encoding( void * data, float position, int pass,
-                      int passCount, float frameRate,
-                      float avgFrameRate, int remainingTime )
-{
-    ((HBWindow*)data)->Encoding( position, pass, passCount, frameRate,
-                                 avgFrameRate, remainingTime );
-}
-static void _RipDone( void * data, int result )
-{
-    ((HBWindow*)data)->RipDone( result );
-}
-
-HBWindow::HBWindow()
-    : MWindow( BRect( 0,0,10,10 ), "HandBrake " HB_VERSION,
-               B_TITLED_WINDOW, 0 )
-{
-    /* Init libhb */
-    HBCallbacks callbacks;
-    callbacks.data     = this;
-    callbacks.scanning = _Scanning;
-    callbacks.scanDone = _ScanDone;
-    callbacks.encoding = _Encoding;
-    callbacks.ripDone  = _RipDone;
-
-    fHandle = HBInit( 1, 0 );
-    HBSetCallbacks( fHandle, callbacks );
-
-    fScanView = new HGroup(
-        new Space( minimax( 10,-1,10,-1 ) ),
-        new VGroup(
-          new Space( minimax( -1,10,-1,10 ) ),
-          new MStringView( "Welcome to HandBrake. Select a DVD to open:" ),
-          new Space( minimax( -1,5,-1,5 ) ),
-          new HGroup(
-            fScanRadio = new MRadioGroup( "Detected volume:",
-                "DVD Folder:", 0 ),
-            new VGroup(
-              fScanDetectedPopup = new MPopup( NULL,
-                  "/Bulk/ANGEL_SEASON2_DISC6", 0 ),
-              fScanFolderControl = new MTextControl( NULL, NULL ),
-              0 ),
-            0 ),
-          fScanBrowseButton = new MButton( "Browse", 12 ),
-          fScanStatusString = new MStringView( "" ),
-          fScanProgress = new MProgressBar( this ),
-          fScanOpenButton = new MButton( "Open",
-              new BMessage( SCAN_OPEN ) ),
-          new Space( minimax( -1,10,-1,10000 ) ),
-          0 ),
-        new Space( minimax( 10,-1,10,-1 ) ),
-        0 );
-
-    fScanDetectedPopup->Menu()->ItemAt(0)->SetMarked(true);
-    fScanProgress->ct_mpm = minimax( 0,12,10000,12 );
-
-    fRipView = new HGroup(
-        new Space( minimax( 10,-1,10,-1 ) ),
-        new VGroup(
-          new Space( minimax( -1,10,-1,10 ) ),
-          new MBorder(
-            M_LABELED_BORDER, 15, "General",
-            new VGroup(
-              fRipTitlePopup = new MPopup( "DVD title:", "dummy", 0 ),
-              new MPopup( "Output format:",
-                  "MP4 file / MPEG-4 video / AAC audio",
-                  "OGM file / MPEG-4 video / Vorbis audio",
-                  "AVI file / MPEG-4 video / MP3 audio",
-                  "AVI file / H264 video / MP3 audio", 0 ),
-              new MTextControl( "File:", "/boot/home/Desktop/Movie.mp4" ),
-              new MButton( "Browse" ),
-              0 )
-            ),
-          new MBorder(
-            M_LABELED_BORDER, 15, "Video",
-            new VGroup(
-              new MPopup( "MPEG-4 encoder:", "FFmpeg", "XviD", 0 ),
-              new HGroup(
-                new MStringView( "Bitrate:" ),
-                new MRadioGroup( "Custom (kbps)", "Target size (MB)", 0 ),
-                new VGroup(
-                  new MTextControl( NULL, NULL ),
-                  new MTextControl( NULL, NULL ),
-                  0 ),
-                0 ),
-              new MSplitter(),
-              new HGroup(
-                new MCheckBox( "2-pass encoding" ),
-                new MButton( "Crop & Scale..." ),
-                0 ),
-              0 )
-            ),
-          new MBorder(
-            M_LABELED_BORDER, 15, "Audio",
-            new VGroup(
-              fRipLanguage1Popup = new MPopup( "Language 1:",
-                  "dummy", 0 ),
-              fRipLanguage2Popup = new MPopup( "Language 2 (optional):",
-                  "dummy", 0 ),
-              fRipBitratePopup = new MPopup( "Bitrate (kbps):", "32",
-                  "64", "96", "128", "160", "192", "224", "256", "288",
-                  "320", 0 ),
-              0 )
-            ),
-          new MProgressBar( this ),
-          new HGroup(
-            new MButton( "Pause" ),
-            new MButton( "Rip!", new BMessage( RIP_RIP ) ),
-            0 ),
-          new Space( minimax( -1,10,-1,10 ) ),
-          0 ),
-        new Space( minimax( 10,-1,10,-1 ) ),
-        0 );
-
-    fRipBitratePopup->Menu()->ItemAt(3)->SetMarked( true );
-
-    fLayers = new LayeredGroup( fScanView, fRipView, 0 );
-    AddChild( dynamic_cast<BView*>(fLayers) );
-
-    /* Center the window */
-    BScreen screen;
-    MoveTo( ( screen.Frame().Width() ) / 2,
-            ( screen.Frame().Height() ) / 2 );
-    
-    Show();
-}
-
-bool HBWindow::QuitRequested()
-{
-    HBClose( &fHandle );
-    be_app->PostMessage( B_QUIT_REQUESTED );
-    return true;
-}
-
-void HBWindow::MessageReceived( BMessage * message )
-{
-    switch( message->what )
-    {
-        case SCAN_OPEN:
-            Lock();
-            /* That's ugly, but there doesn't seem to be another way */
-            ((BRadioButton*)fScanRadio->ChildAt(0))->SetEnabled( false );
-            ((BRadioButton*)fScanRadio->ChildAt(1))->SetEnabled( false );
-            fScanDetectedPopup->SetEnabled( false );
-            fScanFolderControl->SetEnabled( false );
-            fScanBrowseButton->SetEnabled( false );
-            fScanOpenButton->SetEnabled( false );
-            fScanStatusString->SetText( "Opening device..." );
-            Unlock();
-            HBScanDVD( fHandle,
-                fScanDetectedPopup->Menu()->FindMarked()->Label(), 0 );
-            break;
-
-        case RIP_RIP:
-        {
-            HBTitle * title = (HBTitle*) HBListItemAt( fTitleList,
-                    fRipTitlePopup->Menu()->IndexOf(
-                        fRipTitlePopup->Menu()->FindMarked() ) );
-            title->file = strdup( "/boot/home/Desktop/Movie.mp4" );
-            title->twoPass = 0;
-            title->deinterlace = 0;
-            title->topCrop    = title->autoTopCrop;
-            title->bottomCrop = title->autoBottomCrop;
-            title->leftCrop   = title->autoLeftCrop;
-            title->rightCrop  = title->autoRightCrop;
-            title->bitrate = 1024;
-            title->codec = HB_CODEC_FFMPEG;
-            title->mux = HB_MUX_MP4;
-            HBAudio * audio = (HBAudio*) HBListItemAt(
-                    title->audioList, 0 );
-            audio->codec = HB_CODEC_AAC;
-            audio->outBitrate = 128;
-            HBListAdd( title->ripAudioList, audio );
-            HBStartRip( fHandle, title );
-            break;
-        }
-
-        default:
-            MWindow::MessageReceived( message );
-            break;
-    }
-}
-
-void HBWindow::Scanning( int title, int titleCount )
-{
-    Lock();
-    char string[1024]; memset( string, 0, 1024 );
-    snprintf( string, 1023, "Scanning title %d of %d...",
-              title, titleCount );
-    fScanStatusString->SetText( string );
-    fScanProgress->SetValue( (float) title / titleCount );
-    Unlock();
-}
-
-void HBWindow::ScanDone( HBList * titleList )
-{
-#define menu fRipTitlePopup->Menu()
-    Lock();
-    BMenuItem * item;
-    while( ( item = menu->ItemAt(0) ) )
-    {
-        menu->RemoveItem( item );
-        delete item;
-    }
-    HBTitle * title;
-    char      label[1024];
-    for( int i = 0; i < HBListCount( titleList ); i++ )
-    {
-        memset( label, 0, 1024 );
-        title = (HBTitle*) HBListItemAt( titleList, i );
-        snprintf( label, 1023, "%d - %02dh%02dm%02ds", title->index,
-                  title->length / 3600, ( title->length % 3600 ) / 60,
-                  title->length % 60 );
-        menu->AddItem( new BMenuItem( label, NULL ) );
-    }
-    menu->ItemAt(0)->SetMarked( true );
-    fTitleList = titleList;
-    UpdateLanguages();
-    fLayers->ActivateLayer( 1 );
-    Unlock();
-#undef menu
-}
-
-void HBWindow::Encoding( float position, int pass, int passCount,
-               float frameRate, float avgFrameRate,
-               int remainingTime )
-{
-}
-
-void HBWindow::RipDone( int result )
-{
-}
-
-void HBWindow::UpdateLanguages()
-{
-#define menu fRipTitlePopup->Menu()
-    HBTitle * title = (HBTitle*) HBListItemAt( fTitleList,
-            menu->IndexOf( menu->FindMarked() ) );
-#undef menu
-
-#define menu1 fRipLanguage1Popup->Menu()
-#define menu2 fRipLanguage2Popup->Menu()
-    BMenuItem * item;
-    while( ( item = menu1->ItemAt(0) ) )
-    {
-        menu1->RemoveItem( item );
-        delete item;
-    }
-    while( ( item = menu2->ItemAt(0) ) )
-    {
-        menu2->RemoveItem( item );
-        delete item;
-    }
-   
-    HBAudio * audio;
-    for( int i = 0; i < HBListCount( title->audioList ); i++ )
-    {
-        audio = (HBAudio*) HBListItemAt( title->audioList, i );
-        menu1->AddItem( new BMenuItem( audio->language, NULL ) );
-        menu2->AddItem( new BMenuItem( audio->language, NULL ) );
-    }
-    menu1->ItemAt(0)->SetMarked( true );
-    menu2->AddItem( new BMenuItem( "None", NULL ) );
-    menu2->ItemAt( menu2->CountItems() - 1 )->SetMarked( true );
-#undef menu1
-#undef menu2
-}
-
diff --git a/beos/HBWindow.h b/beos/HBWindow.h
deleted file mode 100644 (file)
index 52ddfbf..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-#include "layout-all.h"
-#include "HandBrake.h"
-
-class HBWindow : public MWindow
-{
-    public:
-        HBWindow();
-        bool QuitRequested();
-        void MessageReceived( BMessage * message );
-
-        void Scanning( int title, int titleCount );
-        void ScanDone( HBList * titleList );
-        void Encoding( float position, int pass, int passCount,
-                       float frameRate, float avgFrameRate,
-                       int remainingTime );
-        void RipDone( int result );
-
-    private:
-        void UpdateLanguages();
-        
-        HBHandle * fHandle;
-        HBList   * fTitleList;
-
-        LayeredGroup * fLayers;
-        
-        MView        * fScanView;
-        MRadioGroup  * fScanRadio;
-        MPopup       * fScanDetectedPopup;
-        MTextControl * fScanFolderControl;
-        MButton      * fScanBrowseButton;
-        MStringView  * fScanStatusString;
-        MProgressBar * fScanProgress;
-        MButton      * fScanOpenButton;
-
-        MView * fRipView;
-        MPopup * fRipTitlePopup;
-        MPopup * fRipLanguage1Popup;
-        MPopup * fRipLanguage2Popup;
-        MPopup * fRipBitratePopup;
-};
-
diff --git a/beos/MainWindow.cpp b/beos/MainWindow.cpp
new file mode 100644 (file)
index 0000000..5b2741b
--- /dev/null
@@ -0,0 +1,986 @@
+#include <app/Application.h>
+#include <interface/Box.h>
+#include <interface/Button.h>
+#include <interface/CheckBox.h>
+#include <interface/MenuField.h>
+#include <interface/MenuItem.h>
+#include <interface/PopUpMenu.h>
+#include <interface/RadioButton.h>
+#include <interface/Screen.h>
+#include <interface/Slider.h>
+#include <interface/StatusBar.h>
+#include <interface/StringView.h>
+#include <interface/TextControl.h>
+#include <storage/FilePanel.h>
+#include <storage/Path.h>
+#include <support/String.h>
+
+#include "MainWindow.h"
+#include "PicWindow.h"
+#include "QueueWindow.h"
+
+#define MSG_TITLEPOPUP   'titl'
+#define MSG_CHAPTERPOPUP 'chap'
+#define MSG_FORMATPOPUP  'form'
+#define MSG_CODECSPOPUP  'code'
+#define MSG_BROWSE       'brow'
+#define MSG_QUALITYRADIO 'radi'
+#define MSG_SLIDER       'slid'
+#define MSG_PICSETTINGS  'pise'
+#define MSG_QUEUE_ENABLE 'quen'
+#define MSG_QUEUE_ADD    'quad'
+#define MSG_QUEUE_SHOW   'qush'
+#define MSG_PAUSE        'paus'
+#define MSG_START        'star'
+
+static int FormatSettings[3][4] =
+  { { HB_MUX_MP4 | HB_VCODEC_FFMPEG | HB_ACODEC_FAAC,
+      HB_MUX_MP4 | HB_VCODEC_X264   | HB_ACODEC_FAAC,
+      0,
+      0 },
+    { HB_MUX_AVI | HB_VCODEC_FFMPEG | HB_ACODEC_LAME,
+      HB_MUX_AVI | HB_VCODEC_FFMPEG | HB_ACODEC_AC3,
+      HB_MUX_AVI | HB_VCODEC_X264   | HB_ACODEC_LAME,
+      HB_MUX_AVI | HB_VCODEC_X264   | HB_ACODEC_AC3 },
+    { HB_MUX_OGM | HB_VCODEC_FFMPEG | HB_ACODEC_VORBIS,
+      HB_MUX_OGM | HB_VCODEC_FFMPEG | HB_ACODEC_LAME,
+      0,
+      0 } };
+
+MainView::MainView( hb_handle_t * handle )
+    : BView( BRect( 0,0,700,475 ), NULL, B_FOLLOW_NONE, B_WILL_DRAW )
+{
+    fHandle = handle;
+
+    BRect r, b;
+    BBox * box;
+    
+    SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) );
+
+    /* Source box */
+    b = Bounds();
+    r = BRect( 10,10,b.right/2-5,135 );
+    box = new BBox( r );
+    box->SetLabel( "Source" );
+    AddChild( box );
+
+    b = box->Bounds();
+
+    r = BRect( 10,15,b.right/4,35 );
+    fSrcDVD1String = new BStringView( r, NULL, "DVD:" );
+    box->AddChild( fSrcDVD1String );
+
+    r = BRect( b.right/4+1,15,b.right-10,35 );
+    fSrcDVD2String = new BStringView( r, NULL, "" );
+    fSrcDVD2String->SetAlignment( B_ALIGN_RIGHT );
+    box->AddChild( fSrcDVD2String );
+
+    r = BRect( 10,40,b.right-10,60 );
+    fSrcTitlePopUp = new BPopUpMenu( "" );
+    fSrcTitleMenu  = new BMenuField( r, NULL, "Title:", fSrcTitlePopUp,
+                                     true );
+    fSrcTitleMenu->SetDivider( b.right-130 );
+    box->AddChild( fSrcTitleMenu );
+
+    r = BRect( 10,65,b.right-120,85 );
+    fSrcChapString = new BStringView( r, NULL, "Chapters:" );
+    box->AddChild( fSrcChapString );
+    
+    r = BRect( b.right-119,65,b.right-80,85 );
+    fSrcChapStartPopUp = new BPopUpMenu( "" );
+    fSrcChapStartMenu  = new BMenuField( r, NULL, "",
+                                         fSrcChapStartPopUp, true );
+    fSrcChapStartMenu->SetDivider( 0.0 );
+    box->AddChild( fSrcChapStartMenu );
+
+    r = BRect( b.right-79,65,b.right-50,85 );
+    fSrcChapToString = new BStringView( r, NULL, "to" );
+    fSrcChapToString->SetAlignment( B_ALIGN_CENTER );
+    box->AddChild( fSrcChapToString );
+    
+    r = BRect( b.right-49,65,b.right-10,85 );
+    fSrcChapEndPopUp = new BPopUpMenu( "" );
+    fSrcChapEndMenu  = new BMenuField( r, NULL, "", fSrcChapEndPopUp,
+                                       true );
+    fSrcChapEndMenu->SetDivider( 0.0 );
+    box->AddChild( fSrcChapEndMenu );
+
+    r = BRect( 10,90,b.right/2,110 );
+    fSrcDur1String = new BStringView( r, NULL, "Duration:" );
+    box->AddChild( fSrcDur1String );
+
+    r = BRect( b.right/2+1,90,b.right-10,110 );
+    fSrcDur2String = new BStringView( r, NULL, "00:00:00" );
+    fSrcDur2String->SetAlignment( B_ALIGN_RIGHT );
+    box->AddChild( fSrcDur2String );
+
+    /* Destination box */
+    b = Bounds();
+    r = BRect( b.right/2+5,10,b.right-10,135 );
+    box = new BBox( r );
+    box->SetLabel( "Destination" );
+    AddChild( box );
+
+    b = box->Bounds();
+
+    r = BRect( 10,15,b.right-10,35 );
+    fDstFormatPopUp = new BPopUpMenu( "" );
+#define ADDITEM(a) fDstFormatPopUp->AddItem( new BMenuItem( a, \
+    new BMessage( MSG_FORMATPOPUP ) ) )
+    ADDITEM( "MP4 file" );
+    ADDITEM( "AVI file" );
+    ADDITEM( "OGM file" );
+#undef ADDITEM
+    fDstFormatPopUp->ItemAt( 0 )->SetMarked( true );
+    fDstFormat = -1;
+    fDstFormatMenu = new BMenuField( r, NULL, "File format:",
+                                     fDstFormatPopUp, true );
+    fDstFormatMenu->SetDivider( b.right/3 );
+    box->AddChild( fDstFormatMenu );
+
+    r = BRect( 10,40,b.right-10,60 );
+    fDstCodecsPopUp = new BPopUpMenu( "" );
+    fDstCodecsMenu  = new BMenuField( r, NULL, "Codecs:",
+                                      fDstCodecsPopUp, true );
+    fDstCodecsMenu->SetDivider( b.right/3 );
+    box->AddChild( fDstCodecsMenu );
+
+    r = BRect( 10,65,b.right-10,85 );
+    fDstFileControl = new BTextControl( r, NULL, "File:",
+        "/boot/home/Desktop/Movie", new BMessage() );
+    fDstFileControl->SetDivider( b.right/3 );
+    box->AddChild( fDstFileControl );
+
+    r = BRect( b.right-90,90,b.right-10,115 );
+    fBrowseButton = new BButton( r, NULL, "Browse",
+                                 new BMessage( MSG_BROWSE ) );
+    box->AddChild( fBrowseButton );
+
+    /* Video box */
+    b = Bounds();
+    r = BRect( 10,145,b.right/2-5,395 );
+    box = new BBox( r );
+    box->SetLabel( "Video" );
+    AddChild( box );
+
+    b = box->Bounds();
+
+    r = BRect( 10,15,b.right-10,35 );
+    fVidRatePopUp = new BPopUpMenu( "" );
+    fVidRatePopUp->AddItem( new BMenuItem( "Same as source",
+        new BMessage() ) );
+    for( int i = 0; i < hb_video_rates_count; i++ )
+    {
+        fVidRatePopUp->AddItem( new BMenuItem( hb_video_rates[i].string,
+            new BMessage() ) );
+    }
+    fVidRatePopUp->ItemAt( 0 )->SetMarked( true );
+    fVidRateMenu = new BMenuField( r, NULL, "Framerate (fps):",
+                                   fVidRatePopUp, true );
+    box->AddChild( fVidRateMenu );
+
+    r = BRect( 10,40,b.right-10,60 );
+    fVidEncoderPopUp = new BPopUpMenu( "" );
+    fVidEncoderMenu  = new BMenuField( r, NULL, "Encoder:",
+                                       fVidEncoderPopUp, true );
+    box->AddChild( fVidEncoderMenu );
+
+    r = BRect( 10,65,b.right-10,85 );
+    fVidQualityString = new BStringView( r, NULL, "Quality:" );
+    box->AddChild( fVidQualityString );
+
+    r = BRect( 10,90,b.right*2/3,110);
+    fVidTargetRadio = new BRadioButton( r, NULL, "Target size (MB):",
+        new BMessage( MSG_QUALITYRADIO ) );
+    box->AddChild( fVidTargetRadio );
+
+    r = BRect( b.right*2/3+1,90,b.right-10,110); 
+    fVidTargetControl = new BTextControl( r, NULL, "", "700",
+        new BMessage() );
+    fVidTargetControl->SetDivider( 0 );
+    box->AddChild( fVidTargetControl );
+
+    r = BRect( 10,115,b.right/2,135);
+    fVidAverageRadio = new BRadioButton( r, NULL, "Average bitrate (kbps):",
+        new BMessage( MSG_QUALITYRADIO ) );
+    fVidAverageRadio->SetValue( 1 );
+    box->AddChild( fVidAverageRadio );
+
+    r = BRect( b.right*2/3+1,115,b.right-10,135); 
+    fVidAverageControl = new BTextControl( r, NULL, "", "1000",
+        new BMessage() );
+    fVidAverageControl->SetDivider( 0 );
+    box->AddChild( fVidAverageControl );
+
+    r = BRect( 10,140,b.right/2,160);
+    fVidConstantRadio = new BRadioButton( r, NULL, "Constant quality:",
+        new BMessage( MSG_QUALITYRADIO ) );
+    box->AddChild( fVidConstantRadio );
+
+    r = BRect( 20,165,b.right-10,195);
+    fVidConstantSlider = new BSlider( r, NULL, NULL,
+        new BMessage( MSG_SLIDER ), 0, 100 );
+    fVidConstantSlider->SetValue( 50 );
+    SliderChanged();
+    box->AddChild( fVidConstantSlider );
+
+    r = BRect( 10,200,b.right-10,220);
+    fVidGrayCheck = new BCheckBox( r, NULL, "Grayscale encoding", new BMessage() );
+    box->AddChild( fVidGrayCheck );
+    r = BRect( 10,220,b.right-10,240);
+    fVidTwoPassCheck = new BCheckBox( r, NULL, "2-pass encoding", new BMessage() );
+    box->AddChild( fVidTwoPassCheck );
+
+    /* Subtitles box */
+    b = Bounds();
+    r = BRect( b.right/2+5,145,b.right-10,190 );
+    box = new BBox( r );
+    box->SetLabel( "Subtitles" );
+    AddChild( box );
+
+    b = box->Bounds();
+
+    r = BRect( 10,15,b.right-10,35 );
+    fSubPopUp = new BPopUpMenu( "" );
+    fSubMenu  = new BMenuField( r, NULL, "Language:",
+                                fSubPopUp, true );
+    box->AddChild( fSubMenu );
+
+    /* Audio box */
+    b = Bounds();
+    r = BRect( b.right/2+5,200,b.right-10,320 );
+    box = new BBox( r );
+    box->SetLabel( "Audio" );
+    AddChild( box );
+
+    b = box->Bounds();
+
+    r = BRect( 10,15,b.right-10,35 );
+    fAudLang1PopUp = new BPopUpMenu( "" );
+    fAudLang1Menu  = new BMenuField( r, NULL, "Language 1:",
+                                     fAudLang1PopUp, true );
+    box->AddChild( fAudLang1Menu );
+    r = BRect( 10,40,b.right-10,60 );
+    fAudLang2PopUp = new BPopUpMenu( "" );
+    fAudLang2Menu = new BMenuField( r, NULL, "Language 2:",
+                                    fAudLang2PopUp, true );
+    box->AddChild( fAudLang2Menu );
+    r = BRect( 10,65,b.right-10,85 );
+    fAudRatePopUp = new BPopUpMenu( "" );
+    for( int i = 0; i < hb_audio_rates_count; i++ )
+    {
+        fAudRatePopUp->AddItem( new BMenuItem( hb_audio_rates[i].string,
+            new BMessage ) );
+    }
+    fAudRatePopUp->ItemAt( hb_audio_rates_default )->SetMarked( true );
+    fAudRateMenu = new BMenuField( r, NULL, "Sample rate (Hz):",
+                                   fAudRatePopUp, true );
+    box->AddChild( fAudRateMenu );
+    r = BRect( 10,90,b.right-10,110 );
+    fAudBitratePopUp = new BPopUpMenu( "" );
+    for( int i = 0; i < hb_audio_bitrates_count; i++ )
+    {
+        fAudBitratePopUp->AddItem( new BMenuItem(
+            hb_audio_bitrates[i].string, new BMessage ) );
+    }
+    fAudBitratePopUp->ItemAt(
+        hb_audio_bitrates_default )->SetMarked( true );
+    fAudBitrateMenu = new BMenuField( r, NULL, "Bitrate (kbps):",
+                                      fAudBitratePopUp, true );
+    box->AddChild( fAudBitrateMenu );
+
+    /* Picture settings */
+    b = Bounds();
+    r = BRect( b.right-110,370,b.right-10,395 );
+    fPictureButton = new BButton( r, NULL, "Picture settings...",
+                                  new BMessage( MSG_PICSETTINGS ) );
+    AddChild( fPictureButton );
+
+    /* Bottom */
+    r = BRect( 10,405,b.right-10,435 );
+    fProgressBar = new BStatusBar( r, NULL );
+    AddChild( fProgressBar );
+
+    r = BRect( 10,450,b.right-370,470);
+    fQueueCheck = new BCheckBox( r, NULL, "Enable Queue",
+                                 new BMessage( MSG_QUEUE_ENABLE ) );
+    AddChild( fQueueCheck );
+
+    r = BRect( b.right-360,445,b.right-280,470 );
+    fAddButton = new BButton( r, NULL, "Add to Queue",
+                              new BMessage( MSG_QUEUE_ADD ) );
+
+    r = BRect( b.right-270,445,b.right-190,470 );
+    fShowButton = new BButton( r, NULL, "Show queue",
+                               new BMessage( MSG_QUEUE_SHOW ) );
+
+    r = BRect( b.right-180,445,b.right-100,470 );
+    fPauseButton = new BButton( r, NULL, "Pause",
+                                new BMessage( MSG_PAUSE ) );
+    AddChild( fPauseButton );
+
+    r = BRect( b.right-90,445,b.right-10,470 );
+    fRipButton = new BButton( r, NULL, "Rip",
+                              new BMessage( MSG_START ) );
+    AddChild( fRipButton );
+
+    EnableUI( false );
+    fPauseButton->SetEnabled( false );
+    fRipButton->SetEnabled( false );
+
+    FormatPopUpChanged();
+
+    fFilePanel = NULL;
+}
+
+void MainView::HandleMessage( BMessage * msg )
+{
+    switch( msg->what )
+    {
+        case MSG_TITLEPOPUP:
+            TitlePopUpChanged();
+            break;
+
+        case MSG_CHAPTERPOPUP:
+            ChapterPopUpChanged();
+            break;
+
+        case MSG_FORMATPOPUP:
+            FormatPopUpChanged();
+            break;
+
+        case MSG_CODECSPOPUP:
+            CodecsPopUpChanged();
+            break;
+
+        case MSG_BROWSE:
+            if( !fFilePanel )
+            {
+                fFilePanel = new BFilePanel( B_SAVE_PANEL,
+                    new BMessenger( Window() ), NULL, 0, false );
+            }
+            fFilePanel->Show();
+            break;
+
+        case B_SAVE_REQUESTED:
+        {
+            entry_ref ref;
+            BString string;
+            if( msg->FindRef( "directory", 0, &ref ) == B_OK &&
+                msg->FindString( "name", &string ) == B_OK )
+            {
+                BPath * path = new BPath( &ref );
+                string.Prepend( "/" );
+                string.Prepend( path->Path() );
+                fDstFileControl->SetText( string.String() );
+                CheckExtension();
+            }
+            break;
+        }
+
+        case MSG_QUALITYRADIO:
+            QualityRadioChanged();
+            break;
+
+        case MSG_SLIDER:
+            SliderChanged();
+            break;
+
+        case MSG_PICSETTINGS:
+            fPicWin = new PicWindow( fHandle, fSrcTitlePopUp->IndexOf(
+                fSrcTitlePopUp->FindMarked() ) );
+            fPicWin->Show();
+            break;
+
+        case MSG_QUEUE_ENABLE:
+            if( fQueueCheck->Value() )
+            {
+                AddChild( fAddButton );
+                AddChild( fShowButton );
+            }
+            else
+            {
+                RemoveChild( fAddButton );
+                RemoveChild( fShowButton );
+            }
+            break;
+
+        case MSG_QUEUE_ADD:
+            AddJob();
+            break;
+
+        case MSG_QUEUE_SHOW:
+            fQueueWin = new QueueWindow( fHandle );
+            fQueueWin->Show();
+            break;
+
+        case MSG_PAUSE:
+            fPauseButton->SetEnabled( false );
+            fRipButton->SetEnabled( false );
+            if( !strcmp( fPauseButton->Label(), "Resume" ) )
+            {
+                hb_resume( fHandle );
+            }
+            else
+            {
+                hb_pause( fHandle );
+            }
+            break;
+
+        case MSG_START:
+        {
+            if( !strcmp( fRipButton->Label(), "Cancel" ) )
+            {
+                fPauseButton->SetEnabled( false );
+                fRipButton->SetEnabled( false );
+                hb_stop( fHandle );
+                break;
+            }
+
+            EnableUI( false );
+            fPauseButton->SetEnabled( false );
+            fRipButton->SetEnabled( false );
+
+            if( !fQueueCheck->Value() )
+            {
+                AddJob();
+            }
+
+            hb_start( fHandle );
+            break;
+        }
+    }
+}
+
+void MainView::Update( hb_state_t * s )
+{
+    if( !LockLooper() )
+    {
+        fprintf( stderr, "LockLooper failed\n" );
+        return;
+    }
+
+    switch( s->state )
+    {
+#define p s->param.scandone
+        case HB_STATE_SCANDONE:
+        {
+            hb_list_t  * list;
+            hb_title_t * title;
+            char         string[1024];
+
+            list = hb_get_titles( fHandle );
+            for( int i = 0; i < hb_list_count( list ); i++ )
+            {
+                title = (hb_title_t *) hb_list_item( list, i );
+                fSrcDVD2String->SetText( title->dvd );
+                snprintf( string, 1024, "%d - %02dh%02dm%02ds",
+                          title->index, title->hours, title->minutes,
+                          title->seconds );
+                fSrcTitlePopUp->AddItem( new BMenuItem( string,
+                    new BMessage( MSG_TITLEPOPUP ) ) );
+            }
+            fSrcTitlePopUp->ItemAt( 0 )->SetMarked( true );
+            fSrcTitle = -1;
+            TitlePopUpChanged();
+
+            EnableUI( true );
+            fRipButton->SetEnabled( true );
+            fPauseButton->SetEnabled( false );
+            break;
+        }
+#undef p
+
+#define p s->param.working
+        case HB_STATE_WORKING:
+        {
+            float progress_total;
+            char  text[1024];
+            progress_total = ( p.progress + p.job_cur - 1 ) / p.job_count;
+            snprintf( text, 1024, "Encoding: task %d of %d, %.2f %%",
+                      p.job_cur, p.job_count, 100.0 * p.progress );
+            if( p.seconds > -1 )
+            {
+                snprintf( text + strlen( text ), 1024 - strlen( text ),
+                          " (%.2f fps, avg %.2f fps, ETA %02dh%02dm%02ds)",
+                          p.rate_cur, p.rate_avg, p.hours, p.minutes,
+                          p.seconds );
+            }
+            fProgressBar->Update( fProgressBar->MaxValue() *
+                progress_total - fProgressBar->CurrentValue(), text );
+
+            fPauseButton->SetLabel( "Pause" );
+            fPauseButton->SetEnabled( true );
+            fRipButton->SetLabel( "Cancel" );
+            fRipButton->SetEnabled( true );
+            break;
+        }
+#undef p
+
+        case HB_STATE_PAUSED:
+            fProgressBar->Update( 0, "Paused" );
+            fPauseButton->SetLabel( "Resume" );
+            fPauseButton->SetEnabled( true );
+            fRipButton->SetLabel( "Cancel" );
+            fRipButton->SetEnabled( true );
+            break;          
+
+#define p s->param.workdone 
+        case HB_STATE_WORKDONE:
+            fProgressBar->Update( - fProgressBar->CurrentValue(),
+                                  "Done." );
+            EnableUI( true );
+            fPauseButton->SetLabel( "Pause" );
+            fPauseButton->SetEnabled( false );
+            fRipButton->SetLabel( "Rip" );
+            fRipButton->SetEnabled( true );
+
+            /* FIXME */
+            hb_job_t * job;
+            while( ( job = hb_job( fHandle, 0 ) ) )
+            {
+                hb_rem( fHandle, job );
+            }
+            break;
+#undef p
+    }
+
+    UnlockLooper();
+}
+
+void MainView::EnableUI( bool b )
+{
+
+    rgb_color mycolor;
+    mycolor.red = mycolor.green = mycolor.blue = b ? 0 : 128;
+    mycolor.alpha = 255;
+
+    BStringView * strings[] =
+      { fSrcDVD1String, fSrcDVD2String, fSrcChapString,
+        fSrcChapToString, fSrcDur1String, fSrcDur2String,
+        fVidQualityString };
+    for( unsigned i = 0; i < sizeof( strings ) / sizeof( void * ); i++ )
+    {
+        strings[i]->SetHighColor( mycolor );
+        strings[i]->Invalidate(); /* Force redraw */
+    }
+
+    BMenuField * fields[] =
+      { fSrcTitleMenu, fSrcChapStartMenu, fSrcChapEndMenu,
+        fDstFormatMenu, fDstCodecsMenu, fVidRateMenu, fVidEncoderMenu,
+        fSubMenu, fAudLang1Menu, fAudLang2Menu, fAudRateMenu,
+        fAudBitrateMenu };
+    for( unsigned i = 0; i < sizeof( fields ) / sizeof( void * ); i++ )
+    {
+        fields[i]->SetEnabled( b );
+    }
+
+    BControl * controls[] =
+      { fDstFileControl, fBrowseButton, fVidTargetRadio,
+        fVidTargetControl, fVidAverageRadio, fVidAverageControl,
+        fVidConstantRadio, fVidConstantSlider, fVidGrayCheck,
+        fVidTwoPassCheck, fPictureButton };
+    for( unsigned i = 0; i < sizeof( controls ) / sizeof( void * ); i++ )
+    {
+        controls[i]->SetEnabled( b );
+    }
+
+    if( b )
+    {
+        QualityRadioChanged();
+    }
+}
+
+void MainView::TitlePopUpChanged()
+{
+    int index = fSrcTitlePopUp->IndexOf( fSrcTitlePopUp->FindMarked() );
+    if( index == fSrcTitle )
+    {
+        /* No change actually */
+        return;
+    }
+    fSrcTitle = index;
+
+    /* Get a pointer to the title */
+    hb_list_t    * list;
+    hb_title_t   * title;
+    list  = hb_get_titles( fHandle );
+    title = (hb_title_t *) hb_list_item( list, index );
+
+    char text[1024];
+    BMenuItem * item;
+
+    /* Update chapters popups */
+    while( ( item = fSrcChapStartPopUp->RemoveItem( 0L ) ) )
+    {
+        delete item;
+    }
+    while( ( item = fSrcChapEndPopUp->RemoveItem( 0L ) ) )
+    {
+        delete item;
+    }
+    for( int i = 0; i < hb_list_count( title->list_chapter ); i++ )
+    {
+        snprintf( text, 1024, "%d", i + 1 );
+        fSrcChapStartPopUp->AddItem( new BMenuItem( text,
+            new BMessage( MSG_CHAPTERPOPUP ) ) );
+        fSrcChapEndPopUp->AddItem( new BMenuItem( text,
+            new BMessage( MSG_CHAPTERPOPUP ) ) );
+    }
+    fSrcChapStartPopUp->ItemAt( 0 )->SetMarked( true );
+    fSrcChapEndPopUp->ItemAt( hb_list_count( title->list_chapter )
+                                - 1 )->SetMarked( true );
+    ChapterPopUpChanged();
+
+    /* Update subtitles popup */
+    hb_subtitle_t * sub;
+    while( ( item = fSubPopUp->RemoveItem( 0L ) ) )
+    {
+        delete item;
+    }
+    fSubPopUp->AddItem( new BMenuItem( "None", new BMessage() ) );
+    for( int i = 0; i < hb_list_count( title->list_subtitle ); i++ )
+    {
+        sub = (hb_subtitle_t *) hb_list_item( title->list_subtitle, i );
+        fSubPopUp->AddItem( new BMenuItem( sub->lang, new BMessage() ) );
+    }
+    fSubPopUp->ItemAt( 0 )->SetMarked( true );
+
+    /* Update audio popups */
+    hb_audio_t * audio;
+    while( ( item = fAudLang1PopUp->RemoveItem( 0L ) ) )
+    {
+        delete item;
+    }
+    while( ( item = fAudLang2PopUp->RemoveItem( 0L ) ) )
+    {
+        delete item;
+    }
+    fAudLang1PopUp->AddItem( new BMenuItem( "None", new BMessage() ) );
+    fAudLang2PopUp->AddItem( new BMenuItem( "None", new BMessage() ) );
+    for( int i = 0; i < hb_list_count( title->list_audio ); i++ )
+    {
+        audio = (hb_audio_t *) hb_list_item( title->list_audio, i );
+        fAudLang1PopUp->AddItem( new BMenuItem( audio->lang, new BMessage() ) );
+        fAudLang2PopUp->AddItem( new BMenuItem( audio->lang, new BMessage() ) );
+    }
+    fAudLang1PopUp->ItemAt( 1 )->SetMarked( true );
+    fAudLang2PopUp->ItemAt( 0 )->SetMarked( true );
+}
+
+void MainView::ChapterPopUpChanged()
+{
+    /* Get a pointer to the title */
+    hb_list_t    * list;
+    hb_title_t   * title;
+    list  = hb_get_titles( fHandle );
+    title = (hb_title_t *) hb_list_item( list,
+        fSrcTitlePopUp->IndexOf( fSrcTitlePopUp->FindMarked() ) );
+
+    hb_chapter_t * chapter;
+    int64_t        duration = 0;
+    for( int i = fSrcChapStartPopUp->IndexOf(
+             fSrcChapStartPopUp->FindMarked() );
+         i <= fSrcChapEndPopUp->IndexOf(
+             fSrcChapEndPopUp->FindMarked() );
+         i++ )
+    {
+        chapter = (hb_chapter_t *) hb_list_item( title->list_chapter, i );
+        duration += chapter->duration;
+    }
+    duration /= 90000; /* pts -> seconds */
+
+    char text[1024];
+    snprintf( text, sizeof(text), "%02lld:%02lld:%02lld",
+              duration / 3600, ( duration / 60 ) % 60, duration % 60 );
+    fSrcDur2String->SetText( text );
+}
+
+void MainView::FormatPopUpChanged()
+{
+    int format;
+    BMenuItem * item;
+
+    format = fDstFormatPopUp->IndexOf( fDstFormatPopUp->FindMarked() );
+    if( format == fDstFormat )
+    {
+        /* No change actually */
+        CheckExtension();
+        return;
+    }
+    fDstFormat = format;
+
+    /* Empty codecs popup */
+    while( ( item = fDstCodecsPopUp->RemoveItem( 0L ) ) )
+    {
+        delete item;
+    }
+
+    /* Add acceptable video codec / audio codec combinations */
+#define ADDITEM(a) \
+    fDstCodecsPopUp->AddItem( new BMenuItem( a, new BMessage( MSG_CODECSPOPUP ) ) )
+    switch( format )
+    {
+        case 0:
+            ADDITEM( "MPEG-4 Video / AAC Audio" );
+            ADDITEM( "AVC/H.264 Video / AAC Audio" );
+            break;
+        case 1:
+            ADDITEM( "MPEG-4 Video / MP3 Audio" );
+            ADDITEM( "MPEG-4 Video / AC-3 Audio" );
+            ADDITEM( "AVC/H.264 Video / MP3 Audio" );
+            ADDITEM( "AVC/H.264 Video / AC-3 Audio" );
+            break;
+        case 2:
+            ADDITEM( "MPEG-4 Video / Vorbis Audio" );
+            ADDITEM( "MPEG-4 Video / MP3 Audio" );
+            break;
+    }
+#undef ADDITEM
+
+    fDstCodecsPopUp->ItemAt( 0 )->SetMarked( true );
+
+    CheckExtension();
+    CodecsPopUpChanged();
+}
+
+void MainView::CodecsPopUpChanged()
+{
+    int format = fDstFormatPopUp->IndexOf( fDstFormatPopUp->FindMarked() );
+    int codecs = fDstCodecsPopUp->IndexOf( fDstCodecsPopUp->FindMarked() );
+
+    BMenuItem * item;
+
+    /* Update the encoder popup if necessary */
+    if( ( FormatSettings[format][codecs] & HB_VCODEC_X264 ) &&
+        fVidEncoderPopUp->CountItems() > 1 )
+    {
+        /* MPEG-4 -> H.264 */
+        while( ( item = fVidEncoderPopUp->RemoveItem( 0L ) ) )
+            delete item;
+        fVidEncoderPopUp->AddItem( new BMenuItem( "x264", new BMessage() ) );
+        fVidEncoderPopUp->ItemAt( 0 )->SetMarked( true );
+    }
+    else if( ( FormatSettings[format][codecs] & HB_VCODEC_FFMPEG ) &&
+             fVidEncoderPopUp->CountItems() < 2 )
+    {
+        /* H.264 -> MPEG-4 */
+        while( ( item = fVidEncoderPopUp->RemoveItem( 0L ) ) )
+            delete item;
+        fVidEncoderPopUp->AddItem( new BMenuItem( "FFmpeg", new BMessage() ) );
+        fVidEncoderPopUp->AddItem( new BMenuItem( "XviD", new BMessage() ) );
+        fVidEncoderPopUp->ItemAt( 0 )->SetMarked( true );
+    }
+
+    if( FormatSettings[format][codecs] & HB_ACODEC_AC3 )
+    {
+        /* AC-3 pass-through: disable samplerate and bitrate */
+        fAudRatePopUp->SetEnabled( false );
+        fAudBitratePopUp->SetEnabled( false );
+    }
+    else if( fVidEncoderPopUp->IsEnabled() )
+    {
+        fAudRatePopUp->SetEnabled( true );
+        fAudBitratePopUp->SetEnabled( true );
+    }
+}
+
+void MainView::CheckExtension()
+{
+    char * ext = NULL;
+    switch( fDstFormat )
+    {
+        case 0:
+            ext = ".mp4";
+            break;
+        case 1:
+            ext = ".avi";
+            break;
+        case 2:
+            ext = ".ogm";
+            break;
+    }
+
+    char newname[1024];
+    const char * oldname = fDstFileControl->Text();
+    memcpy( newname, oldname, strlen( oldname ) );
+    if( strlen( oldname ) > 4 &&
+        oldname[strlen( oldname ) - 4] == '.' )
+    {
+        /* Replace extension */
+        memcpy( &newname[strlen( oldname ) - 4], ext, 5 );
+    }
+    else
+    {
+        /* Add extension */
+        memcpy( &newname[strlen( oldname )], ext, 5 );
+    }
+    fDstFileControl->SetText( newname );
+}
+
+void MainView::QualityRadioChanged()
+{
+    fVidTargetControl->SetEnabled( fVidTargetRadio->Value() );
+    fVidAverageControl->SetEnabled( fVidAverageRadio->Value() );
+    fVidConstantSlider->SetEnabled( fVidConstantRadio->Value() );
+    fVidTwoPassCheck->SetEnabled( !fVidConstantRadio->Value() );
+    if( fVidConstantRadio->Value() )
+        fVidTwoPassCheck->SetValue( 0 );
+}
+
+void MainView::SliderChanged()
+{
+    char text[1024];
+    snprintf( text, 1024, "Constant quality: %ld %%",
+              fVidConstantSlider->Value() );
+    fVidConstantRadio->SetLabel( text );
+}
+
+void MainView::AddJob()
+{
+    hb_list_t  * list;
+    hb_title_t * title;
+    hb_job_t   * job;
+    list  = hb_get_titles( fHandle );
+    title = (hb_title_t *) hb_list_item( list,
+        fSrcTitlePopUp->IndexOf( fSrcTitlePopUp->FindMarked() ) );
+    job = title->job;
+
+    job->chapter_start = fSrcChapStartPopUp->IndexOf(
+        fSrcChapStartPopUp->FindMarked() ) + 1;
+    job->chapter_end = fSrcChapEndPopUp->IndexOf(
+        fSrcChapEndPopUp->FindMarked() ) + 1;
+
+    int format = fDstFormatPopUp->IndexOf(
+        fDstFormatPopUp->FindMarked() );
+    int codecs = fDstCodecsPopUp->IndexOf(
+        fDstCodecsPopUp->FindMarked() );
+
+    job->mux    = FormatSettings[format][codecs] & HB_MUX_MASK;
+    job->vcodec = FormatSettings[format][codecs] & HB_VCODEC_MASK;
+    job->acodec = FormatSettings[format][codecs] & HB_ACODEC_MASK;
+
+    if( ( job->vcodec & HB_VCODEC_FFMPEG ) &&
+        fVidEncoderPopUp->IndexOf(
+            fVidEncoderPopUp->FindMarked() ) > 0 )
+    {
+        job->vcodec = HB_VCODEC_XVID;
+    }
+
+    int index;
+    index = fVidRatePopUp->IndexOf(
+        fVidRatePopUp->FindMarked() );
+    if( index > 0 )
+    {
+        job->vrate_base = hb_video_rates[index-1].rate;
+    }
+    else
+    {
+        job->vrate_base = title->rate_base;
+    }
+
+    job->grayscale = fVidGrayCheck->Value();
+
+    job->subtitle = fSubPopUp->IndexOf(
+        fSubPopUp->FindMarked() ) - 1;
+
+    job->audios[0] = fAudLang1PopUp->IndexOf(
+        fAudLang1PopUp->FindMarked() ) - 1;
+    job->audios[1] = fAudLang2PopUp->IndexOf(
+        fAudLang2PopUp->FindMarked() ) - 1;
+    job->audios[2] = -1;
+
+    job->arate = hb_audio_rates[fAudRatePopUp->IndexOf(
+        fAudRatePopUp->FindMarked() )].rate;
+    job->abitrate = hb_audio_bitrates[fAudBitratePopUp->IndexOf(
+        fAudBitratePopUp->FindMarked() )].rate;
+
+    if( fVidConstantRadio->Value() )
+    {
+        job->vquality = 0.01 * fVidConstantSlider->Value();
+        job->vbitrate = 0;
+    }
+    else if( fVidTargetRadio->Value() )
+    {
+        job->vquality = -1.0;
+        job->vbitrate = hb_calc_bitrate( job,
+            atoi( fVidTargetControl->Text() ) );
+    }
+    else
+    {
+        job->vquality = -1.0;
+        job->vbitrate = atoi( fVidAverageControl->Text() );
+    }
+
+    job->file = strdup( fDstFileControl->Text() );
+
+    if( fVidTwoPassCheck->Value() )
+    {
+        job->pass = 1;
+        hb_add( fHandle, job );
+        job->pass = 2;
+        hb_add( fHandle, job );
+    }
+    else
+    {
+        job->pass = 0;
+        hb_add( fHandle, job );
+    }
+}
+
+MainWindow::MainWindow( hb_handle_t * handle )
+    : BWindow( BRect( 0,0,10,10 ), "HandBrake " HB_VERSION,
+               B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE )
+{
+    fHandle = handle;
+
+    /* Add the main view */
+    fView = new MainView( fHandle );
+    AddChild( fView );
+
+    /* Resize to fit */
+    ResizeTo( fView->Bounds().Width(), fView->Bounds().Height() );
+
+    /* Center */
+    BScreen screen;
+    MoveTo( ( screen.Frame().Width() - fView->Bounds().Width() ) / 2,
+            ( screen.Frame().Height() - fView->Bounds().Height() ) / 2 );
+}
+
+void MainWindow::MessageReceived( BMessage * msg )
+{
+    switch( msg->what )
+    {
+        case MSG_TITLEPOPUP:
+        case MSG_CHAPTERPOPUP:
+        case MSG_FORMATPOPUP:
+        case MSG_CODECSPOPUP:
+        case MSG_BROWSE:
+        case MSG_QUALITYRADIO:
+        case MSG_SLIDER:
+        case MSG_PICSETTINGS:
+        case MSG_QUEUE_ENABLE:
+        case MSG_QUEUE_ADD:
+        case MSG_QUEUE_SHOW:
+        case MSG_PAUSE:
+        case MSG_START:
+        case B_SAVE_REQUESTED:
+            fView->HandleMessage( msg );
+            break;
+
+        default:
+            BWindow::MessageReceived( msg );
+            break;
+    }
+}
+
+bool MainWindow::QuitRequested()
+{
+    be_app_messenger.SendMessage( B_QUIT_REQUESTED );
+    return true;
+}
+
+void MainWindow::Update( hb_state_t * s )
+{
+    fView->Update( s );
+}
diff --git a/beos/MainWindow.h b/beos/MainWindow.h
new file mode 100644 (file)
index 0000000..1558556
--- /dev/null
@@ -0,0 +1,121 @@
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <interface/Window.h>
+#include <interface/View.h>
+
+#include "hb.h"
+
+class BButton;
+class BCheckBox;
+class BMenuField;
+class BPopUpMenu;
+class BRadioButton;
+class BSlider;
+class BStatusBar;
+class BStringView;
+class BTextControl;
+class BFilePanel;
+
+class PicWindow;
+class QueueWindow;
+
+class MainView : public BView
+{
+    public:
+        MainView( hb_handle_t * handle );
+
+        void HandleMessage( BMessage * msg );
+        void Update( hb_state_t * s );
+
+    private:
+        void EnableUI( bool );
+        void TitlePopUpChanged();
+        void ChapterPopUpChanged();
+        void FormatPopUpChanged();
+        void CodecsPopUpChanged();
+        void CheckExtension();
+        void QualityRadioChanged();
+        void SliderChanged();
+        void AddJob();
+
+        hb_handle_t  * fHandle;
+
+        BStringView  * fSrcDVD1String;
+        BStringView  * fSrcDVD2String;
+        BPopUpMenu   * fSrcTitlePopUp;
+        BMenuField   * fSrcTitleMenu;
+        int            fSrcTitle;
+        BStringView  * fSrcChapString;
+        BPopUpMenu   * fSrcChapStartPopUp;
+        BMenuField   * fSrcChapStartMenu;
+        BStringView  * fSrcChapToString;
+        BPopUpMenu   * fSrcChapEndPopUp;
+        BMenuField   * fSrcChapEndMenu;
+        BStringView  * fSrcDur1String;
+        BStringView  * fSrcDur2String;
+
+        BPopUpMenu   * fDstFormatPopUp;
+        BMenuField   * fDstFormatMenu;
+        int            fDstFormat;
+        BPopUpMenu   * fDstCodecsPopUp;
+        BMenuField   * fDstCodecsMenu;
+        BTextControl * fDstFileControl;
+        BButton      * fBrowseButton;
+
+        BPopUpMenu   * fVidRatePopUp;
+        BMenuField   * fVidRateMenu;
+        BPopUpMenu   * fVidEncoderPopUp;
+        BMenuField   * fVidEncoderMenu;
+        BStringView  * fVidQualityString;
+        BRadioButton * fVidTargetRadio;
+        BTextControl * fVidTargetControl;
+        BRadioButton * fVidAverageRadio;
+        BTextControl * fVidAverageControl;
+        BRadioButton * fVidConstantRadio;
+        BSlider      * fVidConstantSlider;
+        BCheckBox    * fVidGrayCheck;
+        BCheckBox    * fVidTwoPassCheck;
+
+        BPopUpMenu   * fSubPopUp;
+        BMenuField   * fSubMenu;
+
+        BPopUpMenu   * fAudLang1PopUp;
+        BMenuField   * fAudLang1Menu;
+        BPopUpMenu   * fAudLang2PopUp;
+        BMenuField   * fAudLang2Menu;
+        BPopUpMenu   * fAudRatePopUp;
+        BMenuField   * fAudRateMenu;
+        BPopUpMenu   * fAudBitratePopUp;
+        BMenuField   * fAudBitrateMenu;
+
+        BButton      * fPictureButton;
+
+        BStatusBar   * fProgressBar;
+        BCheckBox    * fQueueCheck;
+        BButton      * fAddButton;
+        BButton      * fShowButton;
+        BButton      * fPauseButton;
+        BButton      * fRipButton;
+
+        BFilePanel   * fFilePanel;
+        PicWindow    * fPicWin;
+        QueueWindow  * fQueueWin;
+};
+
+class MainWindow : public BWindow
+{
+    public:
+        MainWindow( hb_handle_t * handle );
+        void MessageReceived( BMessage * msg );
+        bool QuitRequested();
+
+        void Update( hb_state_t * s );
+
+    private:
+        MainView * fView;
+
+        hb_handle_t * fHandle;
+};
+
+#endif
diff --git a/beos/PicWindow.cpp b/beos/PicWindow.cpp
new file mode 100644 (file)
index 0000000..6b30f27
--- /dev/null
@@ -0,0 +1,369 @@
+#include <app/Application.h>
+#include <interface/Bitmap.h>
+#include <interface/Box.h>
+#include <interface/Button.h>
+#include <interface/CheckBox.h>
+#include <interface/RadioButton.h>
+#include <interface/Screen.h>
+#include <interface/StringView.h>
+
+#include "PicWindow.h"
+#include "Stepper.h"
+
+#define MSG_PREV   'prev'
+#define MSG_NEXT   'next'
+#define MSG_CLOSE  'clos'
+#define MSG_WIDTH  'widt'
+#define MSG_HEIGHT 'heig'
+#define MSG_RADIO  'radi'
+
+PicView::PicView( hb_handle_t * handle, int index )
+    : BView( BRect( 0,0,10,10 ), NULL, B_FOLLOW_NONE, B_WILL_DRAW )
+{
+    fHandle = handle;
+
+    /* Get the title and the job */
+    hb_list_t * list;
+    list   = hb_get_titles( fHandle );
+    fTitle = (hb_title_t *) hb_list_item( list, index );
+    fJob   = fTitle->job;
+
+    /* We'll start with the first picture */
+    fIndex = 0;
+
+    /* Allocate a buffer large enough to call hb_get_preview() later */
+    fRawPic = (uint8_t *) malloc( ( fTitle->width + 2 ) *
+                ( fTitle->height + 2 ) * 4 );
+
+    /* Create the RGB BBitmap we'll use to display */
+    fBitmap = new BBitmap( BRect( 0, 0, fTitle->width + 1,
+                                  fTitle->height + 1 ), 0, B_RGB32 );
+
+    /* Now build the interface */
+    BRect r, b;
+    BBox * box;
+    BButton * button;
+    BStringView * stringView;
+
+    /* Resize ourselves so the picture fits just fine */
+    b = fBitmap->Bounds();
+    ResizeTo( b.Width()+170, b.Height()+65 );
+
+    /* Now build the UI around the BBitmap */
+    SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) );
+
+    /* "Size" box */
+    b = Bounds();
+    r = BRect( b.right-150,10,b.right-10,105 );
+    box = new BBox( r );
+    box->SetLabel( "Size" );
+    AddChild( box );
+
+    b = box->Bounds();
+
+    /* Width */
+    r = BRect( 10,15,b.right/2,35 );
+    stringView = new BStringView( r, NULL, "Width:" );
+    box->AddChild( stringView );
+    r = BRect( b.right/2+1,15,b.right-10,35 );
+    fWidthStepper = new HBStepper( r, 16, 16, fTitle->width,
+        fJob->width, new BMessage( MSG_WIDTH ) );
+    box->AddChild( fWidthStepper );
+
+    /* Height */
+    r = BRect( 10,40,b.right/2,60 );
+    stringView = new BStringView( r, NULL, "Height:" );
+    box->AddChild( stringView );
+    r = BRect( b.right/2+1,40,b.right-10,60 );
+    fHeightStepper = new HBStepper( r, 16, 16, fTitle->height,
+        fJob->height, new BMessage( MSG_HEIGHT ) );
+    box->AddChild( fHeightStepper );
+
+    /* Aspect ratio */
+    r = BRect( 10,65,b.right-10,85 );
+    fRatioCheck = new BCheckBox( r, NULL, "Keep aspect ratio",
+                                 new BMessage( MSG_WIDTH ) );
+    fRatioCheck->SetValue( fJob->keep_ratio );
+    box->AddChild( fRatioCheck );
+
+    /* "Crop" box */
+    b = Bounds();
+    r = BRect( b.right-150,115,b.right-10,260 );
+    box = new BBox( r );
+    box->SetLabel( "Crop" );
+    AddChild( box );
+
+    b = box->Bounds();
+
+    /* Automatic */
+    r = BRect( 10,15,b.right-10,35 );
+    fAutoRadio = new BRadioButton( r, NULL, "Automatic",
+                                   new BMessage( MSG_RADIO ) );
+    box->AddChild( fAutoRadio );
+
+    /* Custom */
+    r = BRect( 10,40,b.right-10,60 );
+    fCustomRadio = new BRadioButton( r, NULL, "Custom:",
+                                     new BMessage( MSG_RADIO ) );
+    box->AddChild( fCustomRadio );
+    float width = ( b.Width() - 30 ) / 2;
+    r = BRect( (b.right-width)/2,65,(b.right+width)/2,85 );
+    fCropSteppers[0] = new HBStepper( r, 2, 0, fTitle->height/2-2,
+        fJob->crop[0], new BMessage( MSG_WIDTH ) );
+    box->AddChild( fCropSteppers[0] );
+    r = BRect( (b.right-width)/2,115,(b.right+width)/2,135 );
+    fCropSteppers[1] = new HBStepper( r, 2, 0, fTitle->height/2-2,
+        fJob->crop[1], new BMessage( MSG_WIDTH ) );
+    box->AddChild( fCropSteppers[1] );
+    r = BRect( 10,90,10+width,110 );
+    fCropSteppers[2] = new HBStepper( r, 2, 0, fTitle->width/2-2,
+        fJob->crop[2], new BMessage( MSG_HEIGHT ) );
+    box->AddChild( fCropSteppers[2] );
+    r = BRect( width+20,90,b.right-10,110 );
+    fCropSteppers[3] = new HBStepper( r, 2, 0, fTitle->width/2-2,
+        fJob->crop[3], new BMessage( MSG_HEIGHT ) );
+    box->AddChild( fCropSteppers[3] );
+
+    if( memcmp( fTitle->crop, fJob->crop, 4 * sizeof( int ) ) )
+    {
+        fCustomRadio->SetValue( 1 );
+    }
+    else
+    {
+        fAutoRadio->SetValue( 1 );
+    }
+
+    /* "Misc" box */
+    b = Bounds();
+    r = BRect( b.right-150,270,b.right-10,315 );
+    box = new BBox( r );
+    box->SetLabel( "Misc" );
+    AddChild( box );
+
+    b = box->Bounds();
+
+    /* Deinterlace */
+    r = BRect( 10,15,b.right-10,35 );
+    fDeintCheck = new BCheckBox( r, NULL, "Deinterlace picture",
+                                 new BMessage( MSG_WIDTH ) );
+    fDeintCheck->SetValue( fJob->deinterlace );
+    box->AddChild( fDeintCheck );
+
+    b = Bounds();
+
+    /* Next/Prev buttons */
+    r = BRect( b.right-90,325,b.right-10,350 );
+    fPrevButton = new BButton( r, NULL, "Previous",
+                               new BMessage( MSG_PREV ) );
+    AddChild( fPrevButton );
+    r = BRect( b.right-90,355,b.right-10,380 );
+    fNextButton = new BButton( r, NULL, "Next",
+                               new BMessage( MSG_NEXT ) );
+    AddChild( fNextButton );
+
+    /* Info string and OK button */
+    r = BRect( 10,b.bottom-30,b.right-100,b.bottom-10 );
+    fInfoString = new BStringView( r, NULL, "" );
+    AddChild( fInfoString );
+    r = BRect( b.right-90,b.bottom-35,b.right-10,b.bottom-10 );
+    button = new BButton( r, NULL, "OK", new BMessage( MSG_CLOSE ) );
+    AddChild( button );
+
+    /* Process and draw a first picture */
+    RadioChanged();
+    UpdateBitmap();
+}
+
+PicView::~PicView()
+{
+    free( fRawPic );
+    delete fBitmap;
+}
+
+/************************************************************************
+ * PicView::Draw
+ ************************************************************************
+ * Calls the inherited BView::Draw, plus draws the BBitmap preview
+ * and the horizontal line above the info string and OK button
+ ***********************************************************************/
+void PicView::Draw( BRect rect )
+{
+    BRect b;
+
+    BView::Draw( rect );
+
+    if( LockLooper() )
+    {
+        b = fBitmap->Bounds();
+        DrawBitmap( fBitmap, BRect( 10,10,b.Width()+10,b.Height()+10 ) );
+        UnlockLooper();
+    }
+
+    b = Bounds();
+    SetHighColor( 128,128,128 );
+    StrokeLine( BPoint( 10,b.bottom-45 ), BPoint( b.right-10,b.bottom-45 ) );
+    SetHighColor( 255,255,255 );
+    StrokeLine( BPoint( 10,b.bottom-44 ), BPoint( b.right-10,b.bottom-44 ) );
+}
+
+void PicView::HandleMessage( BMessage * msg )
+{
+    switch( msg->what )
+    {
+        case MSG_PREV:
+            fIndex--;
+            UpdateBitmap();
+            break;
+
+        case MSG_NEXT:
+            fIndex++;
+            UpdateBitmap();
+            break;
+
+        case MSG_WIDTH:
+        case MSG_HEIGHT:
+            UpdateSettings( msg->what );
+            UpdateBitmap();
+            break;
+
+        case MSG_RADIO:
+            RadioChanged();
+            break;
+
+    }
+}
+
+void PicView::RadioChanged()
+{
+    int cus = fCustomRadio->Value();
+    for( int i = 0; i < 4; i++ )
+    {
+        fCropSteppers[i]->SetEnabled( cus );
+    }
+    if( !cus )
+    {
+        memcpy( fJob->crop, fTitle->crop, 4 * sizeof( int ) );
+        for( int i = 0; i < 4; i++ )
+        {
+            fCropSteppers[i]->SetValue( fJob->crop[i] );
+        }
+        UpdateSettings( MSG_WIDTH );
+        UpdateBitmap();
+    }
+}
+
+void PicView::UpdateSettings( uint32 what )
+{
+    fJob->width       = fWidthStepper->Value();
+    fJob->height      = fHeightStepper->Value();
+    fJob->keep_ratio  = fRatioCheck->Value();
+    fJob->deinterlace = fDeintCheck->Value();
+    for( int i = 0; i < 4; i++ )
+    {
+        fJob->crop[i] = fCropSteppers[i]->Value();
+    }
+
+    if( fJob->keep_ratio )
+    {
+        if( what == MSG_WIDTH )
+        {
+            hb_fix_aspect( fJob, HB_KEEP_WIDTH );
+            if( fJob->height > fTitle->height )
+            {
+                fJob->height = fTitle->height;
+                hb_fix_aspect( fJob, HB_KEEP_HEIGHT );
+            }
+        }
+        else
+        {
+            hb_fix_aspect( fJob, HB_KEEP_HEIGHT );
+            if( fJob->width > fTitle->width )
+            {
+                fJob->width = fTitle->width;
+                hb_fix_aspect( fJob, HB_KEEP_WIDTH );
+            }
+        }
+    }
+
+    fWidthStepper->SetValue( fJob->width );
+    fHeightStepper->SetValue( fJob->height );
+}
+
+void PicView::UpdateBitmap()
+{
+    /* Sanity checks */
+    if( fIndex < 0 )
+    {
+        fIndex = 0;
+        return;
+    }
+    if( fIndex > 9 )
+    {
+        fIndex = 9;
+        return;
+    }
+
+    /* Enable/disable buttons */
+    fPrevButton->SetEnabled( fIndex > 0 );
+    fNextButton->SetEnabled( fIndex < 9 );
+
+    /* Get new preview and copy it in our BBitmap */
+    hb_get_preview( fHandle, fTitle, fIndex, fRawPic );
+    for( int i = 0; i < fTitle->height + 2; i++ )
+    {
+        memcpy( ( (uint8_t *) fBitmap->Bits() ) +
+                    i * fBitmap->BytesPerRow(),
+                fRawPic + 4 * ( fTitle->width + 2 ) * i,
+                4 * ( fTitle->width + 2 ) );
+    }
+
+    /* Update size info */
+    char text[1024];
+    snprintf( text, 1024, "Source: %dx%d, output: %dx%d",
+              fTitle->width, fTitle->height,
+              fJob->width, fJob->height );
+    fInfoString->SetText( text );
+
+    /* Force redraw */
+    Draw( Bounds() );
+}
+
+PicWindow::PicWindow( hb_handle_t * handle, int index )
+    : BWindow( BRect( 0,0,10,10 ), "Picture settings",
+               B_FLOATING_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL,
+               B_NOT_CLOSABLE | B_NOT_RESIZABLE | B_NOT_ZOOMABLE )
+{
+    /* Add the PicView */
+    fView = new PicView( handle, index );
+    AddChild( fView );
+    
+    /* Resize to fit */
+    ResizeTo( fView->Bounds().Width(), fView->Bounds().Height() );
+    
+    /* Center */
+    BScreen screen;
+    MoveTo( ( screen.Frame().Width() - fView->Bounds().Width() ) / 2,
+            ( screen.Frame().Height() - fView->Bounds().Height() ) / 2 );
+}
+
+void PicWindow::MessageReceived( BMessage * msg )
+{
+    switch( msg->what )
+    {
+        case MSG_PREV:
+        case MSG_NEXT:
+        case MSG_WIDTH:
+        case MSG_HEIGHT:
+        case MSG_RADIO:
+            fView->HandleMessage( msg );
+            break;
+
+        case MSG_CLOSE:
+            Lock();
+            Quit();
+            break;
+
+        default:
+            BWindow::MessageReceived( msg );
+    }
+}
diff --git a/beos/PicWindow.h b/beos/PicWindow.h
new file mode 100644 (file)
index 0000000..9fe5d31
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef PICWINDOW_H
+#define PICWINDOW_H
+
+#include <interface/Window.h>
+#include <interface/View.h>
+
+#include "hb.h"
+
+class HBStepper;
+
+class PicView : public BView
+{
+    public:
+        PicView( hb_handle_t * handle, int index );
+        ~PicView();
+        void Draw( BRect rect );
+
+        void HandleMessage( BMessage * msg );
+
+    private:
+        void UpdateBitmap();
+        void RadioChanged();
+        void UpdateSettings( uint32 what );
+
+        hb_handle_t  * fHandle;
+        hb_title_t   * fTitle;
+        hb_job_t     * fJob;
+        int            fIndex;
+        uint8_t      * fRawPic;
+        BBitmap      * fBitmap;
+
+        HBStepper    * fWidthStepper;
+        HBStepper    * fHeightStepper;
+        BCheckBox    * fRatioCheck;
+        BRadioButton * fAutoRadio;
+        BRadioButton * fCustomRadio;
+        HBStepper    * fCropSteppers[4];
+        BCheckBox    * fDeintCheck;
+        BButton      * fPrevButton;
+        BButton      * fNextButton;
+        BStringView  * fInfoString;
+};
+
+class PicWindow : public BWindow
+{
+    public:
+        PicWindow( hb_handle_t * handle, int index );
+        void MessageReceived( BMessage * msg );
+
+    private:
+        PicView * fView;
+};
+
+#endif
diff --git a/beos/QueueWindow.cpp b/beos/QueueWindow.cpp
new file mode 100644 (file)
index 0000000..2b0319e
--- /dev/null
@@ -0,0 +1,132 @@
+#include <app/Message.h>
+#include <interface/Button.h>
+#include <interface/Screen.h>
+#include <interface/ScrollView.h>
+#include <interface/StringView.h>
+
+#include "QueueWindow.h"
+
+#define MSG_REMOVE 'remo'
+#define MSG_CLOSE  'clos'
+
+QueueView::QueueView( hb_handle_t * handle )
+    : BView( BRect( 0,0,500,300 ), NULL, B_FOLLOW_NONE, B_WILL_DRAW )
+{
+    fHandle = handle;
+
+    BRect b = Bounds(), r;
+
+    r = BRect( b.right-90,b.bottom-35,b.right-10,b.bottom-10 );
+    BButton * button = new BButton( r, NULL, "Close", new BMessage( MSG_CLOSE ) );
+    AddChild( button );
+
+    fScrollView = NULL;
+    UpdateQueue();
+}
+
+QueueView::~QueueView()
+{
+}
+
+void QueueView::HandleMessage( BMessage * msg )
+{
+    switch( msg->what )
+    {
+        case MSG_REMOVE:
+            break;
+    }
+}
+
+void QueueView::AddStringView( char * string, BRect * r )
+{
+    BStringView * stringView;
+
+    stringView = new BStringView( *r, NULL, string );
+    fQueueView->AddChild( stringView );
+    free( string );
+
+    r->top    += 20;
+    r->bottom += 20;
+}
+
+void QueueView::UpdateQueue()
+{
+    BRect b = Bounds(), r;
+
+    if( fScrollView )
+    {
+        RemoveChild( fScrollView );
+        delete fScrollView;
+    }
+
+    r = BRect( b.left+10,b.top+10,b.right-B_V_SCROLL_BAR_WIDTH-10,b.bottom-45 );
+    fQueueView  = new BView( r, NULL, B_FOLLOW_NONE, B_WILL_DRAW );
+    fScrollView = new BScrollView( NULL, fQueueView, B_FOLLOW_NONE, 0,
+                                   false, true, B_FANCY_BORDER );
+    AddChild( fScrollView );
+
+    hb_job_t * j;
+    hb_title_t * t;
+    int i;
+    char * s;
+
+    b = fQueueView->Bounds();
+    r = BRect( b.left+10,b.top+10,b.right-10,b.top+25 );
+
+    for( i = 0; i < hb_count( fHandle ); i++ )
+    {
+        j = hb_job( fHandle, i );
+        t = j->title;
+
+        asprintf( &s, "DVD: %s", t->dvd );
+        AddStringView( s, &r );
+
+        asprintf( &s, "Title: %d", t->index );
+        AddStringView( s, &r );
+
+        asprintf( &s, "Chapters: %d to %d", j->chapter_start, j->chapter_end );
+        AddStringView( s, &r );
+
+        asprintf( &s, "Pass: %d of %d", MAX( 1, j->pass ), MIN( 2, j->pass + 1 ) );
+        AddStringView( s, &r );
+
+        asprintf( &s, "Destination: %s", j->file );
+        AddStringView( s, &r );
+    }
+}
+
+QueueWindow::QueueWindow( hb_handle_t * handle )
+    : BWindow( BRect( 0,0,10,10 ), "Queue",
+               B_FLOATING_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL,
+               B_NOT_CLOSABLE | B_NOT_RESIZABLE | B_NOT_ZOOMABLE )
+{
+    /* Add the QueueView */
+    fView = new QueueView( handle );
+    AddChild( fView );
+    
+    /* Resize to fit */
+    ResizeTo( fView->Bounds().Width(), fView->Bounds().Height() );
+    
+    /* Center */
+    BScreen screen;
+    MoveTo( ( screen.Frame().Width() - fView->Bounds().Width() ) / 2,
+            ( screen.Frame().Height() - fView->Bounds().Height() ) / 2 );
+}
+
+void QueueWindow::MessageReceived( BMessage * msg )
+{
+    switch( msg->what )
+    {
+        case MSG_REMOVE:
+            fView->HandleMessage( msg );
+            break;
+
+        case MSG_CLOSE:
+            Lock();
+            Quit();
+            break;
+
+        default:
+            BWindow::MessageReceived( msg );
+    }
+}
diff --git a/beos/QueueWindow.h b/beos/QueueWindow.h
new file mode 100644 (file)
index 0000000..e9b86e3
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef QUEUE_WINDOW_H
+#define QUEUE_WINDOW_H
+
+#include <interface/Window.h>
+#include <interface/View.h>
+
+#include "hb.h"
+
+class QueueView : public BView
+{
+    public:
+        QueueView( hb_handle_t * handle );
+        ~QueueView();
+
+        void HandleMessage( BMessage * msg );
+
+    private:
+        void AddStringView( char * string, BRect * r );
+        void UpdateQueue();
+
+        hb_handle_t  * fHandle;
+
+        BScrollView  * fScrollView;
+        BView        * fQueueView;
+        BButton      * fCloseButton;
+};
+
+class QueueWindow : public BWindow
+{
+    public:
+        QueueWindow( hb_handle_t * handle );
+        void MessageReceived( BMessage * msg );
+
+    private:
+        QueueView * fView;
+};
+
+#endif
diff --git a/beos/ScanWindow.cpp b/beos/ScanWindow.cpp
new file mode 100644 (file)
index 0000000..615731f
--- /dev/null
@@ -0,0 +1,320 @@
+#include <drivers/Drivers.h>
+#include <interface/Box.h>
+#include <interface/Button.h>
+#include <interface/MenuField.h>
+#include <interface/MenuItem.h>
+#include <interface/PopUpMenu.h>
+#include <interface/RadioButton.h>
+#include <interface/Screen.h>
+#include <interface/StatusBar.h>
+#include <interface/StringView.h>
+#include <interface/TextControl.h>
+#include <kernel/fs_info.h>
+#include <storage/FilePanel.h>
+#include <storage/Path.h>
+#include <storage/Query.h>
+#include <storage/VolumeRoster.h>
+#include <sys/ioctl.h>
+
+#include "ScanWindow.h"
+
+#define MSG_RADIO  'radi'
+#define MSG_BROWSE 'brow'
+#define MSG_CANCEL 'canc'
+#define MSG_OPEN   'open'
+
+ScanView::ScanView( hb_handle_t * handle )
+    : BView( BRect( 0,0,400,215 ), NULL, B_FOLLOW_NONE, B_WILL_DRAW )
+{
+    fHandle = handle;
+
+    BRect r, b;
+    BBox * box;
+    BStringView * stringView;
+    
+    SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) );
+
+    b = Bounds();
+
+    r = BRect( 10,10,b.right-10,130 );
+    box = new BBox( r );
+    AddChild( box );
+
+    b = box->Bounds();
+
+    r = BRect( 10,10,b.right-10,30 );
+    stringView = new BStringView( r, NULL, "Select a DVD:" );
+    box->AddChild( stringView );
+
+    r = BRect( 10,35,b.right/2,55 );
+    fDetectedRadio = new BRadioButton( r, NULL, "Detected volume",
+                                       new BMessage( MSG_RADIO ) );
+    box->AddChild( fDetectedRadio );
+
+    r = BRect( b.right/2+1,35,b.right-10,55 );
+    fPopUp = new BPopUpMenu( "No volume detected" );
+    fMenu = new BMenuField( r, NULL, "", fPopUp, true );
+    fMenu->SetDivider( 0 );
+    box->AddChild( fMenu );
+
+    r = BRect( 10,60,b.right/2,80 );
+    fFolderRadio = new BRadioButton( r, NULL, "DVD Folder / Image",
+                                     new BMessage( MSG_RADIO ) );
+    box->AddChild( fFolderRadio );
+
+    r = BRect( b.right/2+1,60,b.right-10,80 );
+    fControl = new BTextControl( r, NULL, "", "", new BMessage() );
+    fControl->SetDivider( 0 );
+    box->AddChild( fControl );
+
+    r = BRect( b.right-90,85,b.right-10,110 );
+    fBrowseButton = new BButton( r, NULL, "Browse",
+        new BMessage( MSG_BROWSE ) );
+    box->AddChild( fBrowseButton );
+
+    b = Bounds();
+
+    r = BRect( 10,b.bottom-75,b.right-10,b.bottom-45 );
+    fBar = new BStatusBar( r, NULL, NULL, NULL );
+    AddChild( fBar );
+
+    r = BRect( b.right-180,b.bottom-35,b.right-100,b.bottom-10 );
+    fCancelButton = new BButton( r, NULL, "Cancel",
+        new BMessage( MSG_CANCEL ) );
+    AddChild( fCancelButton );
+
+    r = BRect( b.right-90,b.bottom-35,b.right-10,b.bottom-10 );
+    fOpenButton = new BButton( r, NULL, "Open", new BMessage( MSG_OPEN ) );
+    AddChild( fOpenButton );
+
+    DetectVolumes();
+
+    if( fPopUp->CountItems() > 0 )
+    {
+        fDetectedRadio->SetValue( true );
+    }
+    else
+    {
+        fFolderRadio->SetValue( true );
+    }
+    RadioChanged();
+
+    fFilePanel = NULL;
+}
+
+void ScanView::HandleMessage( BMessage * msg )
+{
+    switch( msg->what )
+    {
+        case MSG_RADIO:
+            RadioChanged();
+            break;
+
+        case MSG_BROWSE:
+            if( !fFilePanel )
+            {
+                fFilePanel = new BFilePanel( B_OPEN_PANEL,
+                    new BMessenger( Window() ), NULL, 
+                    B_FILE_NODE | B_DIRECTORY_NODE, false, NULL, NULL,
+                    true );
+            }
+            fFilePanel->Show();
+            break;
+
+        case B_REFS_RECEIVED:
+        {
+            entry_ref ref;
+            if( msg->FindRef( "refs", 0, &ref ) == B_OK )
+            {
+                BPath * path = new BPath( &ref );
+                fControl->SetText( path->Path());
+            }
+            break;
+        }
+
+        case MSG_CANCEL:
+            Window()->Hide();
+            break;
+
+        case MSG_OPEN:
+            SetEnabled( false );
+            fBar->Update( - fBar->CurrentValue(), "Opening..." );
+            if( fDetectedRadio->Value() && fPopUp->CountItems() > 0 )
+            {
+                hb_scan( fHandle, fPopUp->FindMarked()->Label(), 0 );
+            }
+            else if( fFolderRadio->Value() )
+            {
+                hb_scan( fHandle, fControl->Text(), 0 );
+            }
+            break;
+    }
+}
+
+void ScanView::Update( hb_state_t * s )
+{
+    if( !LockLooper() )
+    {
+        return;
+    }
+
+    switch( s->state )
+    {
+#define p s->param.scanning
+        case HB_STATE_SCANNING:
+        {
+            char text[1024];
+            snprintf( text, 1024, "Scanning title %d of %d...", p.title_cur,
+                  p.title_count );
+            fBar->Update( fBar->MaxValue() * ( - 0.5 + p.title_cur ) /
+                  p.title_count - fBar->CurrentValue(), text );
+            break;
+        }
+#undef p
+
+        case HB_STATE_SCANDONE:
+            /* If we are still here, then no title was found */
+            fBar->Update( - fBar->CurrentValue(),
+                          "No valid title found." );
+            SetEnabled( true );
+            break;
+    }
+
+    UnlockLooper();
+}
+
+void ScanView::RadioChanged()
+{
+    bool b = fDetectedRadio->Value();
+    fMenu->SetEnabled( b );
+    fControl->SetEnabled( !b );
+    fBrowseButton->SetEnabled( !b );
+    fOpenButton->SetEnabled( !b || ( fPopUp->CountItems() > 0 ) );
+}
+
+void ScanView::SetEnabled( bool b )
+{
+    fDetectedRadio->SetEnabled( b );
+    fMenu->SetEnabled( b );
+    fFolderRadio->SetEnabled( b );
+    fControl->SetEnabled( b );
+    fBrowseButton->SetEnabled( b );
+    fOpenButton->SetEnabled( b );
+
+    if( b )
+    {
+        RadioChanged();
+    }
+}
+
+void ScanView::DetectVolumes()
+{
+    BVolumeRoster   * roster  = new BVolumeRoster();
+    BVolume         * volume = new BVolume();
+    fs_info           info;
+    int               device;
+    device_geometry   geometry;
+
+    while( roster->GetNextVolume( volume ) == B_NO_ERROR )
+    {
+        /* open() and ioctl() for more informations */
+        fs_stat_dev( volume->Device(), &info );
+        if( ( device = open( info.device_name, O_RDONLY ) ) < 0 )
+        {
+            continue;
+        }
+
+        if( ioctl( device, B_GET_GEOMETRY, &geometry,
+                   sizeof( geometry ) ) < 0 )
+        {
+            continue;
+        }
+
+        /* Get the volume name */
+        char volumeName[B_FILE_NAME_LENGTH];
+        volume->GetName( volumeName );
+
+        if( volume->IsReadOnly() && geometry.device_type == B_CD )
+        {
+            /* May be a DVD */
+            fPopUp->AddItem( new BMenuItem( info.device_name, NULL ) );
+        }
+        else if( geometry.device_type == B_DISK )
+        {
+            /* May be a hard drive. Look for VIDEO_TS folders on it */
+            BQuery * query = new BQuery();
+
+            if( query->SetVolume( volume ) != B_OK )
+            {
+                delete query;
+                continue;
+            }
+
+            if( query->SetPredicate( "name = VIDEO_TS.IFO" ) != B_OK )
+            {
+                delete query;
+                continue;
+            }
+
+            query->Fetch();
+
+            BEntry entry, parentEntry;
+            BPath  path;
+            while( query->GetNextEntry( &entry ) == B_OK )
+            {
+                entry.GetParent( &parentEntry );
+                parentEntry.GetPath( &path );
+
+                fPopUp->AddItem( new BMenuItem( path.Path(), NULL ) );
+            }
+
+            delete query;
+        }
+    }
+
+    if( fPopUp->CountItems() > 0 )
+    {
+        fPopUp->ItemAt( 0 )->SetMarked( true );
+    }
+}
+
+ScanWindow::ScanWindow( hb_handle_t * handle )
+    : BWindow( BRect( 0,0,10,10 ), "Scan", B_FLOATING_WINDOW_LOOK,
+               B_MODAL_SUBSET_WINDOW_FEEL, B_NOT_CLOSABLE |
+               B_NOT_RESIZABLE | B_NOT_ZOOMABLE )
+{
+    /* Add the scan view */
+    fView = new ScanView( handle );
+    AddChild( fView );
+    
+    /* Resize to fit */
+    ResizeTo( fView->Bounds().Width(), fView->Bounds().Height() );
+    
+    /* Center */
+    BScreen screen;
+    MoveTo( ( screen.Frame().Width() - fView->Bounds().Width() ) / 2,
+            ( screen.Frame().Height() - fView->Bounds().Height() ) / 2 );
+}
+
+void ScanWindow::MessageReceived( BMessage * msg )
+{
+    switch( msg->what )
+    {
+        case MSG_RADIO:
+        case MSG_BROWSE:
+        case MSG_CANCEL:
+        case MSG_OPEN:
+        case B_REFS_RECEIVED:
+            fView->HandleMessage( msg );
+            break;
+
+        default:
+            BWindow::MessageReceived( msg );
+    }
+}
+
+void ScanWindow::Update( hb_state_t * s )
+{
+    fView->Update( s );
+}
+
diff --git a/beos/ScanWindow.h b/beos/ScanWindow.h
new file mode 100644 (file)
index 0000000..f46c1c1
--- /dev/null
@@ -0,0 +1,56 @@
+#ifndef SCANWINDOW_H
+#define SCANWINDOW_H
+
+#include <interface/Window.h>
+#include <interface/View.h>
+
+#include "hb.h"
+
+class BButton;
+class BMenuField;
+class BPopUpMenu;
+class BRadioButton;
+class BStatusBar;
+class BTextControl;
+
+class ScanView : public BView
+{
+    public:
+        ScanView( hb_handle_t * handle );
+
+        void HandleMessage( BMessage * msg );
+        void Update( hb_state_t * s );
+        void RadioChanged();
+        void SetEnabled( bool );
+
+    private:
+        void DetectVolumes();
+
+        hb_handle_t  * fHandle;
+
+        BRadioButton * fDetectedRadio;
+        BPopUpMenu   * fPopUp;
+        BMenuField   * fMenu;
+        BRadioButton * fFolderRadio;
+        BTextControl * fControl;
+        BButton      * fBrowseButton;
+        BStatusBar   * fBar;
+        BButton      * fCancelButton;
+        BButton      * fOpenButton;
+
+        BFilePanel  * fFilePanel;
+};
+
+class ScanWindow : public BWindow
+{
+    public:
+        ScanWindow( hb_handle_t * handle );
+        void MessageReceived( BMessage * msg );
+
+        void Update( hb_state_t * s );
+
+    private:
+        ScanView    * fView;
+};
+
+#endif
diff --git a/beos/Stepper.cpp b/beos/Stepper.cpp
new file mode 100644 (file)
index 0000000..8f2733a
--- /dev/null
@@ -0,0 +1,130 @@
+#include <interface/Region.h>
+#include <interface/TextControl.h>
+#include <interface/Window.h>
+
+#include "Stepper.h"
+
+#include <stdio.h>
+
+HBStepper::HBStepper( BRect rect, int step, int min, int max, int val,
+                      BMessage * message )
+    : BView( rect, NULL, B_FOLLOW_NONE, B_WILL_DRAW )
+{
+    fStep    = step;
+    fMin     = min;
+    fMax     = max;
+    fMessage = message;
+
+    BRect b = Bounds();
+
+    fEnabled = true;
+
+    fControl = new BTextControl( BRect( 0,1,b.Width()-14,b.Height()-1 ),
+        NULL, NULL, "", new BMessage() );
+    fControl->SetDivider( 0.0 );
+    fControl->TextView()->MakeEditable( false );
+    AddChild( fControl );
+
+    SetValue( val );
+}
+
+void HBStepper::Draw( BRect rect )
+{
+    /* Why do we have to do this here!? */
+    fControl->TextView()->MakeEditable( false );
+    fControl->TextView()->MakeSelectable( false );
+
+    BRect b = Bounds();
+    BRegion region;
+
+    SetHighColor( 128,128,128 ); /* Dark gray */
+    region.MakeEmpty();
+    region.Include( BRect(  3, 0,10, 0 ) );
+    region.Include( BRect(  2, 1, 3, 1 ) );
+    region.Include( BRect( 10, 1,11, 1 ) );
+    region.Include( BRect(  1, 2, 2, 2 ) );
+    region.Include( BRect( 11, 2,12, 2 ) );
+    region.Include( BRect(  1, 2, 1,18 ) );
+    region.Include( BRect(  1,10,12,10 ) );
+    region.Include( BRect( 12, 2,12,18 ) );
+    region.Include( BRect(  1,18, 2,18 ) );
+    region.Include( BRect( 11,18,12,18 ) );
+    region.Include( BRect(  2,19, 3,19 ) );
+    region.Include( BRect( 10,19,11,19 ) );
+    region.Include( BRect(  3,20,10,20 ) );
+    region.OffsetBy( b.Width()-12,0 );
+    FillRegion( &region );
+
+    SetHighColor( 0,0,0 ); /* Black */
+    region.MakeEmpty();
+    region.Include( BRect(  6, 4, 7, 4 ) );
+    region.Include( BRect(  5, 5, 8, 6 ) );
+    region.Include( BRect(  5,14, 8,15 ) );
+    region.Include( BRect(  6,16, 7,16 ) );
+    region.OffsetBy( b.Width()-12,0 );
+    FillRegion( &region );
+
+    BView::Draw( rect );
+}
+
+void HBStepper::AttachedToWindow()
+{
+    if( Parent() )
+    {
+        SetViewColor( Parent()->ViewColor() );
+    }
+}
+
+void HBStepper::MouseDown( BPoint point )
+{
+    BRect r, b = Bounds();
+
+    if( !fEnabled )
+    {
+        return;
+    }
+
+    BMessenger messenger( Window() );
+
+    r = BRect( 2,1,11,9 );
+    r.OffsetBy( b.Width()-12,0 );
+    if( r.Contains( point ) )
+    {
+        SetValue( fValue + fStep );
+        messenger.SendMessage( fMessage );
+    }
+    r.OffsetBy( 0,10 );
+    if( r.Contains( point ) )
+    {
+        SetValue( fValue - fStep );
+        messenger.SendMessage( fMessage );
+    }
+}
+
+void HBStepper::SetValue( int val )
+{
+    fValue = val;
+    if( fValue < fMin )
+    {
+        fValue = fMin;
+    }
+    if( fValue > fMax )
+    {
+        fValue = fMax;
+    }
+
+    char text[16];
+    snprintf( text, 16, "%d", fValue );
+    fControl->SetText( text );
+}
+
+int HBStepper::Value()
+{
+    return fValue;
+}
+
+void HBStepper::SetEnabled( bool e )
+{
+    fEnabled = e;
+    fControl->SetEnabled( fEnabled );
+}
diff --git a/beos/Stepper.h b/beos/Stepper.h
new file mode 100644 (file)
index 0000000..2b0493f
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef STEPPER_H
+#define STEPPER_H
+
+#include <interface/View.h>
+
+class BTextControl;
+
+class HBStepper : public BView
+{
+    public:
+        HBStepper( BRect rect, int step, int min, int max, int val,
+                   BMessage * message );
+        void Draw( BRect rect );
+        void AttachedToWindow();
+        void MouseDown( BPoint point );
+        void SetValue( int val );
+        int  Value();
+        void SetEnabled( bool e );
+
+    private:
+        int            fStep;
+        int            fMin;
+        int            fMax;
+        int            fValue;
+        BMessage     * fMessage;
+
+        bool           fEnabled;
+        BTextControl * fControl;
+};
+
+#endif
diff --git a/beos/liblayout/HGroup.h b/beos/liblayout/HGroup.h
deleted file mode 100644 (file)
index 9eee83f..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-
-#ifndef _HGROUP_H
-#define _HGROUP_H
-#include "MGroup.h"
-#include <View.h>
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT HGroup :  public MGroup, public BView
-{
-       public:         HGroup(minimax mpm,MView *kid=0, ...);
-                               HGroup(MView *kid=0, ...);
-                               HGroup(BMessage*);
-                               virtual ~HGroup();
-                               virtual long Archive(BMessage *archive, bool deep=true) const;
-                               static BArchivable *Instantiate(BMessage *archive);
-                               virtual minimax layoutprefs();
-                               virtual BRect   layout(BRect rect);
-                               virtual void AttachedToWindow();
-                               virtual void DetachedFromWindow();
-                               virtual void MouseDown(BPoint);
-
-       private:        virtual void _expansionhgroup1();
-                               virtual void _expansionhgroup2();
-                               virtual void _expansionhgroup3();
-
-                               static int cmpkids(const void* v1,const void *v2);
-                               int *size;
-                               float totalweight;
-                               int numkids;
-                               sortstruct      *childorder;
-                               MView **mkid;
-                               float totalminx,totalmaxx;
-                               BRect *lastrect;
-
-                               uint32  _expansiondata[2];
-};
-
-#endif
diff --git a/beos/liblayout/LayeredGroup.h b/beos/liblayout/LayeredGroup.h
deleted file mode 100644 (file)
index 61264ca..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-
-#ifndef _LAYEREDGROUP_H
-#define _LAYEREDGROUP_H
-
-#include "MGroup.h"
-#include <Control.h>
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT LayeredGroup :  public MGroup, public BControl
-{
-       public:         LayeredGroup(minimax mpm,MView *arg=0, ...);
-                               LayeredGroup(MView *arg=0, ...);
-                               LayeredGroup(BMessage*);
-                               virtual ~LayeredGroup();
-                               virtual long Archive(BMessage *archive, bool deep=true) const;
-                               static BArchivable *Instantiate(BMessage *archive);
-                               virtual minimax layoutprefs();
-                               virtual BRect   layout(BRect rect);
-                               void                    ActivateLayer(int);
-                               virtual void    MessageReceived(BMessage *mes);
-                               virtual void AttachedToWindow();
-                               virtual void DetachedFromWindow();
-
-       private:        virtual void _expansionlayeredgroup1();
-                               virtual void _expansionlayeredgroup2();
-
-                               int numkids;
-                               int activekid;
-
-                               uint32 _expansiondata[3];
-};
-
-
-#endif
diff --git a/beos/liblayout/MApplication.h b/beos/liblayout/MApplication.h
deleted file mode 100644 (file)
index acdd132..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-
-#ifndef _MAPPLICATION_H
-#define _MAPPLICATION_H
-
-#include "layout.h"
-#include <Application.h>
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT MApplication : public BApplication
-{
-       public: MApplication(char *);
-                       MApplication(BMessage*);
-                       virtual ~MApplication();
-                       virtual long Archive(BMessage *archive, bool deep=true) const;
-                       static BArchivable *Instantiate(BMessage *archive);
-                       virtual void MessageReceived(BMessage*);
-
-                       virtual status_t GetSupportedSuites(BMessage *message);
-                       virtual BHandler *ResolveSpecifier(BMessage *message, int32 index, BMessage *specifier, int32 command, const char *property);
-
-       private:
-                       virtual void _expansionmapplication1();
-                       virtual void _expansionmapplication2();
-                       uint32 _expansiondata[4];
-};
-#endif
diff --git a/beos/liblayout/MBViewWrapper.h b/beos/liblayout/MBViewWrapper.h
deleted file mode 100644 (file)
index 351dfb8..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-
-#ifndef _MBVIEWWRAPPER_H
-#define _MBVIEWWRAPPER_H
-#include "layout.h"
-#include <View.h>
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT MBViewWrapper :  public MView, public BView
-{
-       public:         MBViewWrapper(BView *view, bool usepreferred=true, bool x_fixed=true, bool y_fixed=true);
-                               MBViewWrapper(BMessage*);
-                               virtual long Archive(BMessage *archive, bool deep=true) const;
-                               static BArchivable *Instantiate(BMessage *archive);
-                               virtual ~MBViewWrapper();
-                               virtual minimax layoutprefs();
-                               virtual BRect   layout(BRect rect);
-                               virtual void AttachedToWindow();
-                               virtual void DetachedFromWindow();
-
-       private:        virtual void _expansionmbviewwrapper1(); 
-
-                               BView *childview;
-
-                               uint32  _expansiondata[2];
-};
-
-#endif
diff --git a/beos/liblayout/MBorder.h b/beos/liblayout/MBorder.h
deleted file mode 100644 (file)
index 4e925ec..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-
-#ifndef _MBORDER_H
-#define _MBORDER_H
-#include "MGroup.h"
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT MBorder :  public MGroup, public BView
-{
-       public:
-                       enum {
-                               ROTATE_REVERSE=(int)0x80000000
-                       };
-       
-                       MBorder(ulong border_type,ulong spacing,char *name=NULL,MView *kid=NULL);
-                       MBorder(BMessage*);
-                       virtual long Archive(BMessage *archive, bool deep=true) const;
-                       static BArchivable *Instantiate(BMessage *archive);
-                       ~MBorder();
-                       virtual minimax layoutprefs();
-                       virtual BRect   layout(BRect rect);
-                       virtual void    Draw(BRect);
-                       virtual void AttachedToWindow();
-                       virtual void DetachedFromWindow();
-                       virtual void FrameResized(float width, float height);
-                       void                    DrawBorder();
-                       void                    SetLabel(char *);
-                       char           *Label();
-                       void                    SetHighlight(int);
-                       void                    SetHighlightColors(rgb_color color1, rgb_color color2, rgb_color color3);
-
-       private:
-                       virtual void    _expansionmborder1();
-                       virtual void    _expansionmborder2();
-
-                       static long             _cycler(void *arg);
-                       void                    Cycler();
-                       int     highlightmode;
-                       thread_id cycler;
-
-                       ulong bordertype;
-                       ulong extraspacing;
-                       ulong extralabelspacing;
-                       char  *label;
-                       char  *truncatedlabel;
-                       
-                       rgb_color *highlightcolors;
-
-                       uint32 _expansiondata[1];
-};
-
-
-enum
-{
-       M_NO_BORDER,
-       M_RAISED_BORDER,
-       M_DEPRESSED_BORDER,
-       M_LABELED_BORDER,
-       M_ETCHED_BORDER
-};
-
-enum
-{
-       M_SHOW_FULL_LABEL=      0x00000100
-};
-#endif
diff --git a/beos/liblayout/MButton.h b/beos/liblayout/MButton.h
deleted file mode 100644 (file)
index 64cd3e3..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-
-#ifndef _MBUTTON
-#define _MBUTTON
-#include "layout.h"
-#include <Button.h>
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT MButton :  public MView, public BButton
-{
-       public:         ulong ID;
-
-                               MButton(const char *label, ulong id=0,minimax size=minimax(-1,-1,1E6,1E6,1));
-                               MButton(const char *label, BMessage *message, BHandler *handler=NULL, minimax size=minimax(-1,-1,1E6,1E6,1));
-                               MButton(BMessage*);
-                               virtual long Archive(BMessage *archive, bool deep=true) const;
-                               static BArchivable *Instantiate(BMessage *archive);
-
-                               virtual ~MButton();
-                                               void    SetRepeat(ulong initial_delay, ulong repeat_delay);
-                               virtual minimax layoutprefs();
-                               virtual BRect   layout(BRect rect);
-                               virtual void    setcolor(rgb_color, bool);
-
-                               virtual void    Draw(BRect);
-                               virtual void    AttachedToWindow();
-                               virtual void    DetachedFromWindow();
-
-                               virtual void MouseDown(BPoint);
-
-       private:        static  long _mousetracker(void *arg);
-                                               void _MouseTracker();
-                               thread_id mousethread;
-                               BHandler *target;
-                               int64   lastwhen;
-                               ulong   initialdelay;
-                               ulong   repeatdelay;
-                               void    initobject();
-                               ulong buttonmask;
-               
-                               uint32  _expansiondata[2];
-};
-
-extern const IMPEXPLIBLAYOUT char M_BUTTON_POINTER[];
-extern const IMPEXPLIBLAYOUT char M_BUTTON_ID[];
-extern const IMPEXPLIBLAYOUT char M_BUTTON_MASK[];
-extern const IMPEXPLIBLAYOUT char M_DOUBLECLICK[];
-extern const IMPEXPLIBLAYOUT char M_REPEAT[];
-extern const IMPEXPLIBLAYOUT char M_RELEASE[];
-
-#endif
diff --git a/beos/liblayout/MCheckBox.h b/beos/liblayout/MCheckBox.h
deleted file mode 100644 (file)
index 7b39abd..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-
-#ifndef _MCHECKBOX
-#define _MCHECKBOX
-#include "layout.h"
-#include <CheckBox.h>
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT MCheckBox :  public MView, public BCheckBox
-{
-       public:         MCheckBox(const char *label,ulong id=0, bool state=false);
-                               MCheckBox(const char *label, BMessage *message, BHandler *handler=NULL, bool state=false);
-                               MCheckBox(BMessage*);
-                               virtual long Archive(BMessage *archive, bool deep=true) const;
-                               static BArchivable *Instantiate(BMessage *archive);
-
-                               virtual ~MCheckBox();
-                               virtual void    AttachedToWindow();
-                               virtual void DetachedFromWindow();
-
-                               virtual minimax layoutprefs();
-                               virtual BRect   layout(BRect rect);
-
-       private:        BHandler *target;
-                               uint32  _expansiondata[2];
-};
-
-extern const IMPEXPLIBLAYOUT char M_CHECKBOX_POINTER[];
-extern const IMPEXPLIBLAYOUT char M_CHECKBOX_ID[];
-
-#endif
diff --git a/beos/liblayout/MDividable.h b/beos/liblayout/MDividable.h
deleted file mode 100644 (file)
index 800772b..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-
-// Abstract base class for an object that can be 'divided'.
-// Currently this includes MTextControl and MPopup.
-// The dividable class, and the global function below, is
-// used to align the left half (the label) and the right
-// half (data-entry/selection) of a group of MDividable's
-
-#ifndef _MDIVIDABLE_H
-#define _MDIVIDABLE_H
-
-#include "layout.h"
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT MDividable
-{
-       public:
-               float           labelwidth;
-               MDividable *rolemodel;
-
-       public:
-               MDividable();
-// work around my own bug...
-#ifdef BUILDING_LIBLAYOUT
-               ~MDividable();
-#endif
-               void DivideSameAs(MDividable *);
-               virtual float LabelWidth();
-};
-
-extern void IMPEXPLIBLAYOUT DivideSame(MView *, MView *, ...);
-
-#endif
diff --git a/beos/liblayout/MDragBar.h b/beos/liblayout/MDragBar.h
deleted file mode 100644 (file)
index e345668..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-
-#ifndef _MDRAGBAR_H
-#define _MDRAGBAR_H
-#include "layout.h"
-#include <Control.h>
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT MDragBar :  public MView, public BControl
-{
-       public:         MDragBar(minimax size=minimax(1,1,1E6,1E6));
-                               MDragBar(BMessage*);
-                               virtual long Archive(BMessage *archive, bool deep=true) const;
-                               static BArchivable *Instantiate(BMessage *archive);
-                               virtual ~MDragBar();
-
-                               virtual minimax layoutprefs();
-                               virtual BRect   layout(BRect rect);
-                               virtual void    AttachedToWindow();
-                               virtual void    Draw(BRect rect);
-                               virtual void    KeyDown(const char *bytes, int32 numbytes);
-                               virtual void    DetachedFromWindow();
-                               virtual void    MouseDown(BPoint);
-
-       private:        virtual void _expansionmdragbar1(); 
-
-                               thread_id mousethread;
-                               BPoint dragpoint;
-
-                               static  long    _mousetracker(void *arg);
-                                               void    _MouseTracker();
-
-                               uint32  _expansiondata[2];
-};
-
-#endif
diff --git a/beos/liblayout/MEject.h b/beos/liblayout/MEject.h
deleted file mode 100644 (file)
index a9c0173..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef _MEJECT_H
-#define _MEJECT_H
-
-#include "MPictureButton.h"
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT MEject : public MPictureButton
-{
-       public:         MEject(BHandler *id);
-                               MEject(BHandler *id, BMessage*);
-                               MEject(BMessage*);
-                               virtual ~MEject();
-                               virtual long Archive(BMessage *archive, bool deep=true) const;
-                               static BArchivable *Instantiate(BMessage *archive);
-
-                               virtual void MakePictures();
-};
-extern const IMPEXPLIBLAYOUT char M_BUTTON_POINTER[];
-
-#endif
diff --git a/beos/liblayout/MFFWD.h b/beos/liblayout/MFFWD.h
deleted file mode 100644 (file)
index 97c0d53..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef _MFFWD_H
-#define _MFFWD_H
-
-#include "MPictureButton.h"
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT MFFWD : public MPictureButton
-{
-       public:         MFFWD(BHandler *id=NULL);
-                               MFFWD(BHandler *id, BMessage*);
-                               MFFWD(BMessage*);
-                               virtual ~MFFWD();
-                               virtual long Archive(BMessage *archive, bool deep=true) const;
-                               static BArchivable *Instantiate(BMessage *archive);
-                               
-                               virtual void MakePictures();
-};
-
-extern const IMPEXPLIBLAYOUT char M_BUTTON_POINTER[];
-
-#endif
diff --git a/beos/liblayout/MGroup.h b/beos/liblayout/MGroup.h
deleted file mode 100644 (file)
index 73dcbfb..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
-
-       MGroup is an abstract class from which all groups should derive.
-
-*/
-
-#ifndef _MGROUP_H
-#define _MGROUP_H
-
-#include "layout.h"
-#include <View.h>
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT MGroup : public MView
-{
-       public:         MGroup();
-                               virtual ~MGroup();
-
-                               virtual void    reloadfont(BFont *font[]);
-};
-
-typedef struct
-{
-       MView   *kid;
-       int             kidnum;
-}  sortstruct;
-
-#endif
diff --git a/beos/liblayout/MListView.h b/beos/liblayout/MListView.h
deleted file mode 100644 (file)
index 95c4d42..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-
-#ifndef _MLISTVIEW_H
-#define _MLISTVIEW_H
-#include "layout.h"
-#include <ListView.h>
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT MListView :  public MView, public BListView
-{
-       public:         MListView(list_view_type type=B_SINGLE_SELECTION_LIST,
-                                                                        minimax size=minimax(50,50));
-                               MListView(BMessage*);
-                               virtual ~MListView();
-                               virtual long Archive(BMessage *archive, bool deep=true) const;
-                               static BArchivable *Instantiate(BMessage *archive);
-                               virtual void reloadfont(BFont *font[]);
-                               virtual minimax layoutprefs();
-                               virtual BRect   layout(BRect rect);
-                               virtual void    MessageReceived(BMessage*);
-                               virtual void    AttachedToWindow();
-                               virtual void DetachedFromWindow();
-
-       private:        virtual void _expansionmlistview1(); 
-                               uint32  _expansiondata[2];
-};
-
-#endif
diff --git a/beos/liblayout/MMenuBar.h b/beos/liblayout/MMenuBar.h
deleted file mode 100644 (file)
index a5b061a..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-
-#ifndef _MMENUBAR_H
-#define _MMENUBAR_H
-
-#include "layout.h"
-#include <MenuBar.h>
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT MMenuBar: public MView, public BMenuBar
-{
-       public:
-               MMenuBar(menu_layout layout=B_ITEMS_IN_ROW);
-               MMenuBar(menu_layout layout, bool resizetofit);
-               MMenuBar(BMessage*);
-               virtual ~MMenuBar();
-               virtual long Archive(BMessage *archive, bool deep=true) const;
-               static BArchivable *Instantiate(BMessage *archive);
-               
-               virtual minimax layoutprefs();
-               virtual BRect layout(BRect);
-               virtual void    reloadfont(BFont *font[]);
-               virtual void AttachedToWindow();
-               virtual void DetachedFromWindow();
-       private:
-               virtual void _expansionmmenubar1();
-               virtual void _expansionmmenubar2();
-
-               uint32  _expansiondata[2];
-};
-#endif
diff --git a/beos/liblayout/MOutlineListView.h b/beos/liblayout/MOutlineListView.h
deleted file mode 100644 (file)
index acb00e1..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-
-#ifndef _MOUTLINELISTVIEW_H
-#define _MOUTLINELISTVIEW_H
-#include "layout.h"
-#include <OutlineListView.h>
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT MOutlineListView :  public MView, public BOutlineListView
-{
-       public:         MOutlineListView(list_view_type type=B_SINGLE_SELECTION_LIST,
-                                                                        minimax size=minimax(50,50));
-                               MOutlineListView(BMessage*);
-                               virtual ~MOutlineListView();
-                               virtual long Archive(BMessage *archive, bool deep=true) const;
-                               static BArchivable *Instantiate(BMessage *archive);
-                               virtual void reloadfont(BFont *font[]);
-                               virtual minimax layoutprefs();
-                               virtual BRect   layout(BRect rect);
-                               virtual void    MessageReceived(BMessage*);
-                               virtual void    AttachedToWindow();
-                               virtual void DetachedFromWindow();
-
-       private:        virtual void _expansionmoutlinelistview1(); 
-                               virtual void _expansionmoutlinelistview2(); 
-
-                               uint32  _expansiondata[2];
-};
-
-#endif
diff --git a/beos/liblayout/MPictureButton.h b/beos/liblayout/MPictureButton.h
deleted file mode 100644 (file)
index 687b5c2..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef _MPICTUREBUTTON_H
-#define _MPICTUREBUTTON_H
-
-#include "layout.h"
-#include <PictureButton.h>
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT MPictureButton : public MView, public BPictureButton
-{
-       public:
-               MPictureButton(minimax size, BPicture *off, BPicture *on,
-                               BMessage *message=NULL, BHandler *target=NULL,
-                               uint32 behavior=B_ONE_STATE_BUTTON);
-               MPictureButton(BMessage *archive);
-               virtual ~MPictureButton();
-                               void    SetRepeat(ulong initial_delay, ulong repeat_delay);
-
-               virtual long Archive(BMessage *archive, bool deep=true) const;
-               static BArchivable *Instantiate(BMessage *archive);
-
-               virtual minimax layoutprefs();
-               virtual BRect layout(BRect);
-               virtual void setcolor(rgb_color col, bool deep=false);
-               virtual void MakePictures();
-
-               virtual void AttachedToWindow();
-               virtual void DetachedFromWindow();
-               virtual void MouseDown(BPoint);
-
-       private:
-               virtual void _expansionmpicturebutton1(); 
-               virtual void _expansionmpicturebutton2(); 
-
-               thread_id       mousethread;
-               int64           lastwhen;
-               ulong   initialdelay;
-               ulong   repeatdelay;
-               ulong           buttonmask;
-               BHandler        *target;
-
-               static  long _mousetracker(void *arg);
-                               void _MouseTracker();
-
-               uint32  _expansiondata[2];
-};
-
-extern const IMPEXPLIBLAYOUT char M_DOUBLECLICK[];
-extern const IMPEXPLIBLAYOUT char M_BUTTON_MASK[];
-extern const IMPEXPLIBLAYOUT char M_REPEAT[];
-extern const IMPEXPLIBLAYOUT char M_RELEASE[];
-
-#endif
diff --git a/beos/liblayout/MPlayBW.h b/beos/liblayout/MPlayBW.h
deleted file mode 100644 (file)
index 043aa46..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef _MPLAYBW_H
-#define _MPLAYBW_H
-
-#include "MPictureButton.h"
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT MPlayBW : public MPictureButton
-{
-       public:         MPlayBW(BHandler*);
-                               MPlayBW(BHandler *id, BMessage*);
-                               MPlayBW(BMessage*);
-                               virtual ~MPlayBW();
-                               virtual long Archive(BMessage *archive, bool deep=true) const;
-                               static BArchivable *Instantiate(BMessage *archive);
-
-                               virtual void MakePictures();
-};
-extern const IMPEXPLIBLAYOUT char M_BUTTON_POINTER[];
-
-#endif
diff --git a/beos/liblayout/MPlayFW.h b/beos/liblayout/MPlayFW.h
deleted file mode 100644 (file)
index 7f847df..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef _MPLAYFW_H
-#define _MPLAYFW_H
-
-#include "MPictureButton.h"
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT MPlayFW : public MPictureButton
-{
-       public:         MPlayFW(BHandler*);
-                               MPlayFW(BHandler *id, BMessage*);
-                               MPlayFW(BMessage*);
-                               virtual ~MPlayFW();
-                               virtual long Archive(BMessage *archive, bool deep=true) const;
-                               static BArchivable *Instantiate(BMessage *archive);
-                               virtual void MakePictures();
-};
-extern const IMPEXPLIBLAYOUT char M_BUTTON_POINTER[];
-
-#endif
diff --git a/beos/liblayout/MPopup.h b/beos/liblayout/MPopup.h
deleted file mode 100644 (file)
index 2223664..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-
-#ifndef _MPOPUP_H
-#define _MPOPUP_H
-#include "layout.h"
-#include "MDividable.h"
-#include <MenuField.h>
-
-class BPopUpMenu;
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT MPopup:
-       public MView, public MDividable, public BMenuField
-{
-       public:         MPopup(char *label, char *item ...);
-                               MPopup(char *label, BMessage*, BHandler *, char *item ...);
-                               MPopup(BMessage*);
-                               virtual ~MPopup();
-                               virtual long Archive(BMessage *archive, bool deep=true) const;
-                               static BArchivable *Instantiate(BMessage *archive);
-
-                               virtual float   LabelWidth();
-
-                               virtual minimax layoutprefs();
-                               virtual BRect   layout(BRect rect);
-                               virtual void    reloadfont(BFont *font[]);
-                               void                    SetActive(ulong, bool send=true);
-                               void                    EnableItem(ulong index, bool enabled);
-                               virtual void    AttachedToWindow();
-                               virtual void    DetachedFromWindow();
-
-       private:        virtual void _expansionmpopup1();
-
-                               char            *poplabel;
-                               BHandler        *target;
-                               BPopUpMenu      *popup;
-
-                               uint32  _expansiondata[2];
-};
-
-extern const IMPEXPLIBLAYOUT char M_POPUP_POINTER_NAME[];
-
-#endif
diff --git a/beos/liblayout/MProgressBar.h b/beos/liblayout/MProgressBar.h
deleted file mode 100644 (file)
index 3938c25..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-
-#ifndef _MSTATUSBAR_H
-#define _MSTATUSBAR_H
-#include "layout.h"
-#include <View.h>
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT MProgressBar :  public MView, public BView
-{
-       public:         float   value;
-                               float currentwidth;
-
-       public:         MProgressBar(BHandler *, bool pulsed_updates=false);
-                               MProgressBar(BMessage*);
-                               virtual ~MProgressBar();
-                               virtual long Archive(BMessage *archive, bool deep=true) const;
-                               static BArchivable *Instantiate(BMessage *archive);
-
-                               virtual minimax layoutprefs();
-                               virtual BRect   layout(BRect rect);
-                               virtual void    setcolor(rgb_color,bool);
-                                               void    setbarcolor(rgb_color);
-                                       rgb_color       getbarcolor() {return bar_fill;};
-                               virtual void    Draw(BRect);
-                               virtual void    Pulse();
-                                               void    Refresh();
-                                               void    SetValue(float value);
-                               virtual void    MouseDown(BPoint);
-                               virtual void    WindowActivated(bool);
-                               virtual void    FrameResized(float,float);
-                               virtual void    MessageReceived(BMessage *mes);
-                               virtual void    AttachedToWindow();
-                               virtual void    DetachedFromWindow();
-
-       private:        virtual void _expansionmprogressbar1(); 
-                               virtual void _expansionmprogressbar2(); 
-
-                               thread_id               mousethread;
-                               static  long    _mousetracker(void *arg);
-                                               long    mousetracker();
-
-                               BRect   lastbounds;
-                               BHandler *target;
-                               rgb_color       bar_hi;
-                               rgb_color       bar_fill;
-                               rgb_color       bar_low;
-                               float barwidth;
-
-                               uint32  _expansiondata[2];
-};
-
-extern const IMPEXPLIBLAYOUT char M_PROGRESSBAR_FRACTION[];
-
-#endif
-
diff --git a/beos/liblayout/MRadioGroup.h b/beos/liblayout/MRadioGroup.h
deleted file mode 100644 (file)
index bb430f2..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-
-#ifndef _MRADIOGROUP_H
-#define _MRADIOGROUP_H
-#include "MGroup.h"
-#include <RadioButton.h>
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT MRadioGroup :  public MGroup, public BView
-{
-       public:         MRadioGroup(char *item ...);
-                               MRadioGroup(BMessage *model, char *item ...);
-                               MRadioGroup(BMessage *model, BHandler *target, char *item ...);
-                               MRadioGroup(BMessage*);
-                               virtual ~MRadioGroup();
-                               virtual long Archive(BMessage *archive, bool deep=true) const;
-                               static BArchivable *Instantiate(BMessage *archive);
-
-                               virtual minimax layoutprefs();
-                               virtual BRect   layout(BRect rect);
-                               virtual void    SetActive(ulong);
-                               virtual long    ActiveButton();
-                               virtual void    reloadfont(BFont *font[]);
-                               virtual void    setcolor(rgb_color col,bool deep);
-                               virtual void    AttachedToWindow();
-                               virtual void    DetachedFromWindow();
-
-       private:        virtual void _expansionmradiogroup1(); 
-                               virtual void _expansionmradiogroup2(); 
-
-                               ulong           numradios;
-                               BHandler        *handler;
-
-                               uint32  _expansiondata[3];
-};
-
-extern const IMPEXPLIBLAYOUT char M_RADIO_POINTER_NAME[];
-extern const IMPEXPLIBLAYOUT char M_RADIO_INDEX_NAME[];
-
-
-#endif
-
-
-
diff --git a/beos/liblayout/MRew.h b/beos/liblayout/MRew.h
deleted file mode 100644 (file)
index f21683b..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef _MREW_H
-#define _MREW_H
-
-#include "MPictureButton.h"
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT MRew : public MPictureButton
-{
-       public:         MRew(BHandler*);
-                               MRew(BHandler *id, BMessage*);
-                               MRew(BMessage*);
-                               virtual ~MRew();
-                               virtual long Archive(BMessage *archive, bool deep=true) const;
-                               static BArchivable *Instantiate(BMessage *archive);
-                               virtual void MakePictures();
-};
-extern const IMPEXPLIBLAYOUT char M_BUTTON_POINTER[];
-
-#endif
diff --git a/beos/liblayout/MScrollView.h b/beos/liblayout/MScrollView.h
deleted file mode 100644 (file)
index 8ba21ce..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-
-#ifndef _MSCROLLVIEW_H
-#define _MSCROLLVIEW_H
-
-#include "layout.h"
-#include <ScrollView.h>
-
-// An MScrollView accepts another MView as its target.
-// The MScrollView will display scrollbars as requested
-// so that the target MView may be scrolled left/right or
-// up/down.
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT MScrollView: public MView, public BScrollView
-{
-       public:
-               MScrollView(MView *target, bool horizontal=false, bool vertical=false,
-                       border_style border=B_FANCY_BORDER, minimax size=0);
-               MScrollView(BMessage*);
-               virtual ~MScrollView();
-               virtual long Archive(BMessage *archive, bool deep=true) const;
-               static BArchivable *Instantiate(BMessage *archive);
-               virtual minimax layoutprefs();
-               virtual BRect layout(BRect);
-               virtual void    AttachedToWindow();
-               virtual void DetachedFromWindow();
-
-       private:
-               MView *kid;
-               float leftinset;
-               float rightinset;
-               float topinset;
-               float bottominset;
-};
-
-#endif
diff --git a/beos/liblayout/MSlider.h b/beos/liblayout/MSlider.h
deleted file mode 100644 (file)
index 6e7077d..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-#ifndef _MSLIDER_H
-#define _MSLIDER_H
-
-#include "layout.h"
-#include "Slider.h"
-
-class IMPEXPLIBLAYOUT MSlider: public MView, public BSlider
-{
-       public:
-               MSlider(const char *label, int32 minval, int32 maxval,int32 granularity=1, BMessage *message=NULL, BHandler *target=NULL, thumb_style ts=B_BLOCK_THUMB);
-               virtual ~MSlider();
-               virtual void AllAttached();
-               virtual void DetachedFromWindow();
-               virtual void SetValue(int32 value);
-               void SetGranularity(int32 granul);
-
-               virtual minimax layoutprefs();
-               virtual BRect layout(BRect);
-               
-       private:
-               virtual void _expansionmslider1();
-               virtual void _expansionmslider2();
-               BHandler *target;
-               int32 granularity;
-               uint32 _expansiondata[4];
-};
-
-#endif
diff --git a/beos/liblayout/MSplitter.h b/beos/liblayout/MSplitter.h
deleted file mode 100644 (file)
index 411c5d1..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-
-#ifndef _MSPLITTER_H
-#define _MSPLITTER_H
-
-#include "layout.h"
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT MSplitter : public MView, public BView
-{
-       public:                                 MSplitter();
-                                                       MSplitter(bool cosmetic);
-                                                       MSplitter(BMessage*);
-                       virtual                 ~MSplitter();
-                       virtual long Archive(BMessage *archive, bool deep=true) const;
-                       static BArchivable *Instantiate(BMessage *archive);
-
-                       virtual minimax layoutprefs();
-                       virtual BRect   layout(BRect rect);
-                       virtual void    MouseDown(BPoint);
-                       virtual void    Draw(BRect);
-                       virtual void    MouseMoved(BPoint, ulong, const BMessage*);
-                       virtual void    AttachedToWindow();
-                       virtual void    DetachedFromWindow();
-
-       private:
-                       float           siblingweight;
-                       MView           *previoussibling;
-                       MView           *nextsibling;
-                       thread_id       mousethread;
-                       static long     _mousetracker(void *);
-                       void            _MouseTracker(void);
-                       uint32          _expansiondata[2];
-};
-
-#endif
diff --git a/beos/liblayout/MStop.h b/beos/liblayout/MStop.h
deleted file mode 100644 (file)
index b99fc2f..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef _MSTOP_H
-#define _MSTOP_H
-
-#include "MPictureButton.h"
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT MStop : public MPictureButton
-{
-       public:         MStop(BHandler*);
-                               MStop(BHandler *id, BMessage*);
-                               MStop(BMessage*);
-                               virtual ~MStop();
-                               virtual long Archive(BMessage *archive, bool deep=true) const;
-                               static BArchivable *Instantiate(BMessage *archive);
-                               virtual void MakePictures();
-};
-extern const IMPEXPLIBLAYOUT char M_BUTTON_POINTER[];
-
-#endif
diff --git a/beos/liblayout/MStringView.h b/beos/liblayout/MStringView.h
deleted file mode 100644 (file)
index 4db7445..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-
-#ifndef _MSTRINGVIEW_H
-#define _MSTRINGVIEW_H
-#include "layout.h"
-#include <StringView.h>
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT MStringView :  public MView, public BStringView
-{
-       public:         MStringView(const char *label,alignment a=B_ALIGN_LEFT,minimax size=minimax(10,10,65536,65536,1));
-                               MStringView(BMessage*);
-                               virtual ~MStringView();
-                               virtual long Archive(BMessage *archive, bool deep=true) const;
-                               static BArchivable *Instantiate(BMessage *archive);
-
-                               virtual minimax layoutprefs();
-                               virtual BRect   layout(BRect rect);
-                               virtual void    AttachedToWindow();
-                               virtual void DetachedFromWindow();
-};
-
-#endif
diff --git a/beos/liblayout/MTabView.h b/beos/liblayout/MTabView.h
deleted file mode 100644 (file)
index 04c69ec..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-
-#ifndef _MTABVIEW_H
-#define _MTABVIEW_H
-
-#include <TabView.h>
-#include "MGroup.h"
-
-class IMPEXPLIBLAYOUT MTab: public BTab
-{
-       public:
-               MTab(MView *view, const char *name=NULL);
-               MTab(BMessage *archive);
-               virtual ~MTab();
-};
-
-
-class IMPEXPLIBLAYOUT MTabView: public MGroup, public BTabView
-{
-       public:
-               MTabView();
-               MTabView(BMessage *archive);
-               virtual void Add(MTab *tab);
-               virtual void Select(int32 tab);
-
-               virtual void    reloadfont(BFont *font[]);
-               virtual minimax layoutprefs();
-               virtual BRect layout(BRect);
-               
-       private:
-               void LayoutCurrentTab();
-};
-
-#endif
diff --git a/beos/liblayout/MTextControl.h b/beos/liblayout/MTextControl.h
deleted file mode 100644 (file)
index 46f1a74..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-
-#ifndef _MTEXTCONTROL_H
-#define _MTEXTCONTROL_H
-#include "layout.h"
-#include "MDividable.h"
-#include <TextControl.h>
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT MTextControl:
-       public MView, public MDividable, public BTextControl
-{
-       public:         MTextControl(char *label, char *text);
-                               MTextControl(char *label, char *text, BMessage *mes);
-                               MTextControl(BMessage*);
-                               virtual ~MTextControl();
-                               virtual long Archive(BMessage *archive, bool deep=true) const;
-                               static BArchivable *Instantiate(BMessage *archive);
-
-                               virtual void    SetLabel(const char *);
-                               virtual float   LabelWidth();
-
-                               virtual minimax layoutprefs();
-                               virtual BRect   layout(BRect rect);
-                               virtual void    reloadfont(BFont *font[]);
-                               virtual void    AttachedToWindow();
-                               virtual void DetachedFromWindow();
-
-       private:        float lastheight;
-
-                               uint32  _expansiondata[2];
-};
-
-#endif
diff --git a/beos/liblayout/MTextView.h b/beos/liblayout/MTextView.h
deleted file mode 100644 (file)
index 512a85c..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-
-#ifndef _MTEXTVIEW_H
-#define _MTEXTVIEW_H
-#include "layout.h"
-#include <TextView.h>
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT MTextView :  public MView, public BTextView
-{
-       public:         MTextView(minimax size=0);
-                               MTextView(BMessage*);
-                               virtual ~MTextView();
-                               virtual long Archive(BMessage *archive, bool deep=true) const;
-                               static BArchivable *Instantiate(BMessage *archive);
-
-                               virtual minimax layoutprefs();
-                               virtual BRect   layout(BRect rect);
-                               virtual void    AttachedToWindow();
-                               virtual void DetachedFromWindow();
-                               virtual void MessageReceived(BMessage *mes);
-
-       private:        void initobject();
-                               static long AsyncSetTextRect(void *arg);
-                               thread_id resizer;
-                               uint32  _expansiondata[2];
-};
-
-#endif
diff --git a/beos/liblayout/MVolume.h b/beos/liblayout/MVolume.h
deleted file mode 100644 (file)
index 9d70b79..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-#ifndef _MVOLUME_H
-#define _MVOLUME_H
-
-#include "layout.h"
-#include <Control.h>
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT MVolume : public MView, public BControl
-{
-       public:         MVolume(BHandler*);
-                               MVolume(BMessage*);
-                               virtual ~MVolume();
-                               virtual long Archive(BMessage *archive, bool deep=true) const;
-                               static BArchivable *Instantiate(BMessage *archive);
-
-                               virtual minimax layoutprefs();
-                               BRect layout(BRect);
-                               virtual void    AttachedToWindow();
-                               virtual void DetachedFromWindow();
-                               virtual void Draw(BRect);
-                               virtual void DrawVolume(void);
-                                               float Volume();
-                                               void SetVolume(float vol);
-                               virtual void MouseDown(BPoint);
-                               virtual void KeyDown(const char *bytes, int32 numbytes);
-
-       private:        float volume;
-                               BHandler *target;
-                               BPoint lastvoldot;
-                               BPoint clickpoint;
-                               thread_id mousethread;
-                               bool ispressed;
-                               // moved into private area 21-6-98
-                               static  long _mousetracker(void *arg);
-                                               void _MouseTracker();
-                               // added 21-6-98
-                                               void _PUMouseTracker();
-};
-
-inline float MVolume::Volume()
-{
-       return volume;
-}
-
-#endif
diff --git a/beos/liblayout/MWindow.h b/beos/liblayout/MWindow.h
deleted file mode 100644 (file)
index 6118f87..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-
-#ifndef _MWINDOW_H
-#define _MWINDOW_H
-
-#include "layout.h"
-#include <Window.h>
-
-class BPopUpMenu;
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT MWindow : public BWindow
-{
-       public:
-               ulong   flags;
-
-               MWindow(BRect r,const char *name,window_type type,uint32 flags, uint32 workspaces=B_CURRENT_WORKSPACE);
-               MWindow(BRect r,const char *name,window_look look, window_feel feel,uint32 flags, uint32 workspaces=B_CURRENT_WORKSPACE);
-               MWindow(BMessage*);
-               virtual ~MWindow();
-               virtual long Archive(BMessage *archive, bool deep=true) const;
-               static BArchivable *Instantiate(BMessage *archive);
-
-               virtual const BFont *getfont(fontspec font);
-
-               virtual void MessageReceived(BMessage *message);
-               virtual void Show();
-               virtual void RecalcSize();
-               virtual void FrameResized(float width, float height);
-
-               virtual status_t GetSupportedSuites(BMessage *message);
-               virtual BHandler *ResolveSpecifier(BMessage *message, int32 index, BMessage *specifier, int32 command, const char *property);
-               virtual void ScreenChanged(BRect frame, color_space mode);
-               virtual void WorkspaceActivated(int32 workspace, bool active);
-
-               void StartDragging();
-               static long _mousetracker(void *arg);
-               void _MouseTracker();
-
-       private:
-               virtual void _expansionmwindow1();
-               virtual void _expansionmwindow2();
-               virtual void _expansionmwindow3();
-
-               void            initobject();
-               BFont           **fontlist;
-               BRect           lastrect;
-               BPopUpMenu      *pop;
-               thread_id       mousethread;
-               BPoint          dragpoint;
-               
-               uint32          _expansiondata[1];
-};
-
-enum {
- M_WIN_AUTORESIZE      =0x00000100,
- M_WIN_ESCAPETOCLOSE=0x00000200
-};
-
-#endif // MWINDOW_H
diff --git a/beos/liblayout/PropGadget.h b/beos/liblayout/PropGadget.h
deleted file mode 100644 (file)
index 81a3f1f..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-
-#ifndef _PROPGADGET
-#define _PROPGADGET
-#include "layout.h"
-#include <Control.h>
-#include <Bitmap.h>
-
-class IMPEXPLIBLAYOUT PropGadget;
-
-typedef void (*propgadget_hook)(PropGadget*, void*, double, double);
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class PropGadget : public MView, public BControl
-{
-       public:         PropGadget(double xprop, double xval, double yprop, double yval,
-                                       BBitmap *knobimage=NULL,
-                                        propgadget_hook=NULL,
-                                        void *callbackarg=NULL,
-                                        long extraspacing=0);
-                               PropGadget(BMessage*);
-                               virtual ~PropGadget();
-                               virtual long Archive(BMessage *archive, bool deep=true) const;
-                               static BArchivable *Instantiate(BMessage *archive);
-
-                               BBitmap*        Pknob;
-
-                               virtual void    Draw(BRect);
-                               virtual void    AttachedToWindow();
-                               virtual void    DetachedFromWindow();
-                               virtual void    MouseDown(BPoint);
-
-                               void                    SetProportion(double, double);
-                               void                    SetProportionNoDraw(double,double);
-                               virtual void    SetValues(double,double);
-                               void                    SetValuesNoDraw(double,double);
-                               virtual void    FrameResized(float,float);
-                               void                    ReDraw();
-                               inline double   Hval() {return hval;}
-                               inline double   Vval() {return 1.0-vval;}
-
-                               virtual minimax layoutprefs();
-                               virtual BRect   layout(BRect rect);
-                               virtual void    setcolor(rgb_color col, bool deep=false);
-                               virtual void    DrawContainer(BRect);
-                               virtual void    DrawKnob(BRect);
-                               virtual void    KeyDown(const char *bytes, int32 numbytes);
-                                               bool    IsBusy();
-
-       private:        virtual void _expansionpropgadget1(); 
-                               virtual void _expansionpropgadget2(); 
-
-                               thread_id mousethread;
-                               BPoint  clickpoint;
-                               BRect   lastknobrect;
-                               bool    _isbusy;
-                               bool    vertical;
-                               bool    horizontal;
-
-                               double  hprop;
-                               double  hval;
-                               double  vprop;
-                               double  vval;
-                               void    (*callback)(PropGadget*,void*,double,double);
-                               void    *callbackarg;
-                               long    borderspacing;
-
-                               static  long    _mousetracker(void *arg);
-                                               void    _MouseTracker();
-
-                               uint32  _expansiondata[2];
-};
-#endif
diff --git a/beos/liblayout/Space.h b/beos/liblayout/Space.h
deleted file mode 100644 (file)
index c49f6fb..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-
-#ifndef _SPACE_H
-#define _SPACE_H
-#include "layout.h"
-#include "View.h"
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-class IMPEXPLIBLAYOUT Space :  public MView, public BView
-{
-       public:         Space();
-                               Space(minimax);
-                               Space(BMessage*);
-               virtual ~Space();
-               virtual long Archive(BMessage *archive, bool deep=true) const;
-               static BArchivable *Instantiate(BMessage *archive);
-               virtual minimax layoutprefs();
-               virtual BRect   layout(BRect rect);
-};
-
-#endif
diff --git a/beos/liblayout/SpinButton.h b/beos/liblayout/SpinButton.h
deleted file mode 100644 (file)
index 3bb00db..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-
-#ifndef _SPINBUTTON_H
-#define _SPINBUTTON_H
-
-#include <View.h>
-#include "layout.h"
-#include "HGroup.h"
-#include "MTextControl.h"
-
-enum spinmode
-{
-       SPIN_FLOAT,
-       SPIN_INTEGER
-};
-
-class NumberTextView;
-class TinyButton;
-#if __POWERPC__
-#pragma warn_hidevirtual off
-#endif
-class IMPEXPLIBLAYOUT SpinButton: public MView, public MDividable, public BControl
-{
-       public:
-               SpinButton(const char *label,spinmode mode, BHandler *target=NULL);
-               virtual ~SpinButton();
-
-               virtual void reloadfont(BFont *font[]);
-               virtual minimax layoutprefs();
-               virtual BRect layout(BRect);
-               
-               virtual float LabelWidth();
-
-               virtual void AllAttached();
-               virtual void DetachedFromWindow();
-               virtual void Draw(BRect);
-               virtual void MessageReceived(BMessage *mes);
-               virtual void SetEnabled(bool);
-
-               double Increment();
-               double Decrement();
-               double StepSize();
-               void SetStepSize(double step);
-
-               virtual void SetValue(int32 v);
-               virtual void SetValue(double v);
-               double Value();
-               double Maximum();
-               void SetMaximum(double max);
-               double Minimum();
-               void SetMinimum(double min);
-               const char * Format() const;
-               void SetFormat(const char *f);
-
-       private:
-               spinmode mode;
-               ulong height;
-               TinyButton *tb1,*tb2;
-               NumberTextView *tv;             
-               long lx,ly;
-               void NotifyWorld(BMessage *mes);
-               BHandler *target;
-               uint32 _expansiondata[4];
-};
-
-enum 
-{
-       M_SPIN_UP='!!up',
-       M_SPIN_DOWN='!!dn',
-       M_SPIN_TICK='!spn'
-};
-
-extern const IMPEXPLIBLAYOUT char M_RELEASE[];
-
-#if __POWERPC__
-#pragma warn_hidevirtual on
-#endif
-
-#endif
diff --git a/beos/liblayout/TabGroup.h b/beos/liblayout/TabGroup.h
deleted file mode 100644 (file)
index 64a2cf9..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-
-#ifndef _TABGROUP_H
-#define _TABGROUP_H
-
-#include "MGroup.h"
-#include <Control.h>
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT TabGroup :  public MGroup, public BControl
-{
-       public:         TabGroup(minimax mpm,char *arg=0, ...);
-                               TabGroup(char *arg=0, ...);
-                               TabGroup(BMessage*);
-                               virtual ~TabGroup();
-                               virtual long Archive(BMessage *archive, bool deep=true) const;
-                               static BArchivable *Instantiate(BMessage *archive);
-                               virtual minimax layoutprefs();
-                               virtual BRect   layout(BRect rect);
-                               virtual void    AttachedToWindow();
-                               virtual void    MouseDown(BPoint point);
-                               virtual void    Draw(BRect clip);
-                               virtual void    KeyDown(const char *bytes, int32 numbytes);
-                               virtual void    ActivateTab(int);
-                                               int32   ActiveTab();
-                               virtual void    DetachedFromWindow();
-                               virtual void    SetEnabled(bool enabled);
-                                               void    SetExtraSpacing(float spacing);
-                                               float   ExtraSpacing();
-
-       private:        virtual void    _expansiontabgroup1();
-                               virtual void    _expansiontabgroup2();
-       
-                               int numkids;
-                               int activekid;
-                               float tabheight;
-                               float biggesttabmin;
-                               float fontdescent;
-                               float extraspacing;
-
-                               uint32 _expansiondata[1];
-};
-
-#endif
diff --git a/beos/liblayout/VGroup.h b/beos/liblayout/VGroup.h
deleted file mode 100644 (file)
index 56be070..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-
-#ifndef _VGROUP_H
-#define _VGROUP_H
-#include "MGroup.h"
-#include <View.h>
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-class IMPEXPLIBLAYOUT VGroup :  public MGroup, public BView
-{
-       public:         VGroup(minimax mpm,MView *kid=0, ...);
-                               VGroup(MView *kid=0, ...);
-                               VGroup(BMessage*);
-                               virtual ~VGroup();
-                               virtual long Archive(BMessage *archive, bool deep=true) const;
-                               static BArchivable *Instantiate(BMessage *archive);
-                               virtual minimax layoutprefs();
-                               virtual BRect   layout(BRect rect);
-                               virtual void AttachedToWindow();
-                               virtual void DetachedFromWindow();
-                               virtual void MouseDown(BPoint);
-
-       private:        virtual void _expansionvgroup1();
-                               virtual void _expansionvgroup2();
-                               virtual void _expansionvgroup3();
-
-                               static int cmpkids(const void* v1,const void *v2);
-                               int *size;
-                               float totalweight;
-                               int numkids;
-                               sortstruct      *childorder;
-                               MView **mkid;
-                               float totalminy,totalmaxy;
-                               BRect *lastrect;
-
-                               uint32  _expansiondata[2];
-};
-
-#endif
diff --git a/beos/liblayout/layout-all.h b/beos/liblayout/layout-all.h
deleted file mode 100644 (file)
index b2e78df..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-#include "MApplication.h"
-#include "MWindow.h"
-#include "HGroup.h"
-#include "VGroup.h"
-#include "LayeredGroup.h"
-#include "TabGroup.h"
-#include "MBViewWrapper.h"
-#include "MBorder.h"
-#include "MButton.h"
-#include "MCheckBox.h"
-#include "MDividable.h"
-#include "MDragBar.h"
-#include "MEject.h"
-#include "MFFWD.h"
-#include "MListView.h"
-#include "MMenuBar.h"
-#include "MOutlineListView.h"
-#include "MPictureButton.h"
-#include "MPlayBW.h"
-#include "MPlayFW.h"
-#include "MPopup.h"
-#include "MProgressBar.h"
-#include "MRadioGroup.h"
-#include "MRew.h"
-#include "MScrollView.h"
-#include "MSlider.h"
-#include "MSplitter.h"
-#include "MStop.h"
-#include "MStringView.h"
-#include "MTextControl.h"
-#include "MTextView.h"
-#include "MVolume.h"
-#include "PropGadget.h"
-#include "Space.h"
-#include "SpinButton.h"
diff --git a/beos/liblayout/layout.h b/beos/liblayout/layout.h
deleted file mode 100644 (file)
index 772b251..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
-
-       Lowest-level classes in liblayout
-       - minimax, used to store information about minimum size, maximum size, and weigth of objects
-       - MView, a class that knows how to layout itself
-
-*/
-
-#ifndef _LAYOUT_H
-#define _LAYOUT_H
-
-#if __POWERPC__
-#pragma simple_class_byval off
-#endif
-
-#include <BeBuild.h>
-
-#if !defined(IMPEXPLIBLAYOUT) && defined(BUILDING_LIBLAYOUT)
-#define IMPEXPLIBLAYOUT        _EXPORT
-#else
-#define IMPEXPLIBLAYOUT        _IMPORT
-#endif
-
-#include <Rect.h>
-#include <GraphicsDefs.h>
-#include <stdlib.h>
-
-class BMessage;
-class BFont;
-
-// use macro to make code slightly more readable
-#define MVPTR(x) dynamic_cast<MView*>(x)
-
-enum fontspec
-{
-       M_PLAIN_FONT=0,
-       M_BOLD_FONT,
-       M_FIXED_FONT
-};
-
-
-// this structure is exported from liblayout, and contains the version number
-struct LAYOUT_VERSION_INFO
-{
-       uchar major;
-       uchar minor;
-       ushort patchlevel;
-};
-
-extern "C" LAYOUT_VERSION_INFO IMPEXPLIBLAYOUT LIBLAYOUT_VERSION;
-
-
-class IMPEXPLIBLAYOUT minimax  // Order now, by dialing the number on your screen!
-{
-struct xypair { float x,y;};
-
-       public:         xypair  mini;
-                               xypair  maxi;
-                               float   weight;
-                               
-                               minimax(int minx=0,int miny=0,
-                                               int maxx=10000,int maxy=10000,
-                                               float wght=1.0);
-};
-
-class IMPEXPLIBLAYOUT MView
-{
-       protected:      rgb_color       FILL_COLOR;
-                               rgb_color       LOW_COLOR;
-                               rgb_color       HI_COLOR;
-
-                               // helper functions for archiving/unarchiving the MView
-                               // part of MView hybrids
-                               status_t archive(BMessage *);
-                               status_t unarchive(BMessage *);
-
-       public:         minimax mpm;            // currently active minimax (calculated from ct_mpm and environmental constraints)
-                               minimax ct_mpm;         // size specified at construction-time
-                               ulong   flags;          // various flags
-                                                                       // upper 16 bits are reserve for liblayout-use
-                                                                       // bits 8-15 are reserved for per-class liblayout-use
-                                                                       // bits 0-7 are available
-
-                               MView();
-                               virtual ~MView();
-                               virtual minimax layoutprefs()=0;
-                               virtual BRect   layout(BRect rect)=0;
-
-                               // reload the font from one of the fonts in the font-array
-                               virtual void    reloadfont(BFont *font[]);
-                               // get a BFont with the required fontspec
-                               const BFont     *getfont(fontspec font);
-
-                               // set the color of the MView
-                               virtual void    setcolor(rgb_color col, bool deep=true);
-                               // this one calls the above function
-                                               void    setcolor(uchar red, uchar green, uchar blue, bool deep=true);
-                                       rgb_color       getcolor(); // get the base color (what is set through setcolor() )
-                               
-       private:
-                       virtual void _expansionmview1();
-                       virtual void _expansionmview2();
-                       virtual void _expansionmview3();
-                       virtual void _expansionmview4();
-
-                       uint32 _expansiondata[4];
-};
-
-
-// constants used in messaging all start with a '!'
-#define M_POPUP_SELECTED               '!pop'
-#define M_CHECKBOX_SELECTED            '!chk'
-#define M_BUTTON_SELECTED              '!but'
-#define M_RADIO_SELECTED               '!rad'
-#define M_PLAYBW_SELECTED              '!ylp'
-#define M_PLAYFW_SELECTED              '!ply'
-#define M_FFWD_SELECTED                        '!fwd'
-#define M_REW_SELECTED                         '!rwd'
-#define M_STOP_SELECTED                        '!stp'
-#define M_VOLUME_CHANGED               '!vol'
-#define M_EJECT_SELECTED               '!ejt'
-#define M_PREV_SELECTED                        '!prv'
-#define M_NEXT_SELECTED                        '!nxt'
-#define M_PROGRESSBAR_CLICKED  '!pbc'
-#define M_PROGRESSBAR_DRAGGED  '!pbd'
-#define M_PROGRESSBAR_RELEASED '!pbr'
-#define M_ACTIVATE_LAYER               '!lyr'
-
-// when sent to a window, it recalculates the entire window
-#define M_RECALCULATE_SIZE             '!rsz'
-
-// font-change message is understood by MWindow and MApplication,
-// but is not generated by liblayout.
-#define M_FONT_CHANGED                 '!FNT'
-
-extern IMPEXPLIBLAYOUT rgb_color M_FILL_COLOR;
-extern IMPEXPLIBLAYOUT rgb_color M_LOW_COLOR;
-extern IMPEXPLIBLAYOUT rgb_color M_HI_COLOR;
-extern IMPEXPLIBLAYOUT rgb_color BLACK_COLOR;
-extern IMPEXPLIBLAYOUT rgb_color WHITE_COLOR;
-
-void IMPEXPLIBLAYOUT SetDefaultColors(uchar red, uchar green, uchar blue);
-void IMPEXPLIBLAYOUT SetDefaultColors(rgb_color cs);
-
-// misc flags
-// note that not all controls responds to all flags
-
-enum{
-       M_REPORT_IMMEDIATE=                     0x00010000,             // report first click on control
-       M_REPORT_REPEAT =                       0x00020000,             // report if control is clicked and held
-       M_REPORT_RELEASE=                       0x00040000,             // report release of button over control
-       M_REPORT_RELEASE_ALWAYS=        0x00080000,             // always report release of button
-       M_REPORT_MASK=                          0x000f0000,             // all of the above
-       
-       // mostly for internal use, therefore not documented (yet)
-       M_USE_CALCULATED_MINX=          0x00100000,
-       M_USE_CALCULATED_MINY=          0x00200000,
-       M_USE_CALCULATED_MAXX=          0x00400000,
-       M_USE_CALCULATED_MAXY=          0x00800000,
-       M_NO_X_LEFTOVERS=                       0x01000000, // don't add "leftover" space to this object
-       M_NO_Y_LEFTOVERS=                       0x02000000, // don't add "leftover" space to this object
-       M_NO_COLOR_CHANGES=                     0x20000000, // don't listen to color-drop messages
-       M_NO_FONT_CHANGES=                      0x40000000, // don't listen to font-change messages
-       M_USE_FULL_SIZE =         (int) 0x80000000      // don't respect max-size (set for grouping classes)
-};
-
-
-#endif
diff --git a/configure b/configure
new file mode 100755 (executable)
index 0000000..d0c2928
--- /dev/null
+++ b/configure
@@ -0,0 +1,90 @@
+#! /bin/sh
+
+CC="gcc"
+CXX="g++"
+CCFLAGS="$CCFLAGS -Wall -g"
+OPTIM="$OPTIM -O3 -funroll-loops"
+
+# System-specific flags
+SYSTEM=`uname -s`
+case $SYSTEM in
+  BeOS)
+    CCFLAGS="$CCFLAGS -Wno-multichar"
+    DEFINES="$DEFINES SYS_BEOS"
+    LINKLIBS="$LINKLIBS -lbe -ltracker"
+
+    RELEASE=`uname -r`
+    case $RELEASE in
+      6.0|5.0.4) # Zeta or R5 / BONE beta 7
+        SYSTEM="$SYSTEM / BONE"
+        LINKLIBS="$LINKLIBS -lbind -lsocket"
+        ;;
+      5.0*)      # R5 / net_server
+        SYSTEM="$SYSTEM / net_server"
+        DEFINES="$DEFINES BEOS_NETSERVER"
+        LINKLIBS="$LINKLIBS -lnet"
+        ;;
+      *)
+        echo "Unsupported BeOS version"
+        exit 1 ;;
+    esac
+    ;;
+
+  Darwin)
+    DEFINES="$DEFINES SYS_DARWIN"
+    LINKLIBS="$LINKLIBS -lpthread"
+    ;;
+
+  FreeBSD)
+    DEFINES="$DEFINES SYS_FREEBSD"
+    LINKLIBS="$LINKLIBS -pthread"
+    ;;
+
+  NetBSD)
+    DEFINES="$DEFINES SYS_NETBSD"
+    LINKLIBS="$LINKLIBS -lpthread"
+    ;;
+
+  Linux)
+    DEFINES="$DEFINES SYS_LINUX"
+    LINKLIBS="$LINKLIBS -lpthread"
+    ;;
+
+  *)
+    echo "Unsupported operating system"
+    exit 1 ;;
+esac
+echo "System: $SYSTEM"
+
+# Check for endianness (we need to define WORDS_BIGENDIAN for libdvdread)
+cat > testconf.c << EOF
+int main()
+{
+    int i = 1;
+    return *( (char *) &i );
+}
+EOF
+if ( cc -o testconf testconf.c && ./testconf ) > /dev/null 2>&1
+then
+  echo "Endian: big"
+  DEFINES="$DEFINES WORDS_BIGENDIAN"
+else
+  echo "Endian: little"
+fi
+rm -f testconf.c testconf
+
+# Generate config.jam
+rm -f config.jam
+cat << EOF > config.jam
+CC       = $CC ;
+C++      = $CXX ;
+LINK     = $CXX ;
+CCFLAGS  = $CCFLAGS ;
+C++FLAGS = $CCFLAGS ;
+OPTIM    = $OPTIM ;
+DEFINES  = $DEFINES ;
+LINKLIBS = $LINKLIBS ;
+EOF
+
+echo
+echo "To build HandBrake, run 'jam'."
diff --git a/contrib/Jamfile b/contrib/Jamfile
new file mode 100644 (file)
index 0000000..5bdf71b
--- /dev/null
@@ -0,0 +1,270 @@
+SubDir TOP contrib ;
+
+# Use curl on Mac OS X since it's always installed, and assume wget
+# is installed for all other systems
+if $(OS) = MACOSX
+{
+    WGET = curl -o ;
+}
+else
+{
+    WGET = wget -O ;
+}
+
+# Wget rule: downloads $(<) from the link in $(>)
+rule Wget
+{
+    Depends $(<) : $(>) ;
+}
+actions Wget
+{
+    $(RM) $(<) &&
+    $(WGET) $(<) `cat $(>)` &&
+    ( touch $(<) || true )
+}
+
+# liba52
+rule LibA52
+{
+    Depends $(<) : $(>) ;
+    Depends lib  : $(<) ;
+}
+actions LibA52
+{
+    cd `dirname $(>)` && CONTRIB=`pwd` &&
+    rm -rf a52dec && tar xzf a52dec.tar.gz && cd a52dec &&
+    ./configure --prefix=$CONTRIB && make && make install &&
+    strip -S $CONTRIB/lib/liba52.a
+}
+Wget   $(SUBDIR)/a52dec.tar.gz : $(SUBDIR)/version_a52dec.txt ;
+LibA52 $(SUBDIR)/lib/liba52.a  : $(SUBDIR)/a52dec.tar.gz ;
+
+# libavcodec
+rule LibAvCodec
+{
+    Depends $(<) : $(>) ;
+    Depends lib  : $(<) ;
+}
+actions LibAvCodec
+{
+    cd `dirname $(>)` && CONTRIB=`pwd` &&
+    rm -rf ffmpeg && tar xzf ffmpeg.tar.gz && cd ffmpeg &&
+    ./configure --prefix=$CONTRIB --enable-gpl &&
+    make -C libavcodec && make -C libavutil &&
+    make -C libavcodec installlib && make -C libavutil installlib &&
+    strip -S $CONTRIB/lib/libavcodec.a
+}
+Wget       $(SUBDIR)/ffmpeg.tar.gz    : $(SUBDIR)/version_ffmpeg.txt ;
+LibAvCodec $(SUBDIR)/lib/libavcodec.a : $(SUBDIR)/ffmpeg.tar.gz ;
+
+rule LibAvUtil
+{
+    Depends $(<) : $(>) ;
+    Depends lib  : $(<) ;
+}
+actions LibAvUtil
+{
+    strip -S $(<)
+}
+LibAvUtil $(SUBDIR)/lib/libavutil.a : $(SUBDIR)/lib/libavcodec.a ;
+
+# libdvdcss
+# We need libdvdcss.so for libdvdread's configure to work...
+rule LibDvdCss
+{
+    Depends $(<) : $(>) ;
+    Depends lib  : $(<) ;
+}
+actions LibDvdCss
+{
+    cd `dirname $(>)` && CONTRIB=`pwd` &&
+    rm -rf libdvdcss && tar xzf libdvdcss.tar.gz && cd libdvdcss &&
+    ./configure --prefix=$CONTRIB && make && make install &&
+    strip -S $CONTRIB/lib/libdvdcss.a
+}
+Wget      $(SUBDIR)/libdvdcss.tar.gz : $(SUBDIR)/version_libdvdcss.txt ;
+LibDvdCss $(SUBDIR)/lib/libdvdcss.a  : $(SUBDIR)/libdvdcss.tar.gz ;
+
+# libdvdread
+rule LibDvdRead
+{
+    Depends $(<) : $(>) ;
+    Depends lib  : $(<) ;
+}
+actions LibDvdRead
+{
+    cd `dirname $(>)` && CONTRIB=`pwd` &&
+    rm -rf libdvdread && tar xzf libdvdread.tar.gz && cd libdvdread &&
+    ./configure --prefix=$CONTRIB --disable-shared --with-libdvdcss=$CONTRIB &&
+    make && make install &&
+    strip -S $CONTRIB/lib/libdvdread.a
+}
+Wget       $(SUBDIR)/libdvdread.tar.gz : $(SUBDIR)/version_libdvdread.txt ;
+LibDvdRead $(SUBDIR)/lib/libdvdread.a  : $(SUBDIR)/libdvdread.tar.gz ;
+
+# libfaac
+rule LibFaac
+{
+    Depends $(<) : $(>) ;
+    Depends lib  : $(<) ;
+}
+actions LibFaac
+{
+    cd `dirname $(>)` && CONTRIB=`pwd` &&
+    rm -rf faac && tar xzf faac.tar.gz && cd faac &&
+    ./configure --prefix=$CONTRIB --disable-shared &&
+    make && make install &&
+    strip -S $CONTRIB/lib/libfaac.a
+}
+Wget    $(SUBDIR)/faac.tar.gz   : $(SUBDIR)/version_faac.txt ;
+LibFaac $(SUBDIR)/lib/libfaac.a : $(SUBDIR)/faac.tar.gz ;
+
+# libmp3lame
+rule LibMp3Lame
+{
+    Depends $(<) : $(>) ;
+    Depends lib  : $(<) ;
+}
+actions LibMp3Lame
+{
+    cd `dirname $(>)` && CONTRIB=`pwd` &&
+    rm -rf lame && tar xzf lame.tar.gz && cd lame &&
+    ./configure --prefix=$CONTRIB --disable-shared &&
+    make && make install &&
+    strip -S $CONTRIB/lib/libmp3lame.a
+}
+Wget       $(SUBDIR)/lame.tar.gz      : $(SUBDIR)/version_lame.txt ;
+LibMp3Lame $(SUBDIR)/lib/libmp3lame.a : $(SUBDIR)/lame.tar.gz ;
+
+# libmp4v2
+rule LibMp4v2
+{
+    Depends $(<) : $(>) ;
+    Depends lib  : $(<) ;
+}
+actions LibMp4v2
+{
+    cd `dirname $(>)` && CONTRIB=`pwd` &&
+    rm -rf mpeg4ip && tar xzf mpeg4ip.tar.gz && cd mpeg4ip &&
+    ./bootstrap && make -C lib/mp4v2 libmp4v2.la &&
+    cp lib/mp4v2/.libs/libmp4v2.a $CONTRIB/lib &&
+    cp mpeg4ip_config.h include/mpeg4ip.h include/mpeg4ip_version.h \
+      include/mpeg4ip_win32.h lib/mp4v2/mp4.h $CONTRIB/include &&
+    strip -S $CONTRIB/lib/libmp4v2.a
+}
+Wget     $(SUBDIR)/mpeg4ip.tar.gz : $(SUBDIR)/version_mpeg4ip.txt ;
+LibMp4v2 $(SUBDIR)/lib/libmp4v2.a : $(SUBDIR)/mpeg4ip.tar.gz ;
+
+# libmpeg2
+rule LibMpeg2
+{
+    Depends $(<) : $(>) ;
+    Depends lib  : $(<) ;
+}
+actions LibMpeg2
+{
+    cd `dirname $(>)` && CONTRIB=`pwd` &&
+    rm -rf mpeg2dec && tar xzf mpeg2dec.tar.gz && cd mpeg2dec &&
+    ./configure --prefix=$CONTRIB --disable-shared &&
+    make && make install &&
+    strip -S $CONTRIB/lib/libmpeg2.a
+}
+Wget     $(SUBDIR)/mpeg2dec.tar.gz : $(SUBDIR)/version_mpeg2dec.txt ;
+LibMpeg2 $(SUBDIR)/lib/libmpeg2.a  : $(SUBDIR)/mpeg2dec.tar.gz ;
+
+# libogg
+rule LibOgg
+{
+    Depends $(<) : $(>) ;
+    Depends lib  : $(<) ;
+}
+actions LibOgg
+{
+    cd `dirname $(>)` && CONTRIB=`pwd` &&
+    rm -rf libogg && tar xzf libogg.tar.gz && cd libogg &&
+    ./configure --prefix=$CONTRIB --disable-shared &&
+    make && make install &&
+    strip -S $CONTRIB/lib/libogg.a
+}
+Wget   $(SUBDIR)/libogg.tar.gz : $(SUBDIR)/version_libogg.txt ;
+LibOgg $(SUBDIR)/lib/libogg.a  : $(SUBDIR)/libogg.tar.gz ;
+
+# libsamplerate
+rule LibSampleRate
+{
+    Depends $(<) : $(>) ;
+    Depends lib  : $(<) ;
+}
+actions LibSampleRate
+{
+    cd `dirname $(>)` && CONTRIB=`pwd` &&
+    rm -rf libsamplerate && tar xzf libsamplerate.tar.gz && cd libsamplerate &&
+    ./configure --prefix=$CONTRIB --disable-shared &&
+    make && make install &&
+    strip -S $CONTRIB/lib/libsamplerate.a
+}
+Wget          $(SUBDIR)/libsamplerate.tar.gz : $(SUBDIR)/version_libsamplerate.txt ;
+LibSampleRate $(SUBDIR)/lib/libsamplerate.a  : $(SUBDIR)/libsamplerate.tar.gz ;
+
+# libvorbis
+rule LibVorbis
+{
+    Depends $(<) : $(>) ;
+    Depends lib  : $(<) ;
+}
+actions LibVorbis
+{
+    cd `dirname $(>)` && CONTRIB=`pwd` &&
+    rm -rf libvorbis && tar xzf libvorbis.tar.gz && cd libvorbis &&
+    ./configure --prefix=$CONTRIB --with-ogg=$CONTRIB --disable-shared &&
+    make && make install &&
+    strip -S $CONTRIB/lib/libvorbis.a
+}
+Wget      $(SUBDIR)/libvorbis.tar.gz : $(SUBDIR)/version_libvorbis.txt ;
+LibVorbis $(SUBDIR)/lib/libvorbis.a  : $(SUBDIR)/libvorbis.tar.gz ;
+
+rule LibVorbisEnc
+{
+    Depends $(<) : $(>) ;
+    Depends lib  : $(<) ;
+}
+actions LibVorbisEnc
+{
+    strip -S $(<)
+}
+LibVorbisEnc $(SUBDIR)/lib/libvorbisenc.a : $(SUBDIR)/lib/libvorbis.a ;
+
+# libx264
+rule LibX264
+{
+    Depends $(<) : $(>) ;
+    Depends lib  : $(<) ;
+}
+actions LibX264
+{
+    cd `dirname $(>)` && CONTRIB=`pwd` &&
+    rm -rf x264 && tar xzf x264.tar.gz && cd x264 &&
+    ./configure --prefix=$CONTRIB --enable-pthread && make &&
+    make install &&
+    strip -S $CONTRIB/lib/libx264.a
+}
+Wget    $(SUBDIR)/x264.tar.gz   : $(SUBDIR)/version_x264.txt ;
+LibX264 $(SUBDIR)/lib/libx264.a : $(SUBDIR)/x264.tar.gz ;
+
+# libxvidcore
+rule LibXvidCore
+{
+    Depends $(<) : $(>) ;
+    Depends lib  : $(<) ;
+}
+actions LibXvidCore
+{
+    cd `dirname $(>)` && CONTRIB=`pwd` &&
+    rm -rf xvidcore && tar xzf xvidcore.tar.gz &&
+    cd xvidcore/build/generic/ && ./configure && make libxvidcore.a &&
+    cp ./=build/libxvidcore.a $CONTRIB/lib/ &&
+    cp ../../src/xvid.h $CONTRIB/include/ &&
+    strip -S $CONTRIB/lib/libxvidcore.a
+}
+Wget        $(SUBDIR)/xvidcore.tar.gz   : $(SUBDIR)/version_xvidcore.txt ;
+LibXvidCore $(SUBDIR)/lib/libxvidcore.a : $(SUBDIR)/xvidcore.tar.gz ;
diff --git a/contrib/version_a52dec.txt b/contrib/version_a52dec.txt
new file mode 100644 (file)
index 0000000..86617fd
--- /dev/null
@@ -0,0 +1 @@
+http://download.m0k.org/handbrake/contrib/a52dec-0.7.4.tar.gz
diff --git a/contrib/version_faac.txt b/contrib/version_faac.txt
new file mode 100644 (file)
index 0000000..e346666
--- /dev/null
@@ -0,0 +1 @@
+http://download.m0k.org/handbrake/contrib/faac-1.24.tar.gz
diff --git a/contrib/version_ffmpeg.txt b/contrib/version_ffmpeg.txt
new file mode 100644 (file)
index 0000000..b8a5c6f
--- /dev/null
@@ -0,0 +1 @@
+http://download.m0k.org/handbrake/contrib/ffmpeg-20051007.tar.gz
diff --git a/contrib/version_lame.txt b/contrib/version_lame.txt
new file mode 100644 (file)
index 0000000..b4bb63c
--- /dev/null
@@ -0,0 +1 @@
+http://download.m0k.org/handbrake/contrib/lame-3.96.1.tar.gz
diff --git a/contrib/version_libdvdcss.txt b/contrib/version_libdvdcss.txt
new file mode 100644 (file)
index 0000000..81d1ef1
--- /dev/null
@@ -0,0 +1 @@
+http://download.m0k.org/handbrake/contrib/libdvdcss-1.2.9.tar.gz
diff --git a/contrib/version_libdvdread.txt b/contrib/version_libdvdread.txt
new file mode 100644 (file)
index 0000000..b7be38f
--- /dev/null
@@ -0,0 +1 @@
+http://download.m0k.org/handbrake/contrib/libdvdread-20050928.tar.gz
diff --git a/contrib/version_libogg.txt b/contrib/version_libogg.txt
new file mode 100644 (file)
index 0000000..57daaf7
--- /dev/null
@@ -0,0 +1 @@
+http://download.m0k.org/handbrake/contrib/libogg-1.1.2.tar.gz
diff --git a/contrib/version_libsamplerate.txt b/contrib/version_libsamplerate.txt
new file mode 100644 (file)
index 0000000..a0f5b38
--- /dev/null
@@ -0,0 +1 @@
+http://download.m0k.org/handbrake/contrib/libsamplerate-0.1.2.tar.gz
diff --git a/contrib/version_libvorbis.txt b/contrib/version_libvorbis.txt
new file mode 100644 (file)
index 0000000..db3f67c
--- /dev/null
@@ -0,0 +1 @@
+http://download.m0k.org/handbrake/contrib/libvorbis-1.1.1.tar.gz
diff --git a/contrib/version_mpeg2dec.txt b/contrib/version_mpeg2dec.txt
new file mode 100644 (file)
index 0000000..87a73c9
--- /dev/null
@@ -0,0 +1 @@
+http://download.m0k.org/handbrake/contrib/mpeg2dec-20051019.tar.gz
diff --git a/contrib/version_mpeg4ip.txt b/contrib/version_mpeg4ip.txt
new file mode 100644 (file)
index 0000000..f60e597
--- /dev/null
@@ -0,0 +1 @@
+http://download.m0k.org/handbrake/contrib/mpeg4ip-1.3.tar.gz
diff --git a/contrib/version_x264.txt b/contrib/version_x264.txt
new file mode 100644 (file)
index 0000000..560f081
--- /dev/null
@@ -0,0 +1 @@
+http://download.m0k.org/handbrake/contrib/x264-r305.tar.gz
diff --git a/contrib/version_xvidcore.txt b/contrib/version_xvidcore.txt
new file mode 100644 (file)
index 0000000..573cd3c
--- /dev/null
@@ -0,0 +1 @@
+http://download.m0k.org/handbrake/contrib/xvidcore-1.1.0-beta2.tar.gz
diff --git a/core/Ac3Dec.c b/core/Ac3Dec.c
deleted file mode 100644 (file)
index ef80558..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-/* $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/>.
-   It may be used under the terms of the GNU General Public License. */
-
-#include "HBInternal.h"
-
-/* liba52 */
-#include "a52dec/a52.h"
-
-struct HBWork
-{
-    HB_WORK_COMMON_MEMBERS
-
-    HBHandle    * handle;
-    HBAudio     * audio;
-
-    /* liba52 stuff */
-    a52_state_t * state;
-    int           inFlags;
-    int           outFlags;
-    float         sampleLevel;
-
-    /* Buffers */
-    uint8_t       ac3Frame[3840]; /* Max size of a A52 frame */
-    int           hasSync;
-    int           nextFrameSize;
-};
-
-/* Local prototypes */
-static int Ac3DecWork( HBWork * );
-
-HBWork * HBAc3DecInit( HBHandle * handle, HBAudio * audio )
-{
-    HBWork * w;
-    if( !( w = calloc( sizeof( HBWork ), 1 ) ) )
-    {
-        HBLog( "HBAc3DecInit: malloc() failed, gonna crash" );
-        return NULL;
-    }
-
-    w->name = strdup( "Ac3Dec" );
-    w->work = Ac3DecWork;
-
-    w->handle = handle;
-    w->audio  = audio;
-
-    /* Init liba52 */
-    w->state = a52_init( 0 );
-
-    /* Let it do the downmixing */
-    w->outFlags = A52_STEREO;
-
-    /* 16 bits samples */
-    w->sampleLevel = 32768.0;
-
-    return w;
-}
-
-void HBAc3DecClose( HBWork ** _w )
-{
-    HBWork * w = *_w;
-
-    a52_free( w->state );
-    free( w->name );
-    free( w );
-
-    *_w = NULL;
-}
-
-static int Ac3DecWork( HBWork * w )
-{
-    HBAudio  * audio = w->audio;
-
-    float      position;
-
-    if( HBFifoIsHalfFull( audio->rawFifo ) )
-    {
-        return 0;
-    }
-
-    /* Get a frame header (7 bytes) */
-    if( !w->hasSync )
-    {
-        if( !HBFifoGetBytes( audio->inFifo, w->ac3Frame, 7,
-                             &position ) )
-        {
-            return 0;
-        }
-
-        /* Check the header */
-        w->nextFrameSize = a52_syncinfo( w->ac3Frame, &w->inFlags,
-                                         &audio->inSampleRate,
-                                         &audio->inBitrate );
-
-        if( !w->nextFrameSize )
-        {
-            HBLog( "HBAc3Dec: a52_syncinfo() failed" );
-            HBErrorOccured( w->handle, HB_ERROR_A52_SYNC );
-            return 0;
-        }
-
-        w->hasSync = 1;
-    }
-
-    /* Get the whole frame */
-    if( w->hasSync )
-    {
-        sample_t * samples;
-        HBBuffer * rawBuffer;
-        int        i;
-
-        if( !HBFifoGetBytes( audio->inFifo, w->ac3Frame + 7,
-                             w->nextFrameSize - 7, &position ) )
-        {
-            return 0;
-        }
-
-        w->hasSync = 0;
-
-        /* Feed liba52 */
-        a52_frame( w->state, w->ac3Frame, &w->outFlags,
-                   &w->sampleLevel, 0 );
-
-        /* 6 blocks per frame, 256 samples per block, 2 channels */
-        rawBuffer           = HBBufferInit( 3072 * sizeof( float ) );
-        rawBuffer->position = position;
-
-        for( i = 0; i < 6; i++ )
-        {
-            int j;
-
-            /* Decode a block */
-            a52_block( w->state );
-
-            /* Get a pointer to the float samples */
-            samples = a52_samples( w->state );
-
-            /* Interleave samples */
-            for( j = 0; j < 256; j++ )
-            {
-                rawBuffer->dataf[512*i+2*j]   = samples[j];
-                rawBuffer->dataf[512*i+2*j+1] = samples[256+j];
-            }
-        }
-
-        /* Send decoded data to the resampler */
-        if( !HBFifoPush( audio->rawFifo, &rawBuffer ) )
-        {
-            HBLog( "HBAc3Dec: HBFifoPush failed" );
-        }
-    }
-
-    return 1;
-}
-
diff --git a/core/AviMux.c b/core/AviMux.c
deleted file mode 100644 (file)
index c0209dd..0000000
+++ /dev/null
@@ -1,559 +0,0 @@
-/* $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/>.
-   It may be used under the terms of the GNU General Public License. */
-
-#include "HBInternal.h"
-
-#define AVIF_HASINDEX  0x10
-#define AVIIF_KEYFRAME 0x10
-#define FOURCC(a)      ((a[3]<<24)|(a[2]<<16)|(a[1]<<8)|a[0])
-
-/* Structures definitions */
-typedef struct __attribute__((__packed__))
-{
-    uint32_t FourCC;
-    uint32_t BytesCount;
-    uint32_t MicroSecPerFrame;
-    uint32_t MaxBytesPerSec;
-    uint32_t PaddingGranularity;
-    uint32_t Flags;
-    uint32_t TotalFrames;
-    uint32_t InitialFrames;
-    uint32_t Streams;
-    uint32_t SuggestedBufferSize;
-    uint32_t Width;
-    uint32_t Height;
-    uint32_t Reserved[4];
-
-} HBAviMainHeader;
-
-typedef struct __attribute__((__packed__))
-{
-    uint32_t FourCC;
-    uint32_t BytesCount;
-    uint32_t Type;
-    uint32_t Handler;
-    uint32_t Flags;
-    uint16_t Priority;
-    uint16_t Language;
-    uint32_t InitialFrames;
-    uint32_t Scale;
-    uint32_t Rate;
-    uint32_t Start;
-    uint32_t Length;
-    uint32_t SuggestedBufferSize;
-    uint32_t Quality;
-    uint32_t SampleSize;
-    int16_t  Left;
-    int16_t  Top;
-    int16_t  Right;
-    int16_t  Bottom;
-
-} HBAviStreamHeader;
-
-typedef struct __attribute__((__packed__))
-{
-    uint32_t FourCC;
-    uint32_t BytesCount;
-    uint32_t Size;
-    uint32_t Width;
-    uint32_t Height;
-    uint16_t Planes;
-    uint16_t BitCount;
-    uint32_t Compression;
-    uint32_t SizeImage;
-    uint32_t XPelsPerMeter;
-    uint32_t YPelsPerMeter;
-    uint32_t ClrUsed;
-    uint32_t ClrImportant;
-
-} HBBitmapInfo;
-
-typedef struct __attribute__((__packed__))
-{
-    uint32_t FourCC;
-    uint32_t BytesCount;
-    uint16_t FormatTag;
-    uint16_t Channels;
-    uint32_t SamplesPerSec;
-    uint32_t AvgBytesPerSec;
-    uint16_t BlockAlign;
-    uint16_t BitsPerSample;
-    uint16_t Size;
-
-    /* mp3 specific */
-    uint16_t Id;
-    uint32_t Flags;
-    uint16_t BlockSize;
-    uint16_t FramesPerBlock;
-    uint16_t CodecDelay;
-
-} HBWaveFormatEx;
-
-struct HBMux
-{
-    HB_MUX_COMMON_MEMBERS
-
-    HBHandle      * handle;
-    HBTitle       * title;
-
-    /* Data size in bytes, not including headers */
-    unsigned        size;
-
-    FILE          * file;
-    HBBuffer      * index;
-};
-
-typedef struct
-{
-    HBAviMainHeader   mainHeader;
-    HBAviStreamHeader videoHeader;
-    HBBitmapInfo      videoFormat;
-
-} AviVideoMuxData;
-
-typedef struct
-{
-    uint32_t          fourCC;
-    HBAviStreamHeader audioHeader;
-    HBWaveFormatEx    audioFormat;
-
-} AviAudioMuxData;
-
-/* 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 )
-{
-    HBMux   * m;
-    HBAudio * audio;
-    int i;
-
-    if( !( m = calloc( sizeof( HBMux ), 1 ) ) )
-    {
-        HBLog( "HBAviMux: malloc() failed, gonna crash" );
-        return NULL;
-    }
-    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 = (HBAudio *) HBListItemAt( title->ripAudioList, i );
-        audio->muxData = calloc( sizeof( AviAudioMuxData ), 1 );
-    }
-
-    return m;
-}
-
-void HBAviMuxClose( 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 );
-    }
-
-    HBBufferClose( &m->index );
-
-    free( m );
-
-    *_m = NULL;
-}
-
-#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        = m->title;
-    int               audioCount   = HBListCount( title->ripAudioList );
-    AviVideoMuxData * videoMuxData = (AviVideoMuxData *) title->muxData;
-    AviAudioMuxData * audioMuxData;
-    HBAudio         * audio;
-    int               hdrlBytes;
-    int               i;
-
-    /* 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;
-    }
-
-    /* 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 */
-    vh.FourCC     = FOURCC( "strh" );
-    vh.BytesCount = sizeof( HBAviStreamHeader ) - 8;
-    vh.Type       = FOURCC( "vids" );
-
-    if( title->codec == HB_CODEC_FFMPEG )
-        vh.Handler = FOURCC( "divx" );
-    else if( title->codec == HB_CODEC_XVID )
-        vh.Handler = FOURCC( "xvid" );
-    else if( title->codec == HB_CODEC_X264 )
-        vh.Handler = FOURCC( "h264" );
-
-    vh.Scale      = title->rateBase;
-    vh.Rate       = title->rate;
-
-    /* Video stream format */
-    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 )
-        vf.Compression = FOURCC( "DX50" );
-    else if( title->codec == HB_CODEC_XVID )
-        vf.Compression = FOURCC( "XVID" );
-    else if( title->codec == HB_CODEC_X264 )
-        vf.Compression = FOURCC( "H264" );
-
-    for( i = 0; i < audioCount; i++ )
-    {
-        audio        = HBListItemAt( title->ripAudioList, i );
-        audioMuxData = (AviAudioMuxData *) audio->muxData;
-
-        /* Audio stream header */
-        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 */
-        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 ) *
-        ( 12 + sizeof( HBAviStreamHeader ) ) + sizeof( HBBitmapInfo ) +
-        audioCount * sizeof( HBWaveFormatEx );
-
-    /* Here we really start to write into the file */
-
-    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 );
-        audioMuxData->fourCC = FOURCC( fourCC );
-
-        WriteInt32( m->file, FOURCC( "LIST" ) );
-        WriteInt32( m->file, 4 + sizeof( HBAviStreamHeader ) +
-                          sizeof( HBWaveFormatEx ) );
-        WriteInt32( m->file, FOURCC( "strl" ) );
-        WriteStreamHeader( m->file, &ah );
-        WriteHBWaveFormatEx( m->file, &af );
-    }
-
-    WriteInt32( m->file, FOURCC( "JUNK" ) );
-    WriteInt32( m->file, 2008 - hdrlBytes );
-    for( i = 0; i < 2008 - hdrlBytes; i++ )
-    {
-        WriteInt8( m->file, 0 );
-    }
-    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( HBMux * m, HBBuffer * buffer,
-                      uint32_t fourCC, HBAviStreamHeader * header )
-{
-    HBTitle * title = m->title;
-    AviVideoMuxData * videoMuxData = (AviVideoMuxData *) title->muxData;
-    AviAudioMuxData * audioMuxData;
-
-    HBAudio * audio;
-    int i;
-
-    /* Update index */
-    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( 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( m->file, 0 );
-    }
-
-    /* Update headers */
-    m->size += 8 + EVEN( buffer->size );
-    header->Length++;
-
-    /* RIFF size */
-    fseek( m->file, 4, SEEK_SET );
-    WriteInt32( m->file, 2040 + m->size );
-
-    /* HBAviStreamHeader's lengths */
-    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 );
-        audioMuxData = (AviAudioMuxData *) audio->muxData;
-        fseek( m->file, 268 + i * 114, SEEK_SET );
-        WriteInt32( m->file, audioMuxData->audioHeader.Length );
-    }
-
-    /* movi size */
-    fseek( m->file, 2040, SEEK_SET );
-    WriteInt32( m->file, 4 + m->size );
-}
-
-static void AddIndex( HBMux * m )
-{
-    HBTitle * title = m->title;
-    AviVideoMuxData * videoMuxData = (AviVideoMuxData *) title->muxData;
-
-    fseek( m->file, 0, SEEK_END );
-
-    WriteInt32( m->file, FOURCC( "idx1" ) );
-    WriteInt32( m->file, m->index->size );
-    WriteBuffer( m->file, m->index );
-
-    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 )
-{
-    fputc( val, file );
-}
-
-static void WriteInt16( FILE * file, uint16_t val )
-{
-    fputc( val & 0xFF, file );
-    fputc( val >> 8, file );
-}
-
-static void WriteInt32( FILE * file, uint32_t val )
-{
-    fputc( val & 0xFF, file );
-    fputc( ( val >> 8 ) & 0xFF, file );
-    fputc( ( val >> 16 ) & 0xFF, file );
-    fputc( val >> 24, file );
-}
-
-static void WriteBuffer( FILE * file, HBBuffer * buffer )
-{
-    fwrite( buffer->data, buffer->size, 1, file );
-}
-
-static void WriteHBBitmapInfo( FILE * file, HBBitmapInfo * bitmapInfo )
-{
-    WriteInt32( file, bitmapInfo->FourCC );
-    WriteInt32( file, bitmapInfo->BytesCount );
-    WriteInt32( file, bitmapInfo->Size );
-    WriteInt32( file, bitmapInfo->Width );
-    WriteInt32( file, bitmapInfo->Height );
-    WriteInt16( file, bitmapInfo->Planes );
-    WriteInt16( file, bitmapInfo->BitCount );
-    WriteInt32( file, bitmapInfo->Compression );
-    WriteInt32( file, bitmapInfo->SizeImage );
-    WriteInt32( file, bitmapInfo->XPelsPerMeter );
-    WriteInt32( file, bitmapInfo->YPelsPerMeter );
-    WriteInt32( file, bitmapInfo->ClrUsed );
-    WriteInt32( file, bitmapInfo->ClrImportant );
-}
-
-static void WriteHBWaveFormatEx( FILE * file, HBWaveFormatEx * waveFormatEx )
-{
-    WriteInt32( file, waveFormatEx->FourCC );
-    WriteInt32( file, waveFormatEx->BytesCount );
-    WriteInt16( file, waveFormatEx->FormatTag );
-    WriteInt16( file, waveFormatEx->Channels );
-    WriteInt32( file, waveFormatEx->SamplesPerSec );
-    WriteInt32( file, waveFormatEx->AvgBytesPerSec );
-    WriteInt16( file, waveFormatEx->BlockAlign );
-    WriteInt16( file, waveFormatEx->BitsPerSample );
-    WriteInt16( file, waveFormatEx->Size );
-    WriteInt16( file, waveFormatEx->Id );
-    WriteInt32( file, waveFormatEx->Flags );
-    WriteInt16( file, waveFormatEx->BlockSize );
-    WriteInt16( file, waveFormatEx->FramesPerBlock );
-    WriteInt16( file, waveFormatEx->CodecDelay );
-}
-
-static void WriteMainHeader( FILE * file, HBAviMainHeader * mainHeader )
-{
-    WriteInt32( file, mainHeader->FourCC );
-    WriteInt32( file, mainHeader->BytesCount );
-    WriteInt32( file, mainHeader->MicroSecPerFrame );
-    WriteInt32( file, mainHeader->MaxBytesPerSec );
-    WriteInt32( file, mainHeader->PaddingGranularity );
-    WriteInt32( file, mainHeader->Flags );
-    WriteInt32( file, mainHeader->TotalFrames );
-    WriteInt32( file, mainHeader->InitialFrames );
-    WriteInt32( file, mainHeader->Streams );
-    WriteInt32( file, mainHeader->SuggestedBufferSize );
-    WriteInt32( file, mainHeader->Width );
-    WriteInt32( file, mainHeader->Height );
-    WriteInt32( file, mainHeader->Reserved[0] );
-    WriteInt32( file, mainHeader->Reserved[1] );
-    WriteInt32( file, mainHeader->Reserved[2] );
-    WriteInt32( file, mainHeader->Reserved[3] );
-}
-
-static void WriteStreamHeader( FILE * file, HBAviStreamHeader * streamHeader )
-{
-    WriteInt32( file, streamHeader->FourCC );
-    WriteInt32( file, streamHeader->BytesCount );
-    WriteInt32( file, streamHeader->Type );
-    WriteInt32( file, streamHeader->Handler );
-    WriteInt32( file, streamHeader->Flags );
-    WriteInt16( file, streamHeader->Priority );
-    WriteInt16( file, streamHeader->Language );
-    WriteInt32( file, streamHeader->InitialFrames );
-    WriteInt32( file, streamHeader->Scale );
-    WriteInt32( file, streamHeader->Rate );
-    WriteInt32( file, streamHeader->Start );
-    WriteInt32( file, streamHeader->Length );
-    WriteInt32( file, streamHeader->SuggestedBufferSize );
-    WriteInt32( file, streamHeader->Quality );
-    WriteInt32( file, streamHeader->SampleSize );
-    WriteInt16( file, streamHeader->Left );
-    WriteInt16( file, streamHeader->Top );
-    WriteInt16( file, streamHeader->Right );
-    WriteInt16( file, streamHeader->Bottom );
-}
-
-static void IndexAddInt32( HBBuffer * b, uint32_t val )
-{
-    if( b->size + 16 > b->alloc )
-    {
-        HBLog( "HBAviMux: reallocing index (%d MB)",
-               1 + b->alloc / 1024 / 1024 );
-        HBBufferReAlloc( b, b->alloc + 1024 * 1024 );
-    }
-
-    b->data[b->size++] = val & 0xFF;
-    b->data[b->size++] = ( val >> 8 ) & 0xFF;
-    b->data[b->size++] = ( val >> 16 ) & 0xFF;
-    b->data[b->size++] = val >> 24;
-}
-
diff --git a/core/DVDRead.c b/core/DVDRead.c
deleted file mode 100644 (file)
index 4c36f39..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-/* $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/>.
-   It may be used under the terms of the GNU General Public License. */
-
-#include "HBInternal.h"
-
-#include "dvdread/dvd_reader.h"
-
-/* Local prototypes */
-static void DVDReadThread( void * );
-static int  DoPass( HBDVDRead * );
-static int  Demux( HBDVDRead * );
-static int  Push( HBDVDRead *, HBFifo * fifo, HBBuffer ** buffer );
-
-struct HBDVDRead
-{
-    HBHandle     * handle;
-
-    dvd_reader_t * reader;
-    dvd_file_t   * file;
-    HBTitle      * title;
-    int            beginPosition;
-    int            endPosition;
-    int            pass;
-    HBBuffer     * psBuffer;
-    HBList       * esBufferList;
-
-    volatile int   die;
-    HBThread     * thread;
-};
-
-HBDVDRead * HBDVDReadInit( HBHandle * handle, HBTitle * title )
-{
-    HBDVDRead * d;
-    if( !( d = malloc( sizeof( HBDVDRead ) ) ) )
-    {
-        HBLog( "HBDVDReadInit: malloc() failed, gonna crash" );
-        return NULL;
-    }
-
-    /* Initializations */
-    d->handle        = handle;
-    d->reader        = NULL;
-    d->file          = NULL;
-    d->title         = title;
-    d->beginPosition = 0;
-    d->endPosition   = 0;
-    d->pass          = 0;
-    d->psBuffer      = NULL;
-    d->esBufferList  = HBListInit();
-
-    /* Launch the thread */
-    d->die    = 0;
-    d->thread = HBThreadInit( "dvd reader", DVDReadThread, d,
-                              HB_NORMAL_PRIORITY );
-
-    return d;
-}
-
-void HBDVDReadClose( HBDVDRead ** _d )
-{
-    HBBuffer * buffer;
-
-    HBDVDRead * d = *_d;
-
-    /* Stop the thread */
-    d->die = 1;
-    HBThreadClose( &d->thread );
-
-    /* Clean up */
-    while( ( buffer = (HBBuffer*) HBListItemAt( d->esBufferList, 0 ) ) )
-    {
-        HBListRemove( d->esBufferList, buffer );
-        HBBufferClose( &buffer );
-    }
-    HBListClose( &d->esBufferList ) ;
-    free( d );
-
-    (*_d) = NULL;
-}
-
-static void DVDReadThread( void * _d )
-{
-    HBDVDRead * d     = (HBDVDRead*) _d;
-    HBTitle   * title = d->title;
-
-    int i;
-
-    /* Open the device */
-    d->reader = DVDOpen( title->device );
-    if( !d->reader )
-    {
-        HBLog( "HBDVDRead: DVDOpen() failed" );
-        HBErrorOccured( d->handle, HB_ERROR_DVD_OPEN );
-        return;
-    }
-
-    /* Open the title */
-    d->file = DVDOpenFile( d->reader, title->vts_id, DVD_READ_TITLE_VOBS );
-
-    /* Do the job */
-    for( i = 0; i < ( title->twoPass ? 2 : 1 ); i++ )
-    {
-        HBLog( "HBDVDRead: starting pass %d of %d", i + 1,
-               title->twoPass ? 2 : 1 );
-
-        d->pass = title->twoPass ? ( i + 1 ) : 0;
-
-        if( !DoPass( d ) )
-        {
-            break;
-        }
-    }
-
-    if( !d->die )
-    {
-        HBLog( "HBDVDRead: done" );
-        HBDone( d->handle );
-    }
-
-    /* Clean up */
-    DVDCloseFile( d->file );
-    DVDClose( d->reader );
-}
-
-
-static int DoPass( HBDVDRead * d )
-{
-    int i;
-
-    for( i = d->title->startBlock; i < d->title->endBlock; i++ )
-    {
-        d->psBuffer = HBBufferInit( DVD_VIDEO_LB_LEN );
-        d->psBuffer->position = (float) ( i - d->title->startBlock ) /
-            ( d->title->endBlock - d->title->startBlock );
-
-        if( d->pass )
-        {
-            d->psBuffer->position /= 2;
-
-            if( d->pass == 2 )
-            {
-                d->psBuffer->position += 0.5;
-            }
-        }
-        d->psBuffer->pass = d->pass;
-
-        if( DVDReadBlocks( d->file, i, 1, d->psBuffer->data ) < 0 )
-        {
-            HBLog( "HBDVDRead: DVDReadBlocks() failed" );
-            HBErrorOccured( d->handle, HB_ERROR_DVD_READ );
-            HBBufferClose( &d->psBuffer );
-            return 0;
-        }
-
-        if( !Demux( d ) )
-        {
-            return 0;
-        }
-    }
-
-    return 1;
-}
-
-static int Demux( HBDVDRead * d )
-{
-    HBTitle * title = d->title;
-
-    HBAudio  * audio;
-    HBBuffer * esBuffer;
-    int i;
-
-    /* Demux */
-    HBPStoES( &d->psBuffer, d->esBufferList );
-
-    /* Push buffers */
-    while( ( esBuffer = (HBBuffer*) HBListItemAt( d->esBufferList, 0 ) ) )
-    {
-        /* First pass: trash audio buffers */
-        if( d->pass == 1 && esBuffer->streamId != 0xE0 )
-        {
-            HBListRemove( d->esBufferList, esBuffer );
-            HBBufferClose( &esBuffer );
-            continue;
-        }
-
-        /* Video */
-        if( esBuffer->streamId == 0xE0 )
-        {
-            if( title->start < 0 )
-            {
-                title->start = esBuffer->pts / 90;
-                HBLog( "HBDVDRead: got first 0xE0 packet (%d)",
-                       title->start );
-            }
-
-            HBListRemove( d->esBufferList, esBuffer );
-            if( !Push( d, title->inFifo, &esBuffer ) )
-            {
-                return 0;
-            }
-            continue;
-        }
-
-        /* Audio or whatever */
-        for( i = 0; i < HBListCount( title->ripAudioList ); i++ )
-        {
-            audio = (HBAudio*) HBListItemAt( title->ripAudioList, i );
-
-            if( esBuffer->streamId != audio->id )
-            {
-                continue;
-            }
-
-            if( audio->start < 0 )
-            {
-                audio->start = esBuffer->pts / 90;
-                HBLog( "HBDVDRead: got first 0x%x packet (%d)",
-                       audio->id, audio->start );
-
-                audio->delay = audio->start - title->start;
-            }
-
-            HBListRemove( d->esBufferList, esBuffer );
-            if( !Push( d, audio->inFifo, &esBuffer ) )
-            {
-                return 0;
-            }
-            break;
-        }
-
-        if( esBuffer )
-        {
-            HBListRemove( d->esBufferList, esBuffer );
-            HBBufferClose( &esBuffer );
-        }
-    }
-
-    return 1;
-}
-
-static int Push( HBDVDRead * d, HBFifo * fifo, HBBuffer ** buffer )
-{
-    while( !d->die )
-    {
-        if( HBFifoPush( fifo, buffer ) )
-        {
-            return 1;
-        }
-        HBSnooze( 5000 );
-    }
-
-    return 0;
-}
-
diff --git a/core/FaacEnc.c b/core/FaacEnc.c
deleted file mode 100644 (file)
index 689e6e1..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/* $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/>.
-   It may be used under the terms of the GNU General Public License. */
-
-#include "HBInternal.h"
-
-/* libfaac */
-#include "faac.h"
-
-struct HBWork
-{
-    HB_WORK_COMMON_MEMBERS
-
-    HBHandle          * handle;
-    HBAudio           * audio;
-
-    faacEncHandle     * faac;
-    unsigned long       inputSamples;
-    unsigned long       maxOutputBytes;
-    float             * inputBuffer;
-};
-
-/* Local prototypes */
-static int FaacEncWork( HBWork * );
-
-HBWork * HBFaacEncInit( HBHandle * handle, HBAudio * audio )
-{
-    HBWork * w;
-    if( !( w = calloc( sizeof( HBWork ), 1 ) ) )
-    {
-        HBLog( "HBFaacEncInit: malloc() failed, gonna crash" );
-        return NULL;
-    }
-
-    w->name   = strdup( "FaacEnc" );
-    w->work   = FaacEncWork;
-
-    w->handle = handle;
-    w->audio  = audio;
-
-    return w;
-}
-
-void HBFaacEncClose( HBWork ** _w )
-{
-    HBWork * w = *_w;
-
-    if( w->faac )
-    {
-        faacEncClose( w->faac );
-        free( w->inputBuffer );
-    }
-
-    free( w->name );
-    free( w );
-
-    *_w = NULL;
-}
-
-static int FaacEncWork( HBWork * w )
-{
-    HBAudio   * audio = w->audio;
-
-    HBBuffer * aacBuffer;
-    float      position;
-
-    if( !w->faac )
-    {
-        faacEncConfigurationPtr config;
-
-        if( !HBFifoSize( audio->resampleFifo ) )
-        {
-            return 0;
-        }
-
-        HBLog( "HBFaacEnc: opening libfaac (%x)", audio->id );
-
-        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 * 500; /* per channel */
-        config->bandWidth     = 0;
-        config->outputFormat  = 0;
-        config->inputFormat   = FAAC_INPUT_FLOAT;
-        if( !faacEncSetConfiguration( w->faac, config ) )
-        {
-            HBLog( "HBFaacEnc: faacEncSetConfiguration failed" );
-        }
-        if( faacEncGetDecoderSpecificInfo( w->faac, &audio->esConfig,
-                    &audio->esConfigLength ) < 0 )
-        {
-            HBLog( "HBFaacEnc: faacEncGetDecoderSpecificInfo failed" );
-        }
-    }
-
-    if( HBFifoIsHalfFull( audio->outFifo ) )
-    {
-        return 0;
-    }
-
-    if( !HBFifoGetBytes( audio->resampleFifo,
-                         (uint8_t *) w->inputBuffer,
-                         w->inputSamples * sizeof( float ),
-                         &position ) )
-    {
-        return 0;
-    }
-
-    aacBuffer = HBBufferInit( w->maxOutputBytes );
-    aacBuffer->position = position;
-    aacBuffer->size = faacEncEncode( w->faac, (int32_t*)w->inputBuffer,
-        w->inputSamples, aacBuffer->data, w->maxOutputBytes );
-
-    if( !aacBuffer->size )
-    {
-        HBBufferClose( &aacBuffer );
-    }
-    else if( aacBuffer->size < 0 )
-    {
-        HBLog( "HBFaacEnc: faacEncEncode() failed" );
-    }
-    else
-    {
-        if( !HBFifoPush( audio->outFifo, &aacBuffer ) )
-        {
-            HBLog( "HBFaacEnc: HBFifoPush failed" );
-        }
-    }
-
-    return 1;
-}
-
diff --git a/core/FfmpegEnc.c b/core/FfmpegEnc.c
deleted file mode 100644 (file)
index ae474d0..0000000
+++ /dev/null
@@ -1,255 +0,0 @@
-/* $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/>.
-   It may be used under the terms of the GNU General Public License. */
-
-#include "HBInternal.h"
-
-/* libavcodec */
-#include "ffmpeg/avcodec.h"
-
-struct HBWork
-{
-    HB_WORK_COMMON_MEMBERS
-
-    HBHandle       * handle;
-    HBTitle        * title;
-
-    int              pass;
-    AVCodecContext * context;
-    FILE           * file;
-};
-
-/* Local prototypes */
-static int  FfmpegEncWork( HBWork * );
-static int  InitAvcodec( HBWork * );
-static void CloseAvcodec( HBWork * );
-
-HBWork * HBFfmpegEncInit( HBHandle * handle, HBTitle * title )
-{
-    HBWork * w;
-    if( !( w = calloc( sizeof( HBWork ), 1 ) ) )
-    {
-        HBLog( "HBFfmpegEncInit: malloc() failed, gonna crash" );
-        return NULL;
-    }
-
-    w->name = strdup( "FfmpegEnc" );
-    w->work = FfmpegEncWork;
-
-    w->handle = handle;
-    w->title  = title;
-    w->pass   = 42;
-
-    return w;
-}
-
-void HBFfmpegEncClose( HBWork ** _w )
-{
-    HBWork * w = *_w;
-
-    if( w->context )
-    {
-        CloseAvcodec( w );
-    }
-
-    free( w->name );
-    free( w );
-
-    *_w = NULL;
-}
-
-static int FfmpegEncWork( HBWork * w )
-{
-    HBTitle  * title = w->title;
-
-    HBBuffer * scaledBuffer;
-    HBBuffer * mpeg4Buffer;
-    AVFrame  * frame;
-
-    if( HBFifoIsHalfFull( title->outFifo ) )
-    {
-        return 0;
-    }
-
-    if( !( scaledBuffer = HBFifoPop( title->scaledFifo ) ) )
-    {
-        return 0;
-    }
-
-    /* Init or re-init if needed */
-    if( scaledBuffer->pass != w->pass )
-    {
-        if( w->context )
-        {
-            CloseAvcodec( w );
-        }
-
-        w->pass = scaledBuffer->pass;
-
-        if( !InitAvcodec( w ) )
-        {
-            HBErrorOccured( w->handle, HB_ERROR_MPEG4_INIT );
-            return 0;
-        }
-    }
-
-    frame              = avcodec_alloc_frame();
-    frame->data[0]     = scaledBuffer->data;
-    frame->data[1]     = frame->data[0] + title->outWidth *
-                         title->outHeight;
-    frame->data[2]     = frame->data[1] + title->outWidth *
-                         title->outHeight / 4;
-    frame->linesize[0] = title->outWidth;
-    frame->linesize[1] = title->outWidth / 2;
-    frame->linesize[2] = title->outWidth / 2;
-
-    mpeg4Buffer = HBBufferInit( 3 * title->outWidth *
-                                title->outHeight / 2 );
-    mpeg4Buffer->position = scaledBuffer->position;
-    mpeg4Buffer->size     = avcodec_encode_video( w->context,
-            mpeg4Buffer->data, mpeg4Buffer->alloc, frame );
-    mpeg4Buffer->keyFrame = w->context->coded_frame->key_frame;
-
-    /* Inform the GUI about the current position */
-    HBPosition( w->handle, scaledBuffer->position );
-
-    if( w->pass == 1 )
-    {
-        if( w->context->stats_out )
-        {
-            fprintf( w->file, "%s", w->context->stats_out );
-        }
-        HBBufferClose( &mpeg4Buffer );
-    }
-    else
-    {
-        if( !HBFifoPush( title->outFifo, &mpeg4Buffer ) )
-        {
-            HBLog( "HBFfmpegEnc: HBFifoPush failed" );
-        }
-    }
-
-    HBBufferClose( &scaledBuffer );
-    free( frame );
-
-    return 1;
-}
-
-static int InitAvcodec( HBWork * w )
-{
-    AVCodec        * codec;
-    AVCodecContext * context;
-    HBTitle        * title = w->title;
-
-    HBLog( "HBFfmpegEnc: opening libavcodec (pass %d)", w->pass );
-
-    codec = avcodec_find_encoder( CODEC_ID_MPEG4 );
-    if( !codec )
-    {
-        HBLog( "HBFfmpegEnc: avcodec_find_encoder() failed" );
-        HBErrorOccured( w->handle, HB_ERROR_MPEG4_INIT );
-        return 0;
-    }
-
-    context                     = avcodec_alloc_context();
-    context->bit_rate           = 1024 * title->bitrate;
-    context->bit_rate_tolerance = 10 * context->bit_rate;
-    context->width              = title->outWidth;
-    context->height             = title->outHeight;
-    context->frame_rate         = title->rate;
-    context->frame_rate_base    = title->rateBase;
-    context->gop_size           = 10 * title->rate / title->rateBase;
-
-    if( title->mux == HB_MUX_MP4 && w->pass != 1 )
-    {
-        context->flags |= CODEC_FLAG_GLOBAL_HEADER;
-    }
-
-    if( w->pass )
-    {
-        char fileName[1024]; memset( fileName, 0, 1024 );
-#ifndef HB_CYGWIN
-        sprintf( fileName, "/tmp/HB.%d.ffmpeg.log",
-                 HBGetPid( w->handle ) );
-#else
-        sprintf( fileName, "C:\\HB.%d.ffmpeg.log",
-                 HBGetPid( w->handle ) );
-#endif
-
-        if( w->pass == 1 )
-        {
-            w->file = fopen( fileName, "wb" );
-            context->flags |= CODEC_FLAG_PASS1;
-        }
-        else
-        {
-            FILE * file;
-            int    size;
-            char * log;
-
-            file = fopen( fileName, "rb" );
-            fseek( file, 0, SEEK_END );
-            size = ftell( file );
-            fseek( file, 0, SEEK_SET );
-            if( !( log = malloc( size + 1 ) ) )
-            {
-                HBLog( "HBFfmpegEnc: malloc() failed, gonna crash" );
-            }
-            log[size] = '\0';
-            fread( log, size, 1, file );
-            fclose( file );
-
-            context->flags    |= CODEC_FLAG_PASS2;
-            context->stats_in  = log;
-        }
-    }
-
-#ifdef HB_NOMMX
-    context->dct_algo  = FF_DCT_INT;
-    context->idct_algo = FF_IDCT_INT;
-    context->dsp_mask  = 0x1F;
-#endif
-
-    if( avcodec_open( context, codec ) < 0 )
-    {
-        HBLog( "HBFfmpegEnc: avcodec_open() failed" );
-        return 0;
-    }
-
-    if( title->mux == HB_MUX_MP4 && w->pass != 1 )
-    {
-        /* UGLY */
-        title->esConfig = malloc( 15 );
-        title->esConfigLength = 15;
-        memcpy( title->esConfig, context->extradata + 15, 15 );
-    }
-
-    w->context = context;
-    return 1;
-}
-
-static void CloseAvcodec( HBWork * w )
-{
-    HBLog( "HBFfmpegEnc: closing libavcodec (pass %d)",
-           w->pass );
-
-    if( w->context->stats_in )
-    {
-        free( w->context->stats_in );
-    }
-    avcodec_close( w->context );
-    if( w->file )
-    {
-        fclose( w->file );
-        w->file = NULL;
-    }
-    if( w->title->esConfig )
-    {
-        free( w->title->esConfig );
-        w->title->esConfig       = NULL;
-        w->title->esConfigLength = 0;
-    }
-}
-
diff --git a/core/Fifo.c b/core/Fifo.c
deleted file mode 100644 (file)
index ae0c412..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-/* $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/>.
-   It may be used under the terms of the GNU General Public License. */
-
-#include "Fifo.h"
-#if defined( HB_BEOS ) || defined( HB_LINUX )
-#include <malloc.h>
-#endif
-
-HBBuffer * HBBufferInit( int size )
-{
-    HBBuffer * b;
-    if( !( b = calloc( sizeof( HBBuffer ), 1 ) ) )
-    {
-        HBLog( "HBBuffer: malloc() failed, gonna crash" );
-        return NULL;
-    }
-
-    b->alloc = size;
-    b->size  = size;
-
-#if defined( HB_BEOS ) || defined( HB_LINUX )
-    b->data = memalign( 16, size );
-#elif defined( HB_MACOSX )
-    /* OS X's malloc returns 16-bytes aligned memory */
-    b->data = malloc( size );
-#elif defined( HB_CYGWIN )
-    b->dataOrig  = malloc( size + 15 );
-    b->data      = b->dataOrig + 15;
-    b->data     -= (long) b->data & 15;
-#endif
-    b->dataf     = (float*) b->data;
-
-    if( !b->data )
-    {
-        HBLog( "HBBuffer: malloc() failed, gonna crash" );
-        free( b );
-        return NULL;
-    }
-
-    return b;
-}
-
-void HBBufferReAlloc( HBBuffer * b, int size )
-{
-    /* We don't care about alignment here, realloc is only used in the
-       AVI muxer anyway */
-#if defined( HB_BEOS ) || defined( HB_LINUX ) || defined( HB_MACOSX )
-    b->data = realloc( b->data, size );
-#elif defined( HB_CYGWIN )
-    int alignment = b->data - b->dataOrig;
-    b->dataOrig   = realloc( b->dataOrig, size + alignment );
-    b->data       = b->dataOrig + alignment;
-#endif
-    b->alloc = size;
-
-    if( !b->data )
-    {
-        HBLog( "HBBuffer: realloc() failed, gonna crash soon" );
-    }
-}
-
-void HBBufferClose( HBBuffer ** _b )
-{
-    HBBuffer * b = *_b;
-
-#if defined( HB_BEOS ) || defined( HB_LINUX ) || defined( HB_MACOSX )
-    free( b->data );
-#elif defined( HB_CYGWIN )
-    free( b->dataOrig );
-#endif
-    free( b );
-
-    *_b = NULL;
-}
-
-HBFifo * HBFifoInit( int capacity )
-{
-    HBFifo * f;
-    if( !( f = malloc( sizeof( HBFifo ) ) ) )
-    {
-        HBLog( "HBFifo: malloc() failed, gonna crash" );
-        return NULL;
-    }
-
-    f->die         = 0;
-    f->capacity    = capacity;
-    f->whereToPush = 0;
-    f->whereToPop  = 0;
-
-    if( !( f->buffers = malloc( ( capacity + 1 ) * sizeof( void* ) ) ) )
-    {
-        HBLog( "HBFifo: malloc() failed, gonna crash" );
-        free( f );
-        return NULL;
-    }
-
-    f->lock = HBLockInit();
-    f->cond = HBCondInit();
-
-    return f;
-}
-
-void HBFifoDie( HBFifo * f )
-{
-    HBLockLock( f->lock );
-    f->die = 1;
-    HBCondSignal( f->cond );
-    HBLockUnlock( f->lock );
-}
-
-void HBFifoClose( HBFifo ** _f )
-{
-    HBFifo * f = (*_f);
-
-    HBLog( "HBFifo: trashing %d buffer%s",
-           HBFifoSize( f ), ( HBFifoSize( f ) > 1 ) ? "s" : "" );
-
-    while( f->whereToPush != f->whereToPop )
-    {
-        HBBufferClose( &(f->buffers[f->whereToPop]) );
-        f->whereToPop++;
-        f->whereToPop %= ( f->capacity + 1 );
-    }
-
-    HBLockClose( &f->lock );
-    HBCondClose( &f->cond );
-    free( f->buffers );
-    free( f );
-
-    *_f = NULL;
-}
-
diff --git a/core/Fifo.h b/core/Fifo.h
deleted file mode 100644 (file)
index 26c4b55..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-/* $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/>.
-   It may be used under the terms of the GNU General Public License. */
-
-#ifndef HB_FIFO_H
-#define HB_FIFO_H
-
-#include "Utils.h"
-#include "Thread.h"
-
-struct HBBuffer
-{
-    /* Members used everywhere */
-    int       alloc;
-    int       size;
-    uint8_t * data;
-#if defined( HB_CYGWIN )
-    uint8_t * dataOrig;
-#endif
-    float   * dataf;
-    float     position;
-    int       pass;
-
-    /* Only used for PStoES */
-    uint32_t  streamId;
-    uint64_t  pts;
-
-    /* NTSC suxx */
-    int       repeat;
-
-    /* Only used for MPEG-4, MP3 and AAC buffers */
-    int       keyFrame;
-
-    /* Use for bitstreams */
-    int       _pos;
-};
-
-HBBuffer * HBBufferInit( int size );
-void       HBBufferReAlloc( HBBuffer *, int size );
-void       HBBufferClose( HBBuffer ** );
-
-struct HBFifo
-{
-    int         die;
-    int         capacity;
-    int         whereToPush;
-    int         whereToPop;
-    HBBuffer ** buffers;
-    HBLock    * lock;
-    HBCond    * cond;
-};
-
-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 ** );
-
-static inline int HBFifoSize( HBFifo * f )
-{
-    int size;
-    HBLockLock( f->lock );
-    size = ( f->capacity + 1 + f->whereToPush - f->whereToPop ) %
-                 ( f->capacity + 1 );
-    HBLockUnlock( f->lock );
-    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 );
-    HBCondSignal( f->cond );
-    if( ( f->capacity + 1 + f->whereToPush - f->whereToPop ) %
-            ( f->capacity + 1 ) != f->capacity )
-    {
-        f->buffers[f->whereToPush] = *b;
-        f->whereToPush++;
-        f->whereToPush %= ( f->capacity + 1 );
-        HBLockUnlock( f->lock );
-        *b = NULL;
-        return 1;
-    }
-    HBLockUnlock( f->lock );
-    return 0;
-}
-
-static inline HBBuffer * HBFifoPop( HBFifo * f )
-{
-    HBLockLock( f->lock );
-    if( f->whereToPush != f->whereToPop )
-    {
-        HBBuffer * b = f->buffers[f->whereToPop];
-        f->whereToPop++;
-        f->whereToPop %= ( f->capacity + 1 );
-        HBLockUnlock( f->lock );
-        return b;
-    }
-    HBLockUnlock( f->lock );
-    return NULL;
-}
-
-static inline int HBFifoWait( HBFifo * f )
-{
-    HBLockLock( f->lock );
-    if( f->whereToPush != f->whereToPop )
-    {
-        HBLockUnlock( f->lock );
-        return 1;
-    }
-    if( f->die )
-    {
-        HBLockUnlock( f->lock );
-        return 0;
-    }
-    HBCondWait( f->cond, f->lock );
-    if( f->whereToPush != f->whereToPop )
-    {
-        HBLockUnlock( f->lock );
-        return 1;
-    }
-    HBLockUnlock( f->lock );
-    return 0;
-}
-
-static inline float HBFifoPosition( HBFifo * f )
-{
-    float pos;
-    HBLockLock( f->lock );
-    if( f->whereToPush != f->whereToPop )
-    {
-        pos = f->buffers[f->whereToPop]->position;
-    }
-    else
-    {
-        pos = 0.0;
-    }
-    HBLockUnlock( f->lock );
-    return pos;
-}
-
-static inline int HBFifoGetBytes( HBFifo * f, uint8_t * data, int nb,
-                                  float * position )
-{
-    int whereToPop, bytes = 0;
-    HBBuffer * buffer;
-    HBLockLock( f->lock );
-
-    /* Do we have enough? */
-    for( whereToPop = f->whereToPop; ; whereToPop++ )
-    {
-        whereToPop %= ( f->capacity + 1 );
-        if( f->whereToPush == whereToPop )
-        {
-            /* We hit the end of the fifo */
-            break;
-        }
-
-        bytes += f->buffers[whereToPop]->size -
-                    f->buffers[whereToPop]->_pos;
-
-        if( bytes >= nb )
-        {
-            break;
-        }
-    }
-
-    if( bytes < nb )
-    {
-        /* Not enough data */
-        HBLockUnlock( f->lock );
-        return 0;
-    }
-
-    for( bytes = 0; bytes < nb; )
-    {
-        int copy;
-
-        buffer = f->buffers[f->whereToPop];
-        copy   = MIN( nb - bytes, buffer->size - buffer->_pos );
-
-        memcpy( data + bytes, buffer->data + buffer->_pos, copy );
-        (*position) = buffer->position;
-
-        buffer->_pos += copy;
-        bytes        += copy;
-
-        if( buffer->_pos == buffer->size )
-        {
-            HBBufferClose( &buffer );
-            f->whereToPop++;
-            f->whereToPop %= ( f->capacity + 1 );
-        }
-    }
-
-    HBLockUnlock( f->lock );
-    return 1;
-}
-
-#endif
diff --git a/core/HBInternal.h b/core/HBInternal.h
deleted file mode 100644 (file)
index 4fa45f8..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/* $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/>.
-   It may be used under the terms of the GNU General Public License. */
-
-#ifndef HB_INTERNAL_H
-#define HB_INTERNAL_H
-
-#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 ** );
-
-/* Decoders */
-HBWork * HBMpeg2DecInit( HBHandle *, HBTitle * );
-void     HBMpeg2DecClose( HBWork ** );
-HBWork * HBAc3DecInit( HBHandle *, HBAudio * );
-void     HBAc3DecClose( HBWork ** );
-HBWork * HBLpcmDecInit( HBHandle *, HBAudio * );
-void     HBLpcmDecClose( 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 ** );
-HBWork * HBXvidEncInit( HBHandle *, HBTitle * );
-void     HBXvidEncClose( HBWork ** );
-HBWork * HBX264EncInit( HBHandle *, HBTitle * );
-void     HBX264EncClose( HBWork ** );
-HBWork * HBMp3EncInit( HBHandle *, HBAudio * );
-void     HBMp3EncClose( HBWork ** );
-HBWork * HBFaacEncInit( HBHandle *, HBAudio * );
-void     HBFaacEncClose( HBWork ** );
-HBWork * HBVorbisEncInit ( HBHandle *, HBAudio * );
-void     HBVorbisEncClose( HBWork ** );
-
-/* Scanner */
-HBScan * HBScanInit( HBHandle *, const char * device, int title );
-void     HBScanClose( HBScan ** );
-
-/* Called by HBScan to tell the GUI how far we've been */
-void HBScanning( HBHandle *, int title, int titleCount );
-
-/* Called by HBScan. titleList is a list of all valid titles which
-   should be shown on the interface */
-void HBScanDone( HBHandle *, HBList * titleList );
-
-/* Used to create temporary files (/tmp/HB.pid.whatever) */
-int  HBGetPid( HBHandle * );
-
-/* Called by every thread involved in the rip process. Returns
-   immediately is rip isn't paused, blocks until the rip is resumed
-   otherwise */
-void HBCheckPaused( HBHandle * );
-
-/* Called by the decoders when the last packet is being proceeded */
-void HBDone( HBHandle * );
-
-/* Called by the video encoder to update the GUI progress */
-void HBPosition( HBHandle *, float );
-
-/* Called by any thread which couldn't continue and asks to stop */
-void HBErrorOccured( HBHandle *, int error );
-
-#endif
diff --git a/core/HandBrake.c b/core/HandBrake.c
deleted file mode 100644 (file)
index 6d16b46..0000000
+++ /dev/null
@@ -1,780 +0,0 @@
-/* $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/>.
-   It may be used under the terms of the GNU General Public License. */
-
-#include "HBInternal.h"
-
-/* libavcodec */
-#include "ffmpeg/avcodec.h"
-
-/* Local prototypes */
-static void HandBrakeThread( void * );
-static void _StopRip( HBHandle * );
-static void FixPictureSettings( HBTitle * );
-static int  GetCPUCount();
-
-struct HBHandle
-{
-    int            cpuCount;
-    HBCallbacks    cb;
-
-    int            stopScan;
-    int            stopRip;
-    int            ripDone;
-    int            error;
-
-    HBScan       * scan;
-    HBList       * titleList;
-    HBTitle      * curTitle;
-    uint64_t       beginDate;
-    uint64_t       pauseDate;
-    uint64_t       lastPosUpdate;
-    uint64_t       lastFpsUpdate;
-    int            framesSinceBegin;
-    int            framesSinceFps;
-    float          curFrameRate;
-    float          avgFrameRate;
-    int            remainingTime;
-
-    HBLock       * lock;
-    HBLock       * pauseLock;
-    volatile int   die;
-    HBThread     * thread;
-    int            pid;
-};
-
-HBHandle * HBInit( int debug, int cpuCount )
-{
-    HBHandle * h;
-
-    /* See HBLog() in Utils.cpp */
-    if( debug )
-    {
-        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 )
-    {
-        h->cpuCount = GetCPUCount();
-        HBLog( "HBInit: %d CPU%s detected", h->cpuCount,
-             ( h->cpuCount > 1 ) ? "s" : "" );
-    }
-    else
-    {
-        if( cpuCount < 1 )
-        {
-            HBLog( "HBInit: invalid CPU count (%d), using 1",
-                 cpuCount );
-            h->cpuCount = 1;
-        }
-        else if( cpuCount > 8 )
-        {
-            HBLog( "HBInit: invalid CPU count (%d), using 8",
-                 cpuCount );
-            h->cpuCount = 8;
-        }
-        else
-        {
-            HBLog( "HBInit: user specified %d CPU%s",
-                 cpuCount, ( cpuCount > 1 ) ? "s" : "" );
-            h->cpuCount = cpuCount;
-        }
-    }
-
-    h->lock      = HBLockInit();
-    h->pauseLock = HBLockInit();
-    h->thread    = HBThreadInit( "libhb", HandBrakeThread, h,
-                                 HB_NORMAL_PRIORITY );
-    return h;
-}
-
-void HBSetCallbacks( HBHandle * h, HBCallbacks callbacks )
-{
-    HBLockLock( h->lock );
-    h->cb = callbacks;
-    HBLockUnlock( h->lock );
-}
-
-void HBScanDVD( HBHandle * h, const char * dvd, int title )
-{
-    HBLockLock( h->lock );
-    h->scan = HBScanInit( h, dvd, title );
-    HBLockUnlock( h->lock );
-}
-
-void HBStartRip( HBHandle * h, HBTitle * title )
-{
-    int i;
-    HBAudio * audio;
-
-    HBLockLock( h->lock );
-
-    h->beginDate        = HBGetDate();
-    h->lastPosUpdate    = 0;
-    h->lastFpsUpdate    = 0;
-    h->framesSinceBegin = 0;
-    h->framesSinceFps   = 0;
-
-    FixPictureSettings( title );
-
-    /* Video fifos */
-    title->inFifo     = HBFifoInit( 2048 );
-    title->rawFifo    = HBFifoInit( 32 );
-    title->scaledFifo = HBFifoInit( 32 );
-    title->outFifo    = HBFifoInit( 32 );
-
-    /* Video work objects */
-    title->decoder    = HBMpeg2DecInit( h, title );
-    title->scale      = HBScaleInit( h, title );
-    if( title->codec == HB_CODEC_FFMPEG )
-        title->encoder = HBFfmpegEncInit( h, title );
-    else if( title->codec == HB_CODEC_XVID )
-        title->encoder = HBXvidEncInit( h, title );
-    else if( title->codec == HB_CODEC_X264 )
-        title->encoder = HBX264EncInit( h, title );
-
-    for( i = 0; i < HBListCount( title->ripAudioList ); i++ )
-    {
-        audio = HBListItemAt( title->ripAudioList, i );
-
-        /* Audio fifos */
-        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 );
-        else if( audio->outCodec == HB_CODEC_AAC )
-            audio->encoder = HBFaacEncInit( h, audio );
-        else if( audio->outCodec == HB_CODEC_VORBIS )
-            audio->encoder = HBVorbisEncInit( h, audio );
-    }
-
-    /* Create threads */
-    title->dvdRead = HBDVDReadInit( h, title );
-
-    title->muxThread = HBMuxThreadInit( h, title );
-
-    for( i = 0; i < h->cpuCount; i++ )
-    {
-        title->workThreads[i] = HBWorkThreadInit( h, title, i ? 0 : 1 );
-    }
-
-    h->curTitle = title;
-
-    HBLockUnlock( h->lock );
-}
-
-void HBPauseRip( HBHandle * h )
-{
-    HBLockLock( h->lock );
-    h->pauseDate = HBGetDate();
-    HBLockLock( h->pauseLock );
-    HBLockUnlock( h->lock );
-}
-
-void HBResumeRip( HBHandle * h )
-{
-    HBLockLock( h->lock );
-    h->beginDate     += HBGetDate() - h->pauseDate;
-    h->lastPosUpdate += HBGetDate() - h->pauseDate;
-    h->lastFpsUpdate += HBGetDate() - h->pauseDate;
-    HBLockUnlock( h->pauseLock );
-    HBLockUnlock( h->lock );
-}
-
-void HBStopRip( HBHandle * h )
-{
-    HBLockLock( h->lock );
-    h->stopRip = 1;
-    HBLockUnlock( h->lock );
-}
-
-uint8_t * HBGetPreview( HBHandle * h, HBTitle * t, int picture )
-{
-    AVPicture pic1, pic2, pic3, pic4;
-    uint8_t * buf1, * buf2, * buf3, * buf4;
-    char fileName[1024];
-    FILE * file;
-    ImgReSampleContext * resampleContext;
-    int8_t * preview, * pen;
-    int i;
-
-    FixPictureSettings( t );
-
-    buf1 = malloc( 3 * t->inWidth * t->inHeight / 2 );
-    buf2 = malloc( 3 * t->inWidth * t->inHeight / 2 );
-    buf3 = malloc( 3 * t->outWidth * t->outHeight / 2 );
-    buf4 = malloc( 4 * t->outWidth * t->outHeight );
-
-    if( !buf1 || !buf2 || !buf3 || !buf4 )
-    {
-        HBLog( "HBGetPreview: malloc() failed, gonna crash" );
-        return NULL;
-    }
-
-    /* Original YUV picture */
-    avpicture_fill( &pic1, buf1, PIX_FMT_YUV420P, t->inWidth,
-                    t->inHeight );
-
-    /* Deinterlaced YUV picture */
-    avpicture_fill( &pic2, buf2, PIX_FMT_YUV420P,
-                    t->inWidth, t->inHeight );
-
-    /* Scaled YUV picture */
-    avpicture_fill( &pic3, buf3, PIX_FMT_YUV420P, t->outWidth,
-                    t->outHeight );
-
-    /* Scaled RGB picture ) */
-    avpicture_fill( &pic4, buf4, PIX_FMT_RGBA32, t->outWidth,
-                    t->outHeight );
-
-    /* Get the original image from the temp file */
-    memset( fileName, 0, 1024 );
-    sprintf( fileName, "/tmp/HB.%d.%d.%d", h->pid, t->title,
-             picture );
-    file = fopen( fileName, "rb" );
-    if( file )
-    {
-        fread( buf1, 3 * t->inWidth * t->inHeight / 2, 1, file );
-        fclose( file );
-    }
-    else
-    {
-        HBLog( "HBGetPreview: could not open %s", fileName );
-        memset( buf1, 0, 3 * t->inWidth * t->inHeight / 2 );
-    }
-
-    /* Deinterlace if needed, and scale */
-    resampleContext =
-        img_resample_full_init( t->outWidth, t->outHeight,
-                                t->inWidth, t->inHeight,
-                                t->topCrop, t->bottomCrop,
-                                t->leftCrop, t->rightCrop );
-    if( t->deinterlace )
-    {
-        avpicture_deinterlace( &pic2, &pic1, PIX_FMT_YUV420P,
-                               t->inWidth, t->inHeight );
-        img_resample( resampleContext, &pic3, &pic2 );
-    }
-    else
-    {
-        img_resample( resampleContext, &pic3, &pic1 );
-    }
-
-    /* Convert to RGB */
-    img_convert( &pic4, PIX_FMT_RGBA32, &pic3, PIX_FMT_YUV420P,
-                 t->outWidth, t->outHeight );
-
-    /* Create the final preview */
-    preview = malloc( 4 * ( t->outWidthMax + 2 ) *
-                      ( t->outHeightMax + 2 ) );
-
-    if( !preview )
-    {
-        HBLog( "HBGetPreview: malloc() failed, gonna crash" );
-        return NULL;
-    }
-
-    /* Blank it */
-    memset( preview, 0x80,
-            4 * ( t->outWidthMax + 2 ) * ( t->outHeightMax + 2 ) );
-
-    /* Draw the picture (centered) and draw the cropping zone */
-    pen = preview + ( t->outHeightMax - t->outHeight ) *
-                    ( t->outWidthMax + 2 ) * 2 +
-              ( t->outWidthMax - t->outWidth ) * 2;
-
-    memset( pen, 0xFF, 4 * ( t->outWidth + 2 ) );
-    pen += 4 * ( t->outWidthMax + 2 );
-
-    for( i = 0; i < t->outHeight; i++ )
-    {
-        uint8_t * nextLine = pen + 4 * ( t->outWidthMax + 2 );
-
-        memset( pen, 0xFF, 4 );
-        pen += 4;
-        memcpy( pen, buf4 + 4 * t->outWidth * i, 4 * t->outWidth );
-        pen += 4 * t->outWidth;
-        memset( pen, 0xFF, 4 );
-
-        pen = nextLine;
-    }
-
-    memset( pen, 0xFF, 4 * ( t->outWidth + 2 ) );
-
-    /* Free memory */
-    free( buf1 );
-    free( buf2 );
-    free( buf3 );
-    free( buf4 );
-
-    return preview;
-    return NULL;
-}
-
-int HBGetBitrateForSize( HBTitle * title, int size, int muxer,
-                         int audioCount, int audioBitrate )
-{
-    int64_t available;
-    int     overheadPerFrame;
-    int     samplesPerFrame;
-    int length;
-
-    switch( muxer )
-    {
-        /* Overhead are max seen values */
-        case HB_MUX_MP4:
-            overheadPerFrame = 6;
-            samplesPerFrame  = 1024;  /* AAC */
-            break;
-        case HB_MUX_AVI:
-            overheadPerFrame = 26;
-            samplesPerFrame  = 1152;  /* MP3 */
-            break;
-        case HB_MUX_OGM:
-            overheadPerFrame = 0;     /* XXX */
-            samplesPerFrame  = 1024;  /* Vorbis */
-            break;
-        default:
-            return 0;
-    }
-
-    length = 3600 * title->hours + 60 * title->minutes +
-             title->seconds + 1;
-
-    available  = (int64_t) size * 1024 * 1024;
-
-    /* Audio data */
-    available -= audioCount * length * audioBitrate * 1000 / 8;
-
-    /* Video headers */
-    available -= (int64_t) length * title->rate *
-        overheadPerFrame / title->rateBase;
-
-    /* Audio headers */
-    available -= (int64_t) audioCount * length * 44100 *
-        overheadPerFrame / samplesPerFrame;
-
-    if( available < 0 )
-    {
-        return 0;
-    }
-    return( available / ( 128 * length ) );
-}
-
-void HBClose( HBHandle ** _h )
-{
-    char command[1024];
-
-    HBHandle * h = *_h;
-
-    h->die = 1;
-    HBThreadClose( &h->thread );
-
-    if( h->scan )
-    {
-        HBScanClose( &h->scan );
-    }
-    if( h->curTitle )
-    {
-        _StopRip( h );
-    }
-    if( h->titleList )
-    {
-        HBTitle * title;
-        while( ( title = (HBTitle*) HBListItemAt( h->titleList, 0 ) ) )
-        {
-            HBListRemove( h->titleList, title );
-            HBTitleClose( &title );
-        }
-    }
-
-#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 );
-    free( h );
-
-    *_h = NULL;
-}
-
-/* Following functions are called by libhb's internal threads */
-void HBCheckPaused( HBHandle * h )
-{
-    HBLockLock( h->pauseLock );
-    HBLockUnlock( h->pauseLock );
-}
-
-void HBScanning( HBHandle * h, int title, int titleCount )
-{
-    h->cb.scanning( h->cb.data, title, titleCount );
-}
-
-void HBScanDone( HBHandle * h, HBList * titleList )
-{
-    HBLockLock( h->lock );
-    h->stopScan  = 1;
-    h->titleList = titleList;
-    HBLockUnlock( h->lock );
-}
-
-int HBGetPid( HBHandle * h )
-{
-    return h->pid;
-}
-
-void HBDone( HBHandle * h )
-{
-    HBLockLock( h->lock );
-    h->ripDone = 1;
-    HBLockUnlock( h->lock );
-}
-
-void HBPosition( HBHandle * h, float position )
-{
-    int pass, passCount;
-
-    h->framesSinceBegin++;
-    h->framesSinceFps++;
-
-    if( h->curTitle->twoPass )
-    {
-        pass      = ( position < 0.5 ) ? 1 : 2;
-        passCount = 2;
-    }
-    else
-    {
-        passCount = pass = 1;
-    }
-
-    if( HBGetDate() - h->lastPosUpdate < 200000 )
-    {
-        return;
-    }
-
-    h->lastPosUpdate  = HBGetDate();
-
-    if( HBGetDate() - h->lastFpsUpdate > 1000000 )
-    {
-        h->curFrameRate = 1000000.0 * h->framesSinceFps /
-            ( HBGetDate() - h->lastFpsUpdate );
-        h->avgFrameRate = 1000000.0 * h->framesSinceBegin /
-            ( HBGetDate() - h->beginDate );
-        h->remainingTime = ( 1.0 - position ) *
-            ( HBGetDate() - h->beginDate ) / position / 1000000;
-
-        h->lastFpsUpdate  = HBGetDate();
-        h->framesSinceFps = 0;
-    }
-
-    h->cb.encoding( h->cb.data, position, pass, passCount,
-                           h->curFrameRate, h->avgFrameRate,
-                           h->remainingTime );
-}
-
-void HBErrorOccured( HBHandle * h, int error )
-{
-    HBLockLock( h->lock );
-    h->error = error;
-    HBLockUnlock( h->lock );
-}
-
-/* Local functions */
-static void HandBrakeThread( void * _h )
-{
-    HBHandle * h = (HBHandle*) _h;
-
-    h->pid = getpid();
-
-    while( !h->die )
-    {
-        HBLockLock( h->lock );
-
-        if( h->stopScan )
-        {
-            HBScanClose( &h->scan );
-            h->stopScan = 0;
-            HBLockUnlock( h->lock );
-            h->cb.scanDone( h->cb.data, h->titleList );
-            continue;
-        }
-
-        if( h->stopRip )
-        {
-            _StopRip( h );
-            h->stopRip = 0;
-            HBLockUnlock( h->lock );
-            h->cb.ripDone( h->cb.data, HB_CANCELED );
-            continue;
-        }
-
-        if( h->ripDone )
-        {
-            HBTitle * title = h->curTitle;
-
-            /* Wait until we're done with the video track */
-            uint64_t  waitStart = HBGetDate();
-            for( ;; )
-            {
-                if( !HBFifoSize( title->inFifo ) &&
-                    !HBFifoSize( title->rawFifo ) &&
-                    !HBFifoSize( title->scaledFifo ) )
-                {
-                    break;
-                }
-
-                /* 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;
-        }
-
-        if( h->error )
-        {
-            _StopRip( h );
-            HBLockUnlock( h->lock );
-            h->cb.ripDone( h->cb.data, h->error );
-            h->error = 0;
-            continue;
-        }
-
-        HBLockUnlock( h->lock );
-        HBSnooze( 10000 );
-    }
-}
-
-static void _StopRip( HBHandle * h )
-{
-    HBTitle * title = h->curTitle;
-    HBAudio * audio;
-    int i;
-
-    if( !title )
-    {
-        return;
-    }
-
-    /* Stop input and work threads */
-    HBDVDReadClose( &title->dvdRead );
-    for( i = 0; i < h->cpuCount; i++ )
-    {
-        HBWorkThreadClose( &title->workThreads[h->cpuCount-i-1] );
-    }
-
-    /* Invalidate fifos */
-    HBFifoDie( title->outFifo );
-    for( i = 0; i < HBListCount( title->ripAudioList ); i++ )
-    {
-        audio = HBListItemAt( title->ripAudioList, i );
-        HBFifoDie( audio->outFifo );
-    }
-
-    /* Stop mux thread */
-    HBMuxThreadClose( &title->muxThread );
-
-    /* Clean up */
-    HBMpeg2DecClose( &title->decoder );
-    HBScaleClose( &title->scale );
-
-    if( title->codec == HB_CODEC_FFMPEG )
-        HBFfmpegEncClose( &title->encoder );
-    else if( title->codec == HB_CODEC_XVID )
-        HBXvidEncClose( &title->encoder );
-    else if( title->codec == HB_CODEC_X264 )
-        HBX264EncClose( &title->encoder );
-
-    HBFifoClose( &title->inFifo );
-    HBFifoClose( &title->rawFifo );
-    HBFifoClose( &title->scaledFifo );
-    HBFifoClose( &title->outFifo );
-
-    while( ( audio = HBListItemAt( title->ripAudioList, 0 ) ) )
-    {
-        /* Audio work objects */
-        if( audio->inCodec == HB_CODEC_AC3 )
-            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 );
-        else if( audio->outCodec == HB_CODEC_AAC )
-            HBFaacEncClose( &audio->encoder );
-        else if( audio->outCodec == HB_CODEC_VORBIS )
-            HBVorbisEncClose( &audio->encoder );
-
-        /* Audio fifos */
-        HBFifoClose( &audio->inFifo );
-        HBFifoClose( &audio->rawFifo );
-        HBFifoClose( &audio->resampleFifo );
-        HBFifoClose( &audio->outFifo );
-
-        HBListRemove( title->ripAudioList, audio );
-    }
-
-    h->curTitle = NULL;
-}
-
-static void FixPictureSettings( HBTitle * t )
-{
-    /* Sanity checks */
-    t->outWidth   = MULTIPLE_16( t->outWidth );
-    t->topCrop    = EVEN( t->topCrop );
-    t->bottomCrop = EVEN( t->bottomCrop );
-    t->leftCrop   = EVEN( t->leftCrop );
-    t->rightCrop  = EVEN( t->rightCrop );
-
-    t->outWidth   = MIN( t->outWidth, t->outWidthMax );
-    t->outWidth   = MAX( 16, t->outWidth );
-
-    t->outHeight  =
-        MULTIPLE_16( (uint64_t) t->outWidth * t->inWidth *
-                     ( t->inHeight - t->topCrop - t->bottomCrop ) *
-                     VOUT_ASPECT_FACTOR /
-                     ( (uint64_t) t->inHeight *
-                     ( t->inWidth - t->leftCrop - t->rightCrop ) *
-                     t->aspect ) );
-    t->outHeight  = MAX( 16, t->outHeight );
-
-    if( t->outHeight > t->outHeightMax )
-    {
-        t->outHeight = t->outHeightMax;
-        t->outWidth  =
-            MULTIPLE_16( (uint64_t) t->outHeight * t->inHeight *
-                         ( t->inWidth - t->leftCrop - t->rightCrop ) *
-                         t->aspect /
-                         ( (uint64_t) t->inWidth *
-                         ( t->inHeight - t->topCrop - t->bottomCrop ) *
-                         VOUT_ASPECT_FACTOR ) );
-        t->outWidth  = MIN( t->outWidth, t->outWidthMax );
-        t->outWidth  = MAX( 16, t->outWidth );
-    }
-}
-
-static int GetCPUCount()
-{
-    int CPUCount = 1;
-
-#if defined( HB_BEOS )
-    system_info info;
-    get_system_info( &info );
-    CPUCount = info.cpu_count;
-
-#elif defined( HB_MACOSX )
-    FILE * info;
-    char   buffer[256];
-
-    if( ( info = popen( "/usr/sbin/sysctl hw.ncpu", "r" ) ) )
-    {
-        if( fgets( buffer, 256, info ) )
-        {
-            int count;
-            if( sscanf( buffer, "hw.ncpu: %d", &count ) == 1 )
-            {
-                CPUCount = count;
-            }
-            else
-            {
-                HBLog( "GetCPUCount: sscanf() failed" );
-            }
-        }
-        else
-        {
-            HBLog( "GetCPUCount: fgets() failed" );
-        }
-        fclose( info );
-    }
-    else
-    {
-        HBLog( "GetCPUCount: popen() failed" );
-    }
-
-#elif defined( HB_LINUX )
-    FILE * info;
-    char   buffer[256];
-
-    if( ( info = popen( "grep -c '^processor' /proc/cpuinfo", "r" ) ) )
-    {
-        if( fgets( buffer, 256, info ) )
-        {
-            int count;
-            if( sscanf( buffer, "%d", &count ) == 1 )
-            {
-                CPUCount = count;
-            }
-            else
-            {
-                HBLog( "GetCPUCount: sscanf() failed" );
-            }
-        }
-        else
-        {
-            HBLog( "GetCPUCount: fgets() failed" );
-        }
-        fclose( info );
-    }
-    else
-    {
-        HBLog( "GetCPUCount: fopen() failed" );
-    }
-
-#elif defined( HB_CYGWIN )
-    /* TODO */
-    CPUCount = 1;
-
-#endif
-    CPUCount = MAX( 1, CPUCount );
-    CPUCount = MIN( CPUCount, 8 );
-
-    return CPUCount;
-}
-
diff --git a/core/HandBrake.h b/core/HandBrake.h
deleted file mode 100644 (file)
index 9d84d39..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/* $Id: HandBrake.h,v 1.10 2004/01/21 18:40:36 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_HANDBRAKE_H
-#define HB_HANDBRAKE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "Utils.h"
-
-/* Interface callbacks */
-typedef struct HBCallbacks
-{
-    void * data;
-
-    void (*scanning) ( void * data, int title, int titleCount );
-    void (*scanDone) ( void * data, HBList * titleList );
-    void (*encoding) ( void * data, float position, int pass,
-                       int passCount, float curFrameRate,
-                       float avgFrameRate, int remainingTime );
-    void (*ripDone)  ( void * data, int result );
-
-} HBCallbacks;
-
-/* Init libhb. Set debug to 0 to see no output, 1 to see all libhb logs.
-   Set cpuCount to 0 if you want libhb to autodetect */
-HBHandle * HBInit( int debug, int cpuCount );
-
-/* Tell libhb what functions should be called when a GUI should be
-   updated. */
-void       HBSetCallbacks( HBHandle *, HBCallbacks callbacks );
-
-/* Launch a thread which scans the specified DVD and title. Use
-   title = 0 to scan all titles. Returns immediately */
-void       HBScanDVD( HBHandle *, const char * dvd, int title );
-
-/* Calculate bitrate so the output file fits in X MB */
-int        HBGetBitrateForSize( HBTitle * title, int size, int muxer,
-                                int audioCount, int audioBitrate );
-
-/* Start ripping the specified title. Returns immediatly */
-void       HBStartRip( HBHandle *, HBTitle * );
-
-/* Suspend rip */
-void       HBPauseRip( HBHandle * );
-
-/* Resume rip */
-void       HBResumeRip( HBHandle * );
-
-/* Cancel rip. Returns immediatly - you'll be noticed by the ripDone
-   callback when it's really stopped.
-   If the rip was paused, you _must_ call HBResumeRip() first. */
-void       HBStopRip( HBHandle * );
-
-/* Calculate preview for the specified picture of the specified title,
-   taking care of the current cropping & scaling settings. Returns a
-   pointer to raw RGBA data that _has_ to be freed by the calling
-   function. The picture includes the white border around the picture,
-   so its size is ( maxWidth + 2 ) x ( maxHeight + 2 ).
-   The data belongs to the caller, who must free it. */
-uint8_t  * HBGetPreview( HBHandle *, HBTitle *, int picture );
-
-/* Clean up things */
-void       HBClose( HBHandle ** );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/core/Jamfile b/core/Jamfile
deleted file mode 100644 (file)
index 3c68353..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-# $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/>.
-# It may be used under the terms of the GNU General Public License.
-
-SubDir TOP core ;
-
-LIBHB_SRC =
-    Ac3Dec.c AviMux.c DVDRead.c FaacEnc.c FfmpegEnc.c Fifo.c HandBrake.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 -W ;
-
-# Needed includes
-ObjectHdrs Ac3Dec.c    : $(TOP)/contrib/liba52 ;
-ObjectHdrs FfmpegEnc.c
-           HandBrake.c
-           MpgaDec.c
-           Scale.c     : $(TOP)/contrib/libavcodec ;
-ObjectHdrs DVDRead.c
-           Scan.c      : $(TOP)/contrib/libdvdread ;
-ObjectHdrs FaacEnc.c   : $(TOP)/contrib/libfaac ;
-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 ;
-ObjectHdrs X264Enc.c   : $(TOP)/contrib/libx264 ;
-ObjectHdrs XvidEnc.c   : $(TOP)/contrib/libxvidcore ;
-
diff --git a/core/LpcmDec.c b/core/LpcmDec.c
deleted file mode 100644 (file)
index 425f429..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/* $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/>.
-   It may be used under the terms of the GNU General Public License. */
-
-#include "HBInternal.h"
-
-struct HBWork
-{
-    HB_WORK_COMMON_MEMBERS
-
-    HBHandle    * handle;
-    HBAudio     * audio;
-
-    int           initDone;
-};
-
-/* Local prototypes */
-static int LpcmDecWork( HBWork * );
-
-HBWork * HBLpcmDecInit( HBHandle * handle, HBAudio * audio )
-{
-    HBWork * w;
-    if( !( w = calloc( sizeof( HBWork ), 1 ) ) )
-    {
-        HBLog( "HBLpcmDecInit: malloc() failed, gonna crash" );
-        return NULL;
-    }
-
-    w->name = strdup( "LpcmDec" );
-    w->work = LpcmDecWork;
-
-    w->handle = handle;
-    w->audio  = audio;
-
-    return w;
-}
-
-void HBLpcmDecClose( HBWork ** _w )
-{
-    HBWork * w = *_w;
-    free( w->name );
-    free( w );
-    *_w = NULL;
-}
-
-static int LpcmDecWork( HBWork * w )
-{
-    HBAudio   * audio  = w->audio;
-
-    HBBuffer  * lpcmBuffer;
-    HBBuffer  * rawBuffer;
-    uint8_t   * samples_u8;
-    float     * samples_f;
-    int         samples_nr, i;
-
-    if( HBFifoIsHalfFull( audio->rawFifo ) )
-    {
-        return 0;
-    }
-
-    /* Get a new LPCM buffer */
-    lpcmBuffer = HBFifoPop( audio->inFifo );
-    if( !lpcmBuffer )
-    {
-        return 0;
-    }
-
-    if( !w->initDone )
-    {
-        /* SampleRate */
-        switch( ( lpcmBuffer->data[4] >> 4 ) & 0x3 )
-        {
-            case 0:
-                audio->inSampleRate = 48000;
-                break;
-            case 1:
-                audio->inSampleRate = 32000;
-                break;
-            default:
-                HBLog( "HBLpcmDec: unknown samplerate (%d)",
-                       ( lpcmBuffer->data[4] >> 4 ) & 0x3 );
-        }
-
-        /* We hope there are 2 channels */
-        HBLog( "HBLpcmDec: samplerate: %d Hz, channels: %d",
-               audio->inSampleRate, ( lpcmBuffer->data[4] & 0x7 ) + 1 );
-
-        w->initDone = 1;
-    }
-
-    if( lpcmBuffer->data[5] != 0x80 )
-    {
-        HBLog( "HBLpcmDec: no frame sync (%02x)", lpcmBuffer->data[5] );
-    }
-
-    /* Allocate raw buffer */
-    samples_nr          = ( lpcmBuffer->size - 6 ) / sizeof( int16_t );
-    rawBuffer           = HBBufferInit( samples_nr * sizeof( float ) );
-    rawBuffer->position = lpcmBuffer->position;
-
-    /* Big endian int16 -> float conversion (happy casting) */
-    samples_u8 = lpcmBuffer->data + 6;
-    samples_f  = rawBuffer->dataf;
-    for( i = 0; i < samples_nr; i++ )
-    {
-        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/Mp3Enc.c b/core/Mp3Enc.c
deleted file mode 100644 (file)
index c1aae34..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-/* $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/>.
-   It may be used under the terms of the GNU General Public License. */
-
-#include "HBInternal.h"
-
-/* libmp3lame */
-#include "lame/lame.h"
-
-struct HBWork
-{
-    HB_WORK_COMMON_MEMBERS
-
-    HBHandle          * handle;
-    HBAudio           * audio;
-    lame_global_flags * globalFlags;
-};
-
-/* Local prototypes */
-static int Mp3EncWork( HBWork * );
-
-HBWork * HBMp3EncInit( HBHandle * handle, HBAudio * audio )
-{
-    HBWork * w;
-    if( !( w = calloc( sizeof( HBWork ), 1 ) ) )
-    {
-        HBLog( "HBMp3EncInit: malloc() failed, gonna crash" );
-        return NULL;
-    }
-
-    w->name   = strdup( "Mp3Enc" );
-    w->work   = Mp3EncWork;
-
-    w->handle = handle;
-    w->audio  = audio;
-
-    return w;
-}
-
-void HBMp3EncClose( HBWork ** _w )
-{
-    HBWork * w = *_w;
-
-    if( w->globalFlags ) lame_close( w->globalFlags );
-
-    free( w->name );
-    free( w );
-    *_w = NULL;
-}
-
-static int Mp3EncWork( HBWork * w )
-{
-    HBAudio  * audio = w->audio;
-
-    HBBuffer * mp3Buffer;
-    int        ret;
-
-    float   samples_f[1152 * 2];
-    int16_t samples_s16[1152 * 2];
-    float   position;
-    int     i;
-
-    if( !w->globalFlags )
-    {
-        if( !HBFifoSize( audio->resampleFifo ) )
-        {
-            return 0;
-        }
-
-        HBLog( "HBMp3Enc: opening lame (%d kbps)", audio->outBitrate );
-
-        w->globalFlags = lame_init();
-        lame_set_brate( w->globalFlags, audio->outBitrate );
-
-        /* No resampling there - it's been done before */
-        lame_set_in_samplerate( w->globalFlags, audio->outSampleRate );
-        lame_set_out_samplerate( w->globalFlags, audio->outSampleRate );
-
-        if( lame_init_params( w->globalFlags ) == -1 )
-        {
-            HBLog( "HBMp3Enc: lame_init_params() failed" );
-            HBErrorOccured( w->handle, HB_ERROR_MP3_INIT );
-            return 0;
-        }
-    }
-
-    if( HBFifoIsHalfFull( audio->outFifo ) )
-    {
-        return 0;
-    }
-
-    if( !HBFifoGetBytes( audio->resampleFifo, (uint8_t*) samples_f,
-                         1152 * 2 * sizeof( float ), &position ) )
-    {
-        return 0;
-    }
-
-    /* float -> s16 */
-    for( i = 0; i < 1152 * 2; i++ )
-    {
-        samples_s16[i] = samples_f[i];
-    }
-
-    mp3Buffer = HBBufferInit( LAME_MAXMP3BUFFER );
-    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( w->handle, HB_ERROR_MP3_ENCODE );
-        HBBufferClose( &mp3Buffer );
-    }
-    else if( ret == 0 )
-    {
-        /* No error, but nothing encoded */
-        HBBufferClose( &mp3Buffer );
-    }
-    else
-    {
-        /* Encoding was successful */
-        mp3Buffer->size     = ret;
-        mp3Buffer->keyFrame = 1;
-        mp3Buffer->position = position;
-
-        if( !HBFifoPush( audio->outFifo, &mp3Buffer ) )
-        {
-            HBLog( "HBMp3Enc: HBFifoPush failed" );
-        }
-    }
-
-    return 1;
-}
-
diff --git a/core/Mp4Mux.c b/core/Mp4Mux.c
deleted file mode 100644 (file)
index d48c1ad..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-/* $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/>.
-   It may be used under the terms of the GNU General Public License. */
-
-#include "HBInternal.h"
-
-/* libmp4v2 */
-#include "mp4.h"
-
-struct HBMux
-{
-    HB_MUX_COMMON_MEMBERS
-
-    HBHandle      * handle;
-    HBTitle       * title;
-
-    MP4FileHandle   file;
-
-    /* QuickTime sync workaround */
-    int             sampleRate;
-    uint64_t        frames;
-    uint64_t        date;
-
-};
-
-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 )
-{
-    HBMux   * m;
-    HBAudio * audio;
-    int       i;
-
-    if( !( m = calloc( sizeof( HBMux ), 1 ) ) )
-    {
-        HBLog( "HBMp4Mux: malloc() failed, gonna crash" );
-        return NULL;
-    }
-    m->start    = Mp4Start;
-    m->muxVideo = Mp4MuxVideo;
-    m->muxAudio = Mp4MuxAudio;
-    m->end      = Mp4End;
-
-    m->handle   = handle;
-    m->title    = title;
-
-    /* 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( 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 Mp4Start( HBMux * m )
-{
-    HBTitle    * title = m->title;
-    HBAudio    * audio;
-    Mp4MuxData * muxData;
-    int          i;
-
-    /* Create file */
-    m->file = MP4Create( title->file, 0, 0 );
-
-    /* Add video track */
-    muxData = (Mp4MuxData *) title->muxData;
-    if( HBListCount( title->ripAudioList ) )
-    {
-        /* 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 );
-    }
-    else
-    {
-        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 );
-
-    /* Add audio tracks */
-    for( i = 0; i < HBListCount( title->ripAudioList ); i++ )
-    {
-        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 );
-    }
-
-    return 0;
-}
-
-static int Mp4MuxVideo( HBMux * m, void * _muxData, HBBuffer * buffer )
-{
-    Mp4MuxData * muxData = (Mp4MuxData *) _muxData;
-    HBTitle    * title   = m->title;
-
-    if( HBListCount( title->ripAudioList ) )
-    {
-        /* 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;
-    }
-    else
-    {
-        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( m->file );
-
-    HBLog( "HBMp4Mux: making the file ISMA compliant" );
-    if( !MP4MakeIsmaCompliant( title->file, 0 /*MP4_DETAILS_ALL*/, 1 ) )
-    {
-        HBLog( "HBMp4Mux: MP4MakeIsmaCompliant() failed" );
-    }
-
-    HBLog( "HBMp4Mux: optimizing" );
-    sprintf( tmpFile, "%s.tmp", title->file );
-    tmpFile[strlen( title->file ) + 4] = '\0';
-    if( !MP4Optimize( title->file, tmpFile, 0 /*MP4_DETAILS_ALL*/ ) )
-    {
-        HBLog( "HBMp4Mux: MP4Optimize() failed" );
-        unlink( tmpFile );
-    }
-    else
-    {
-        rename( tmpFile, title->file );
-    }
-    return 0;
-}
-
diff --git a/core/Mpeg2Dec.c b/core/Mpeg2Dec.c
deleted file mode 100644 (file)
index 043c416..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-/* $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/>.
-   It may be used under the terms of the GNU General Public License. */
-
-#include "HBInternal.h"
-
-#include "mpeg2dec/mpeg2.h"
-
-struct HBWork
-{
-    HB_WORK_COMMON_MEMBERS
-
-    HBHandle           * handle;
-    HBTitle            * title;
-    int                  pass;
-    mpeg2dec_t         * libmpeg2;
-    const mpeg2_info_t * info;
-    int                  lateField;
-};
-
-/* Local prototypes */
-static int Mpeg2DecWork( HBWork * );
-
-HBWork * HBMpeg2DecInit( HBHandle * handle, HBTitle * title )
-{
-    HBWork * w ;
-    if( !( w = malloc( sizeof( HBWork ) ) ) )
-    {
-        HBLog( "HBMpeg2Dec: malloc() failed, gonna crash" );
-        return NULL;
-    }
-
-    w->name   = strdup( "Mpeg2Dec" );
-    w->work   = Mpeg2DecWork;
-
-    w->handle = handle;
-    w->title  = title;
-
-    w->pass          = 42;
-    w->libmpeg2      = NULL;
-    w->info          = NULL;
-    w->lateField     = 0;
-
-    return w;
-}
-
-void HBMpeg2DecClose( HBWork ** _w )
-{
-    HBWork * w = *_w;
-
-    if( w->libmpeg2 )
-    {
-        HBLog( "HBMpeg2Dec: closing libmpeg2 (pass %d)", w->pass );
-        mpeg2_close( w->libmpeg2 );
-    }
-    free( w->name );
-    free( w );
-
-    *_w = NULL;
-}
-
-static int Mpeg2DecWork( HBWork * w )
-{
-    HBTitle     * title = w->title;
-    HBBuffer    * mpeg2Buffer;
-    HBBuffer    * rawBuffer;
-    mpeg2_state_t state;
-
-    if( HBFifoIsHalfFull( title->rawFifo ) )
-    {
-        return 0;
-    }
-
-    /* Get a new buffer to decode */
-    if( !( mpeg2Buffer = HBFifoPop( title->inFifo ) ) )
-    {
-        return 0;
-    }
-
-    /* Init or re-init if needed */
-    if( mpeg2Buffer->pass != w->pass )
-    {
-        if( w->libmpeg2 )
-        {
-            HBLog( "HBMpeg2Dec: closing libmpeg2 (pass %d)", w->pass );
-            mpeg2_close( w->libmpeg2 );
-        }
-
-        w->pass = mpeg2Buffer->pass;
-
-        HBLog( "HBMpeg2Dec: opening libmpeg2 (pass %d)", w->pass );
-#ifdef HB_NOMMX
-        mpeg2_accel( 0 );
-#endif
-        w->libmpeg2  = mpeg2_init();
-        w->info      = mpeg2_info( w->libmpeg2 );
-        w->lateField = 0;
-    }
-
-    /* Decode */
-    mpeg2_buffer( w->libmpeg2, mpeg2Buffer->data,
-                  mpeg2Buffer->data + mpeg2Buffer->size );
-
-    for( ;; )
-    {
-        state = mpeg2_parse( w->libmpeg2 );
-
-        if( state == STATE_BUFFER )
-        {
-            break;
-        }
-        else if( ( state == STATE_SLICE || state == STATE_END ) &&
-                 w->info->display_fbuf )
-        {
-            rawBuffer = HBBufferInit( 3 * title->inWidth *
-                                      title->inHeight );
-
-            /* TODO: make libmpeg2 write directly in our buffer */
-            memcpy( rawBuffer->data, w->info->display_fbuf->buf[0],
-                    title->inWidth * title->inHeight );
-            memcpy( rawBuffer->data + title->inWidth * title->inHeight,
-                    w->info->display_fbuf->buf[1],
-                    title->inWidth * title->inHeight / 4 );
-            memcpy( rawBuffer->data + title->inWidth * title->inHeight +
-                        title->inWidth * title->inHeight / 4,
-                    w->info->display_fbuf->buf[2],
-                    title->inWidth * title->inHeight / 4 );
-
-            rawBuffer->position = mpeg2Buffer->position;
-            rawBuffer->pass     = mpeg2Buffer->pass;
-
-            /* NTSC pulldown kludge */
-            if( w->info->display_picture->nb_fields == 3 )
-            {
-                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 )
-        {
-            /* Shouldn't happen on a DVD */
-            HBLog( "HBMpeg2Dec: STATE_INVALID" );
-        }
-    }
-
-    HBBufferClose( &mpeg2Buffer );
-
-    return 1;
-}
diff --git a/core/MpgaDec.c b/core/MpgaDec.c
deleted file mode 100644 (file)
index e397a72..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/* $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
deleted file mode 100644 (file)
index c9449e7..0000000
+++ /dev/null
@@ -1,228 +0,0 @@
-/* $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
deleted file mode 100644 (file)
index fbd1fd9..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* $Id: Mux.h,v 1.2 2004/05/02 16:25:00 titer Exp $
-
-   This file is part of the HandBrake source code.
-   Homepage: <http://handbrake.m0k.org/>.
-   It may be used under the terms of the GNU General Public License. */
-
-#ifndef HB_MUX_H
-#define HB_MUX_H
-
-#define HB_MUX_COMMON_MEMBERS \
-    int (*start)    ( HBMux * ); \
-    int (*muxVideo) ( HBMux *, void *, HBBuffer * ); \
-    int (*muxAudio) ( HBMux *, void *, HBBuffer * ); \
-    int (*end)      ( HBMux * );
-
-typedef struct HBMux HBMux;
-
-HBMuxThread * HBMuxThreadInit( HBHandle *, HBTitle * );
-void          HBMuxThreadClose( HBMuxThread ** );
-
-#endif
diff --git a/core/OgmMux.c b/core/OgmMux.c
deleted file mode 100644 (file)
index e99a494..0000000
+++ /dev/null
@@ -1,396 +0,0 @@
-/* $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/>.
-   It may be used under the terms of the GNU General Public License. */
-
-#include "HBInternal.h"
-
-#include <ogg/ogg.h>
-
-static int OgmStart( HBMux * );
-static int OgmMux( HBMux *, void *, HBBuffer * );
-static int OgmEnd( HBMux * );
-
-struct HBMux
-{
-    HB_MUX_COMMON_MEMBERS
-
-    HBHandle * handle;
-    HBTitle  * title;
-    FILE     * file;
-};
-
-typedef struct
-{
-    int              codec;
-    ogg_stream_state os;
-    int              i_packet_no;
-
-} OgmMuxData;
-
-typedef struct __attribute__((__packed__))
-{
-    uint8_t i_packet_type;
-
-    char stream_type[8];
-    char sub_type[4];
-
-    int32_t i_size;
-
-    int64_t i_time_unit;
-    int64_t i_samples_per_unit;
-    int32_t i_default_len;
-
-    int32_t i_buffer_size;
-    int16_t i_bits_per_sample;
-    int16_t i_padding_0;            // hum hum
-    union
-    {
-        struct
-        {
-            int32_t i_width;
-            int32_t i_height;
-
-        } video;
-        struct
-        {
-            int16_t i_channels;
-            int16_t i_block_align;
-            int32_t i_avgbytespersec;
-        } audio;
-    } header;
-
-} ogg_stream_header_t;
-
-#define SetWLE( p, v ) _SetWLE( (uint8_t*)p, v)
-static void _SetWLE( uint8_t *p, uint16_t i_dw )
-{
-    p[1] = ( i_dw >>  8 )&0xff;
-    p[0] = ( i_dw       )&0xff;
-}
-
-#define SetDWLE( p, v ) _SetDWLE( (uint8_t*)p, v)
-static void _SetDWLE( uint8_t *p, uint32_t i_dw )
-{
-    p[3] = ( i_dw >> 24 )&0xff;
-    p[2] = ( i_dw >> 16 )&0xff;
-    p[1] = ( i_dw >>  8 )&0xff;
-    p[0] = ( i_dw       )&0xff;
-}
-#define SetQWLE( p, v ) _SetQWLE( (uint8_t*)p, v)
-static void _SetQWLE( uint8_t *p, uint64_t i_qw )
-{
-    SetDWLE( p,   i_qw&0xffffffff );
-    SetDWLE( p+4, ( i_qw >> 32)&0xffffffff );
-}
-
-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( &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 )
-        {
-            return -1;
-        }
-    }
-    return 0;
-}
-
-static int OgmStart( HBMux * m )
-{
-    HBTitle           * title = m->title;
-    HBAudio           * audio;
-    OgmMuxData        * muxData;
-    ogg_packet          op;
-    ogg_stream_header_t h;
-    int                 i;
-
-    /* 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 tracks */
-
-    /* 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 = (HBAudio *) HBListItemAt( title->ripAudioList, i );
-        muxData = (OgmMuxData *) audio->muxData;
-
-        muxData->codec = audio->outCodec;
-        muxData->i_packet_no = 0;
-        ogg_stream_init( &muxData->os, i + 1 );
-
-    }
-
-    /* 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 )
-    {
-        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 = muxData->i_packet_no++;
-    ogg_stream_packetin( &muxData->os, &op );
-    OgmFlush( m, muxData );
-
-    /* Audio */
-    for( i = 0; i < HBListCount( title->ripAudioList ); i++ )
-    {
-        audio   = (HBAudio *) HBListItemAt( title->ripAudioList, i );
-        muxData = (OgmMuxData *) audio->muxData;
-        memset( &h, 0, sizeof( ogg_stream_header_t ) );
-        switch( muxData->codec )
-        {
-            case HB_CODEC_MP3:
-            {
-                h.i_packet_type = 0x01;
-                memcpy( h.stream_type, "audio    ", 8 );
-                memcpy( h.sub_type, "55  ", 4 );
-
-                SetDWLE( &h.i_size, sizeof( ogg_stream_header_t ) - 1);
-                SetQWLE( &h.i_time_unit, 0 );
-                SetQWLE( &h.i_samples_per_unit, audio->outSampleRate );
-                SetDWLE( &h.i_default_len, 1 );
-                SetDWLE( &h.i_buffer_size, 30*1024 );
-                SetWLE ( &h.i_bits_per_sample, 0 );
-
-                SetDWLE( &h.header.audio.i_channels, 2 );
-                SetDWLE( &h.header.audio.i_block_align, 0 );
-                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 = muxData->i_packet_no++;
-                ogg_stream_packetin( &muxData->os, &op );
-                break;
-            }
-            case HB_CODEC_VORBIS:
-            {
-                HBBuffer *h = HBFifoPop( audio->outFifo );
-
-                memcpy( &op, h->data, sizeof( ogg_packet ) );
-                op.packet = h->data + sizeof( ogg_packet );
-                ogg_stream_packetin( &muxData->os, &op );
-                break;
-            }
-            default:
-                HBLog( "HBOgmMux: unhandled codec" );
-                break;
-        }
-        OgmFlush( m, muxData );
-    }
-
-    /* second pass: all non b_o_s packets */
-    for( i = 0; i < HBListCount( title->ripAudioList ); i++ )
-    {
-        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++ )
-            {
-                h = HBFifoPop( audio->outFifo );
-
-                memcpy( &op, h->data, sizeof( ogg_packet ) );
-                op.packet = h->data + sizeof( ogg_packet );
-                ogg_stream_packetin( &muxData->os, &op );
-
-                OgmFlush( m, muxData );
-            }
-        }
-    }
-
-    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( ;; )
-        {
-            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;
-            }
-        }
-        free( op.packet );
-    }
-    return 0;
-}
-
-static int OgmEnd( HBMux * m )
-{
-    HBTitle    * title = m->title;
-    HBAudio    * audio;
-    OgmMuxData * muxData;
-    int          i;
-
-    muxData = (OgmMuxData *) title->muxData;
-    if( OgmFlush( m, muxData ) < 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
deleted file mode 100644 (file)
index f3632b3..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-/* $Id: Resample.c,v 1.4 2004/05/02 16:25:00 titer Exp $
-
-   This file is part of the HandBrake source code.
-   Homepage: <http://handbrake.m0k.org/>.
-   It may be used under the terms of the GNU General Public License. */
-
-#include "HBInternal.h"
-
-#include "samplerate.h"
-
-struct HBWork
-{
-    HB_WORK_COMMON_MEMBERS
-
-    HBHandle  * handle;
-    HBAudio   * audio;
-
-    float     * samples;
-    SRC_STATE * state;
-    SRC_DATA    data;
-
-    uint64_t    in;
-    uint64_t    out;
-};
-
-/* Local prototypes */
-static int ResampleWork( HBWork * );
-
-HBWork * HBResampleInit( HBHandle * handle, HBAudio * audio )
-{
-    HBWork * w;
-    if( !( w = calloc( sizeof( HBWork ), 1 ) ) )
-    {
-        HBLog( "HBResampleInit: malloc() failed, gonna crash" );
-        return NULL;
-    }
-
-    w->name = strdup( "Resample" );
-    w->work = ResampleWork;
-
-    w->handle = handle;
-    w->audio  = audio;
-
-    return w;
-}
-
-void HBResampleClose( HBWork ** _w )
-{
-    HBWork * w = *_w;
-
-    if( w->samples ) free( w->samples );
-    if( w->state )   src_delete( w->state );
-
-    free( w->name );
-    free( w );
-    *_w = NULL;
-}
-
-static int ResampleWork( HBWork * w )
-{
-    HBAudio  * audio = w->audio;
-
-    HBBuffer * resampleBuffer;
-    float      position;
-
-    if( HBFifoIsHalfFull( audio->resampleFifo ) )
-    {
-        return 0;
-    }
-
-    /* Initialization */
-    if( !w->samples )
-    {
-        int error;
-
-        /* Until a first packet comes, audio->inSampleRate is
-           undefined */
-        if( !HBFifoSize( audio->rawFifo ) )
-        {
-            return 0;
-        }
-
-        /* No, the user can't choose. 44100 Hz, take it or leave it */
-        audio->outSampleRate = 44100;
-        HBLog( "HBResample: in = %d Hz, out = %d Hz",
-                audio->inSampleRate, audio->outSampleRate );
-
-        /* Buffer in which we'll pop the samples from the decoder */
-        w->samples = malloc( audio->inSampleRate * 2 *
-                             sizeof( float ) / 10 );
-
-        /* Init libsamplerate */
-        w->state = src_new( SRC_SINC_FASTEST, 2, &error );
-
-        /* Prepare the SRC_DATA structure */
-        w->data.data_in       = w->samples;
-        w->data.input_frames  = audio->inSampleRate / 10;
-        w->data.output_frames = audio->outSampleRate / 10;
-        w->data.src_ratio     = (double) audio->outSampleRate /
-                                (double) audio->inSampleRate;
-        w->data.end_of_input  = 0;
-    }
-
-    /* Fix A/V synchro in case the audio track starts later than the
-       video */
-    if( audio->delay > 0 )
-    {
-        HBLog( "HBResample: adding %d ms of silence", audio->delay );
-
-        resampleBuffer = HBBufferInit( audio->delay *
-                audio->outSampleRate * 2 * sizeof( float ) / 1000 );
-        memset( resampleBuffer->data, 0, resampleBuffer->size );
-        if( !HBFifoPush( audio->resampleFifo, &resampleBuffer ) )
-        {
-            HBLog( "HBResample: HBFifoPush failed" );
-        }
-
-        audio->delay = 0;
-        return 1;
-    }
-
-    /* Get samples from the decoder */
-    if( !HBFifoGetBytes( audio->rawFifo, (uint8_t *) w->samples,
-                         audio->inSampleRate * 2 * sizeof( float ) / 10,
-                         &position ) )
-    {
-        return 0;
-    }
-
-    /* Init resampled buffer */
-    resampleBuffer = HBBufferInit( audio->outSampleRate * 2 *
-                                   sizeof( float ) / 10 );
-    resampleBuffer->position = position;
-
-    /* Resample */
-    w->data.data_out = resampleBuffer->dataf;
-    if( src_process( w->state, &w->data ) )
-    {
-        HBLog( "HBResample: src_process failed" );
-    }
-    resampleBuffer->size = w->data.output_frames_gen * 2 *
-                           sizeof( float );
-
-    if( w->data.input_frames_used != w->data.input_frames )
-    {
-        /* Here we're basically f*cked */
-        HBLog( "HBResample: ohoh, %d/%d used",
-               w->data.input_frames_used, w->data.input_frames );
-    }
-
-    /* Send resampled data to the encoder */
-    if( !HBFifoPush( audio->resampleFifo, &resampleBuffer ) )
-    {
-        HBLog( "HBResample: HBFifoPush failed" );
-    }
-
-    return 1;
-}
-
diff --git a/core/Scale.c b/core/Scale.c
deleted file mode 100644 (file)
index 2908d64..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/* $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/>.
-   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;
-    HBTitle            * title;
-
-    HBBuffer           * deintBuffer;
-    ImgReSampleContext * context;
-    AVPicture            rawPicture;
-    AVPicture            deintPicture;
-    AVPicture            scaledPicture;
-};
-
-/* Local prototypes */
-static int ScaleWork( HBWork * );
-
-HBWork * HBScaleInit( HBHandle * handle, HBTitle * title )
-{
-    HBWork * w;
-    if( !( w = malloc( sizeof( HBWork ) ) ) )
-    {
-        HBLog( "HBScaleInit: malloc() failed, gonna crash" );
-        return NULL;
-    }
-
-    w->name = strdup( "Scale" );
-    w->work = ScaleWork;
-
-    w->handle = handle;
-    w->title  = title;
-
-    /* Allocate a constant buffer used for deinterlacing */
-    w->deintBuffer = HBBufferInit( 3 * title->inWidth *
-                                   title->inHeight / 2 );
-
-    avpicture_fill( &w->deintPicture, w->deintBuffer->data,
-                    PIX_FMT_YUV420P, title->inWidth, title->inHeight );
-
-    /* Init libavcodec */
-    w->context =
-        img_resample_full_init( title->outWidth, title->outHeight,
-                                title->inWidth,  title->inHeight,
-                                title->topCrop,  title->bottomCrop,
-                                title->leftCrop, title->rightCrop );
-
-    return w;
-}
-
-void HBScaleClose( HBWork ** _w )
-{
-    HBWork * w = *_w;
-
-    img_resample_close( w->context );
-    HBBufferClose( &w->deintBuffer );
-    free( w->name );
-    free( w );
-    *_w = NULL;
-}
-
-static int ScaleWork( HBWork * w )
-{
-    HBTitle  * title = w->title;
-    HBBuffer * rawBuffer;
-    HBBuffer * scaledBuffer;
-    HBBuffer * tmpBuffer;
-
-    if( HBFifoIsHalfFull( title->scaledFifo ) )
-    {
-        return 0;
-    }
-
-    /* Get a new raw picture */
-    if( !( rawBuffer = HBFifoPop( title->rawFifo ) ) )
-    {
-        return 0;
-    }
-
-    /* Allocate new buffer for the scaled picture */
-    scaledBuffer = HBBufferInit( 3 * title->outWidth *
-                                 title->outHeight / 2 );
-    scaledBuffer->position = rawBuffer->position;
-    scaledBuffer->pass     = rawBuffer->pass;
-
-    /* libavcodec stuff */
-    avpicture_fill( &w->rawPicture, rawBuffer->data, PIX_FMT_YUV420P,
-                    title->inWidth, title->inHeight );
-    avpicture_fill( &w->scaledPicture, scaledBuffer->data,
-                    PIX_FMT_YUV420P, title->outWidth,
-                    title->outHeight );
-
-    /* Do the job */
-    if( title->deinterlace )
-    {
-        avpicture_deinterlace( &w->deintPicture, &w->rawPicture,
-                               PIX_FMT_YUV420P, title->inWidth,
-                               title->inHeight );
-        img_resample( w->context, &w->scaledPicture,
-                      &w->deintPicture );
-    }
-    else
-    {
-        img_resample( w->context, &w->scaledPicture, &w->rawPicture );
-    }
-
-    if( rawBuffer->repeat )
-    {
-        tmpBuffer = HBBufferInit( scaledBuffer->size );
-        tmpBuffer->position = scaledBuffer->position;
-        tmpBuffer->pass     = scaledBuffer->pass;
-        memcpy( tmpBuffer->data, scaledBuffer->data,
-                scaledBuffer->size );
-
-        if( !HBFifoPush( title->scaledFifo, &tmpBuffer ) )
-        {
-            HBLog( "HBScale: HBFifoPush failed" );
-        }
-    }
-
-    if( !HBFifoPush( title->scaledFifo, &scaledBuffer ) )
-    {
-        HBLog( "HBScale: HBFifoPush failed" );
-    }
-
-    /* Free memory */
-    HBBufferClose( &rawBuffer );
-
-    return 1;
-}
-
diff --git a/core/Scan.c b/core/Scan.c
deleted file mode 100644 (file)
index 9315e59..0000000
+++ /dev/null
@@ -1,597 +0,0 @@
-/* $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/>.
-   It may be used under the terms of the GNU General Public License. */
-
-#include "HBInternal.h"
-#include "Languages.h"
-
-#include "dvdread/ifo_read.h"
-
-#include "mpeg2dec/mpeg2.h"
-
-/* Local prototypes */
-static void      ScanThread( void * );
-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 );
-
-struct HBScan
-{
-    HBHandle     * handle;
-    char         * device;
-    int            title;
-    volatile int   die;
-    HBThread     * thread;
-    HBList       * titleList;
-};
-
-HBScan * HBScanInit( HBHandle * handle, const char * device, int title )
-{
-    HBScan * s;
-    if( !( s = malloc( sizeof( HBScan ) ) ) )
-    {
-        HBLog( "HBScanInit: malloc() failed, gonna crash" );
-        return NULL;
-    }
-
-    s->handle = handle;
-    s->device = strdup( device );
-    s->title  = title;
-    s->die    = 0;
-    s->thread = HBThreadInit( "scan", ScanThread, s,
-                              HB_NORMAL_PRIORITY );
-
-    return s;
-}
-
-void HBScanClose( HBScan ** _s )
-{
-    HBScan * s = *_s;
-
-    s->die = 1;
-    HBThreadClose( &s->thread );
-
-    free( s->device );
-    free( s );
-    *_s = NULL;
-}
-
-static void ScanThread( void * _s )
-{
-    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 );
-
-    reader = DVDOpen( s->device );
-    if( !reader )
-    {
-        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, reader, vmg, i + 1 ) ) )
-        {
-            HBListAdd( titleList, title );
-        }
-        if( s->title || i == vmg->tt_srpt->nr_of_srpts - 1 )
-        {
-            break;
-        }
-        i++;
-    }
-
-    ifoClose( vmg );
-
-    HBLog( "HBScan: closing device %s", s->device );
-    DVDClose( reader );
-
-    if( s->die )
-    {
-        while( ( title = HBListItemAt( titleList, 0 ) ) )
-        {
-            HBListRemove( titleList, title );
-            HBTitleClose( &title );
-        }
-        HBListClose( &titleList );
-        return;
-    }
-
-    if( !HBListCount( titleList ) )
-    {
-        HBListClose( &titleList );
-    }
-    HBScanDone( s->handle, titleList );
-}
-
-
-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;
-    HBTitle      * title2;
-    HBAudio      * audio;
-    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, vmg->tt_srpt->nr_of_srpts );
-
-    title = HBTitleInit( s->device, index );
-
-    /* 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->hours && !title->minutes && title->seconds < 10 )
-    {
-        HBLog( "HBScan: ignoring title %d (too short)", index );
-        HBTitleClose( &title );
-        return NULL;
-    }
-
-    /* Detect languages */
-    audio_nr = vts->vtsi_mat->nr_of_vts_audio_streams;
-
-    for( i = 0; i < audio_nr; i++ )
-    {
-        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;
-        }
-
-        if( !( audio_control & 0x8000 ) )
-        {
-            continue;
-        }
-
-        i_position = ( audio_control & 0x7F00 ) >> 8;
-
-        switch( audio_format )
-        {
-            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;
-        }
-
-        if( !id )
-        {
-            continue;
-        }
-
-        /* Check if we don't already found an track with the same id */
-        audio = NULL;
-        for( j = 0; j < HBListCount( title->audioList ); j++ )
-        {
-            audio = (HBAudio*) HBListItemAt( title->audioList, j );
-            if( id == audio->id )
-            {
-                break;
-            }
-            else
-            {
-                audio = NULL;
-            }
-        }
-
-        if( audio )
-        {
-            HBLog( "HBScan: title %d: discarding duplicate track %x",
-                   index, id );
-            continue;
-        }
-
-        audio = HBAudioInit( id, LanguageForCode( lang_code ), codec );
-        audio->inCodec = codec;
-        HBLog( "HBScan: title %d: new language (%x, %s)", index, id,
-               audio->language );
-        HBListAdd( title->audioList, audio );
-    }
-
-    /* Discard titles with no audio tracks */
-    if( !HBListCount( title->audioList ) )
-    {
-        HBLog( "HBScan: ignoring title %d (no audio track)", index );
-        HBTitleClose( &title );
-        return NULL;
-    }
-
-    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++ )
-    {
-        if( s->die )
-        {
-            break;
-        }
-
-        if( !DecodeFrame( s, dvdFile, title, i ) )
-        {
-            HBLog( "HBScan: ignoring title %d (could not decode)",
-                   index );
-            HBTitleClose( &title );
-            return NULL;
-        }
-    }
-
-    DVDCloseFile( dvdFile );
-
-    /* Handle ratio */
-    if( title->inHeight * title->aspect >
-            title->inWidth * VOUT_ASPECT_FACTOR )
-    {
-        title->outWidthMax  = title->inWidth;
-        title->outHeightMax = MULTIPLE_16( (uint64_t)title->inWidth *
-                               VOUT_ASPECT_FACTOR / title->aspect );
-    }
-    else
-    {
-        title->outWidthMax  = MULTIPLE_16( (uint64_t)title->inHeight *
-                               title->aspect / VOUT_ASPECT_FACTOR );
-        title->outHeightMax = title->inHeight;
-    }
-
-    /* Default picture size */
-    title->outWidth  = title->outWidthMax;
-    title->outHeight = title->outHeightMax;
-
-    return title;
-}
-
-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 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 = 0;
-
-    HBList   * esBufferList = HBListInit();
-    HBBuffer * esBuffer     = NULL;
-
-
-    /* Init libmpeg2 */
-    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->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( ;; )
-    {
-        state = mpeg2_parse( handle );
-
-        if( state == STATE_BUFFER )
-        {
-            /* Free the previous buffer */
-            if( esBuffer )
-            {
-                HBBufferClose( &esBuffer );
-            }
-
-            /* Get a new one */
-            esBuffer = GetBuffer( esBufferList, dvdFile, &pictureStart,
-                                  pictureEnd );
-            if( !esBuffer )
-            {
-                break;
-            }
-
-            /* Feed libmpeg2 */
-            mpeg2_buffer( handle, esBuffer->data,
-                          esBuffer->data + esBuffer->size );
-        }
-        else if( state == STATE_SEQUENCE )
-        {
-            if( !which )
-            {
-                /* Get size & framerate info */
-                title->inWidth     = info->sequence->width;
-                title->inHeight    = info->sequence->height;
-                title->aspect      = (uint64_t)info->sequence->display_width *
-                    info->sequence->pixel_width * VOUT_ASPECT_FACTOR /
-                    ( info->sequence->display_height *
-                      info->sequence->pixel_height );
-                title->rate        = 27000000;
-                title->rateBase    = info->sequence->frame_period;
-
-                title->autoTopCrop    = title->inHeight / 2;
-                title->autoBottomCrop = title->inHeight / 2;
-                title->autoLeftCrop   = title->inWidth / 2;
-                title->autoRightCrop  = title->inWidth / 2;
-            }
-        }
-        else if( ( state == STATE_SLICE || state == STATE_END ) &&
-                 ( info->display_fbuf ) &&
-                 ( info->display_picture->flags & PIC_MASK_CODING_TYPE )
-                     == PIC_FLAG_CODING_TYPE_I )
-        {
-#define Y info->display_fbuf->buf[0]
-#define DARK 64
-            /* Detect black borders */
-            int i, j;
-            for( i = 0; i < title->inWidth; i++ )
-            {
-                for( j = 0; j < title->autoTopCrop; j++ )
-                    if( Y[ j * title->inWidth + i ] > DARK )
-                    {
-                        title->autoTopCrop = j;
-                        break;
-                    }
-                for( j = 0; j < title->autoBottomCrop; j++ )
-                    if( Y[ ( title->inHeight - j - 1 ) *
-                           title->inWidth + i ] > DARK )
-                    {
-                        title->autoBottomCrop = j;
-                        break;
-                    }
-            }
-            for( i = 0; i < title->inHeight; i++ )
-            {
-                for( j = 0; j < title->autoLeftCrop; j++ )
-                    if( Y[ i * title->inWidth + j ] > DARK )
-                    {
-                        title->autoLeftCrop = j;
-                        break;
-                    }
-                for( j = 0; j < title->autoRightCrop; j++ )
-                    if( Y[ i * title->inWidth +
-                            title->inWidth - j - 1 ] > DARK )
-                    {
-                        title->autoRightCrop = j;
-                        break;
-                    }
-            }
-#undef Y
-#undef DARK
-
-            /* Write the raw picture to a file */
-            fwrite( info->display_fbuf->buf[0],
-                    title->inWidth * title->inHeight, 1, file );
-            fwrite( info->display_fbuf->buf[1],
-                    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 )
-        {
-            /* Reset libmpeg2 */
-            mpeg2_close( handle );
-#ifdef HB_NOMMX
-            mpeg2_accel( 0 );
-#endif
-            handle = mpeg2_init();
-        }
-    }
-
-    while( ( esBuffer = (HBBuffer*) HBListItemAt( esBufferList, 0 ) ) )
-    {
-        HBListRemove( esBufferList, esBuffer );
-        HBBufferClose( &esBuffer );
-    }
-    HBListClose( &esBufferList );
-    if( esBuffer ) HBBufferClose( &esBuffer );
-    mpeg2_close( handle );
-    fclose( file );
-
-    return ret;
-}
-
-static char * LanguageForCode( int code )
-{
-    char codeString[2];
-    iso639_lang_t * lang;
-
-    codeString[0] = ( code >> 8 ) & 0xFF;
-    codeString[1] = code & 0xFF;
-
-    for( lang = languages; lang->engName; lang++ )
-    {
-        if( !strncmp( lang->iso639_1, codeString, 2 ) )
-        {
-            if( *lang->nativeName )
-            {
-                return lang->nativeName;
-            }
-
-            return lang->engName;
-        }
-    }
-
-    return "Unknown";
-}
-
diff --git a/core/Thread.c b/core/Thread.c
deleted file mode 100644 (file)
index 9379223..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-/* $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/>.
-   It may be used under the terms of the GNU General Public License. */
-
-#include "Thread.h"
-
-/**********************************************************************
- * HBThread implementation
- **********************************************************************/
-struct HBThread
-{
-    /* User-friendly name */
-    char    * name;
-
-    /* HB_(LOW|NORMAL)_PRIORITY */
-    int       priority;
-
-    /* Thread function and argument */
-    void      (*function) ( void * );
-    void    * arg;
-
-    /* OS-specific thread id */
-#if defined( HB_BEOS )
-    int       thread;
-#elif defined( HB_MACOSX ) || defined( HB_LINUX )
-    pthread_t thread;
-#elif defined( HB_CYGWIN )
-    HANDLE    thread;
-#endif
-};
-
-/* HBThreadInit actually starts this routine because
-   pthread_setschedparam() might fail if called from an external
-   thread (typically, because the thread exited immediatly). This isn't
-   really necessary, but I find it nicer that way */
-static void ThreadFunc( void * _t )
-{
-    HBThread * t = (HBThread*) _t;
-
-#if defined( HB_MACOSX )
-    /* Set the thread priority */
-    struct sched_param param;
-    memset( &param, 0, sizeof( struct sched_param ) );
-    param.sched_priority = t->priority;
-    if( pthread_setschedparam( pthread_self(), SCHED_OTHER, &param ) )
-    {
-        HBLog( "HBThread: couldn't set thread priority" );
-    }
-#endif
-
-    /* Start the real routine */
-    t->function( t->arg );
-}
-
-HBThread * HBThreadInit( char * name, void (* function)(void *),
-                         void * arg, int priority )
-{
-    /* Initializations */
-    HBThread * t;
-    if( !( t = malloc( sizeof( HBThread ) ) ) )
-    {
-        HBLog( "HBThread: malloc() failed, gonna crash" );
-        return NULL;
-    }
-    t->name     = strdup( name );
-    t->priority = priority;
-    t->function = function;
-    t->arg      = arg;
-
-    /* Create and start the thread */
-#if defined( HB_BEOS )
-    t->thread = spawn_thread( (int32 (*)( void * )) ThreadFunc,
-                              name, priority, t );
-    resume_thread( t->thread );
-#elif defined( HB_MACOSX ) || defined( HB_LINUX )
-    pthread_create( &t->thread, NULL,
-                    (void * (*)( void * )) ThreadFunc, t );
-#elif defined( HB_CYGWIN )
-    t->thread = CreateThread( NULL, 0,
-        (LPTHREAD_START_ROUTINE) ThreadFunc, t, 0, NULL );
-#endif
-
-    HBLog( "HBThread: thread %d started (\"%s\")",
-           t->thread, t->name );
-
-    return t;
-}
-
-void HBThreadClose( HBThread ** _t )
-{
-    HBThread * t = *_t;
-
-    /* Join the thread */
-#if defined( HB_BEOS )
-    long exitValue;
-    wait_for_thread( t->thread, &exitValue );
-#elif defined( HB_MACOSX ) || defined( HB_LINUX )
-    pthread_join( t->thread, NULL );
-#elif defined( HB_CYGWIN )
-    WaitForSingleObject( t->thread, INFINITE );
-#endif
-
-    HBLog( "HBThread: thread %d stopped (\"%s\")",
-           t->thread, t->name );
-
-    /* Clean up */
-    free( t->name );
-    free( t );
-    *_t = NULL;
-}
-
-
-/**********************************************************************
- * HBLock implementation
- **********************************************************************/
-HBLock * HBLockInit()
-{
-    HBLock * l;
-    if( !( l = malloc( sizeof( HBLock ) ) ) )
-    {
-        HBLog( "HBLock: malloc() failed, gonna crash" );
-        return NULL;
-    }
-
-#if defined( HB_BEOS )
-    l->sem = create_sem( 1, "sem" );
-#elif defined( HB_MACOSX ) || defined( HB_LINUX )
-    pthread_mutex_init( &l->mutex, NULL );
-#elif defined( HB_CYGWIN )
-    l->mutex = CreateMutex( 0, FALSE, 0 );
-#endif
-
-    return l;
-}
-
-void HBLockClose( HBLock ** _l )
-{
-    HBLock * l = *_l;
-
-#if defined( HB_BEOS )
-    delete_sem( l->sem );
-#elif defined( HB_MACOSX ) || defined( HB_LINUX )
-    pthread_mutex_destroy( &l->mutex );
-#elif defined( HB_CYGWIN )
-    CloseHandle( l->mutex );
-#endif
-    free( l );
-
-    *_l = NULL;
-}
-
-
-/**********************************************************************
- * HBCond implementation
- **********************************************************************/
-HBCond * HBCondInit()
-{
-    HBCond * c = malloc( sizeof( HBCond ) );
-
-#if defined( HB_BEOS )
-    c->thread = -1;
-#elif defined( HB_MACOSX ) || defined( HB_LINUX )
-    pthread_cond_init( &c->cond, NULL );
-#elif defined( HB_CYGWIN )
-    c->event = CreateEvent( NULL, FALSE, FALSE, NULL );
-#endif
-
-    return c;
-}
-
-void HBCondClose( HBCond ** _c )
-{
-    HBCond * c = *_c;
-
-#if defined( HB_BEOS )
-#elif defined( HB_MACOSX ) || defined( HB_LINUX )
-    pthread_cond_destroy( &c->cond );
-#elif defined( HB_CYGWIN )
-    CloseHandle( c->event );
-#endif
-    free( c );
-
-    *_c = NULL;
-}
-
diff --git a/core/Thread.h b/core/Thread.h
deleted file mode 100644 (file)
index bf34321..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/* $Id: Thread.h,v 1.10 2004/03/16 16:14:03 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_THREAD_H
-#define HB_THREAD_H
-
-/* System headers */
-#if defined( HB_BEOS )
-#  include <OS.h>
-#elif defined( HB_MACOSX ) || defined( HB_LINUX )
-#  include <pthread.h>
-#elif defined( HB_CYGWIN )
-#  include <windows.h>
-#endif
-
-#include "Utils.h"
-
-/* Thread priorities */
-#if defined( HB_BEOS )
-#  define HB_LOW_PRIORITY    5
-#  define HB_NORMAL_PRIORITY 10
-#elif defined( HB_MACOSX )
-#  define HB_LOW_PRIORITY    0
-#  define HB_NORMAL_PRIORITY 31
-#elif defined( HB_LINUX ) || defined( HB_CYGWIN )
-/* Actually unused */
-#  define HB_LOW_PRIORITY    0
-#  define HB_NORMAL_PRIORITY 0
-#endif
-
-/**********************************************************************
- * HBThread/HBLock/HBCond declarations
- **********************************************************************/
-HBThread *           HBThreadInit( char * name,
-                                   void (* function)(void *),
-                                   void * arg, int priority );
-void                 HBThreadClose( HBThread ** );
-
-HBLock             * HBLockInit();
-static inline void   HBLockLock( HBLock * );
-static inline void   HBLockUnlock( HBLock * );
-void                 HBLockClose( HBLock ** );
-
-HBCond             * HBCondInit();
-static inline void   HBCondWait( HBCond *, HBLock * );
-static inline void   HBCondSignal( HBCond * );
-void                 HBCondClose( HBCond ** );
-
-
-/**********************************************************************
- * HBLock implementation (inline functions)
- **********************************************************************/
-struct HBLock
-{
-#if defined( HB_BEOS )
-    sem_id          sem;
-#elif defined( HB_MACOSX ) || defined( HB_LINUX )
-    pthread_mutex_t mutex;
-#elif defined( HB_CYGWIN )
-    HANDLE          mutex;
-#endif
-};
-
-static inline void HBLockLock( HBLock * l )
-{
-#if defined( HB_BEOS )
-    acquire_sem( l->sem );
-#elif defined( HB_MACOSX ) || defined( HB_LINUX )
-    pthread_mutex_lock( &l->mutex );
-#elif defined( HB_CYGWIN )
-    WaitForSingleObject( l->mutex, INFINITE );
-#endif
-}
-
-static inline void HBLockUnlock( HBLock * l )
-{
-#if defined( HB_BEOS )
-    release_sem( l->sem );
-#elif defined( HB_MACOSX ) || defined( HB_LINUX )
-    pthread_mutex_unlock( &l->mutex );
-#elif defined( HB_CYGWIN )
-    ReleaseMutex( l->mutex );
-#endif
-}
-
-
-/**********************************************************************
- * HBCond implementation (inline functions)
- **********************************************************************/
-struct HBCond
-{
-#if defined( HB_BEOS )
-    int                 thread;
-#elif defined( HB_MACOSX ) || defined( HB_LINUX )
-    pthread_cond_t      cond;
-#elif defined( HB_CYGWIN )
-    HANDLE              event;
-#endif
-
-};
-
-static inline void HBCondWait( HBCond * c, HBLock * lock )
-{
-#if defined( HB_BEOS )
-    c->thread = find_thread( NULL );
-    release_sem( lock->sem );
-    suspend_thread( c->thread );
-    acquire_sem( lock->sem );
-    c->thread = -1;
-#elif defined( HB_MACOSX ) || defined( HB_LINUX )
-    pthread_cond_wait( &c->cond, &lock->mutex );
-#elif defined( HB_CYGWIN )
-    SignalObjectAndWait( lock->mutex, c->event, INFINITE, FALSE );
-    WaitForSingleObject( lock->mutex, INFINITE );
-#endif
-}
-
-static inline void HBCondSignal( HBCond * c )
-{
-#if defined( HB_BEOS )
-    while( c->thread != -1 )
-    {
-        thread_info info;
-        get_thread_info( c->thread, &info );
-        if( info.state == B_THREAD_SUSPENDED )
-        {
-            resume_thread( c->thread );
-            break;
-        }
-        /* In case HBCondSignal is called between HBCondWait's
-           release_sem() and suspend_thread() lines, wait a bit */
-        snooze( 5000 );
-    }
-#elif defined( HB_MACOSX ) || defined( HB_LINUX )
-    pthread_cond_signal( &c->cond );
-#elif defined( HB_CYGWIN )
-    PulseEvent( c->event );
-#endif
-}
-
-#endif
diff --git a/core/Utils.c b/core/Utils.c
deleted file mode 100644 (file)
index 45ebf7b..0000000
+++ /dev/null
@@ -1,379 +0,0 @@
-/* $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/>.
-   It may be used under the terms of the GNU General Public License. */
-
-#include <stdarg.h>
-#include <time.h>
-#include <sys/time.h>
-#ifdef HB_CYGWIN
-#  include <windows.h>
-#endif
-
-#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;
-    int     allocItems;
-    int     nbItems;
-};
-
-void HBSnooze( int time )
-{
-#if defined( HB_BEOS )
-    snooze( time );
-#elif defined( HB_MACOSX ) || defined( HB_LINUX )
-    usleep( time );
-#elif defined( HB_CYGWIN )
-    Sleep( time / 1000 );
-#endif
-}
-
-void HBLog( char * log, ... )
-{
-    char        string[80];
-    time_t      _now;
-    struct tm * now;
-    va_list     args;
-
-    if( !getenv( "HB_DEBUG" ) )
-    {
-        return;
-    }
-
-    /* Show the time */
-    _now = time( NULL );
-    now  = localtime( &_now );
-    sprintf( string, "[%02d:%02d:%02d] ",
-             now->tm_hour, now->tm_min, now->tm_sec );
-
-    /* Convert the message to a string */
-    va_start( args, log );
-    vsnprintf( string + 11, 67, log, args );
-    va_end( args );
-
-    /* Add the end of line */
-    strcat( string, "\n" );
-
-    /* Print it */
-    fprintf( stderr, "%s", string );
-}
-
-uint64_t HBGetDate()
-{
-#ifndef HB_CYGWIN
-    struct timeval tv;
-    gettimeofday( &tv, NULL );
-    return( (uint64_t) tv.tv_sec * 1000000 + (uint64_t) tv.tv_usec );
-#else
-    return( 1000 * GetTickCount() );
-#endif
-}
-
-/* Basic MPEG demuxer - only works with DVDs ! (2048 bytes packets) */
-int HBPStoES( HBBuffer ** _psBuffer, HBList * esBufferList )
-{
-    HBBuffer * psBuffer = *_psBuffer;
-    HBBuffer * esBuffer;
-    int        pos = 0;
-
-#define d (psBuffer->data)
-
-    /* pack_header */
-    if( d[pos] != 0 || d[pos+1] != 0 ||
-        d[pos+2] != 0x1 || d[pos+3] != 0xBA )
-    {
-        HBLog( "HBPStoES: not a PS packet (%02x%02x%02x%02x)",
-             d[pos], d[pos+1], d[pos+2], d[pos+3] );
-        HBBufferClose( _psBuffer );
-        return 0;
-    }
-    pos += 4;                    /* pack_start_code */
-    pos += 9;                    /* pack_header */
-    pos += 1 + ( d[pos] & 0x7 ); /* stuffing bytes */
-
-    /* system_header */
-    if( d[pos] == 0 && d[pos+1] == 0 &&
-        d[pos+2] == 0x1 && d[pos+3] == 0xBB )
-    {
-        int header_length;
-
-        pos           += 4; /* system_header_start_code */
-        header_length  = ( d[pos] << 8 ) + d[pos+1];
-        pos           += 2 + header_length;
-    }
-
-    /* PES */
-    while( pos + 6 < psBuffer->size &&
-           d[pos] == 0 && d[pos+1] == 0 && d[pos+2] == 0x1 )
-    {
-        int      streamId;
-        int      PES_packet_length;
-        int      PES_packet_end;
-        int      PES_header_d_length;
-        int      PES_header_end;
-        int      hasPTS;
-        uint64_t PTS = 0;
-
-        pos               += 3;               /* packet_start_code_prefix */
-        streamId           = d[pos];
-        pos               += 1;
-
-        PES_packet_length  = ( d[pos] << 8 ) + d[pos+1];
-        pos               += 2;               /* PES_packet_length */
-        PES_packet_end     = pos + PES_packet_length;
-
-        if( streamId != 0xE0 && streamId != 0xBD &&
-            ( streamId & 0xC0 ) != 0xC0  )
-        {
-            /* Not interesting */
-            pos = PES_packet_end;
-            continue;
-        }
-
-        hasPTS             = ( ( d[pos+1] >> 6 ) & 0x2 ) ? 1 : 0;
-        pos               += 2;               /* Required headers */
-
-        PES_header_d_length  = d[pos];
-        pos                    += 1;
-        PES_header_end          = pos + PES_header_d_length;
-
-        if( hasPTS )
-        {
-            PTS = ( ( ( (uint64_t) d[pos] >> 1 ) & 0x7 ) << 30 ) +
-                  ( d[pos+1] << 22 ) +
-                  ( ( d[pos+2] >> 1 ) << 15 ) +
-                  ( d[pos+3] << 7 ) +
-                  ( d[pos+4] >> 1 );
-        }
-
-        pos = PES_header_end;
-
-        if( streamId == 0xBD )
-        {
-            streamId |= ( d[pos] << 8 );
-            if( ( streamId & 0xF0FF ) == 0x80BD )
-            {
-                /* A52 */
-                pos += 4;
-            }
-            else if( ( streamId & 0xF0FF ) == 0xA0BD )
-            {
-                /* LPCM */
-                pos += 1;
-            }
-        }
-
-        /* Sanity check */
-        if( pos >= PES_packet_end )
-        {
-            pos = PES_packet_end;
-            continue;
-        }
-
-        /* Here we hit we ES payload */
-        esBuffer = HBBufferInit( PES_packet_end - pos );
-
-        esBuffer->position = psBuffer->position;
-        esBuffer->pass     = psBuffer->pass;
-        esBuffer->streamId = streamId;
-        esBuffer->pts      = PTS;
-        memcpy( esBuffer->data, d + pos,
-                PES_packet_end - pos );
-
-        HBListAdd( esBufferList, esBuffer );
-
-        pos = PES_packet_end;
-    }
-
-#undef d
-
-    HBBufferClose( _psBuffer );
-
-    return 1;
-}
-
-#define HBLIST_DEFAULT_SIZE 20
-HBList * HBListInit()
-{
-    HBList * l;
-    if( !( l = malloc( sizeof( HBList ) ) ) )
-    {
-        HBLog( "HBListInit: malloc() failed, gonna crash" );
-        return NULL;
-    }
-
-    if( !( l->items = malloc( HBLIST_DEFAULT_SIZE * sizeof( void* ) ) ) )
-    {
-        HBLog( "HBListInit: malloc() failed, gonna crash" );
-        free( l );
-        return NULL;
-    }
-
-    l->allocItems = HBLIST_DEFAULT_SIZE;
-    l->nbItems    = 0;
-
-    return l;
-}
-
-int HBListCount( HBList * l )
-{
-    return l->nbItems;
-}
-
-void HBListAdd( HBList * l, void * item )
-{
-    if( !item )
-    {
-        return;
-    }
-
-    if( l->nbItems == l->allocItems )
-    {
-        l->allocItems += HBLIST_DEFAULT_SIZE;
-        l->items       = realloc( l->items,
-                                  l->allocItems * sizeof( void* ) );
-    }
-
-    l->items[l->nbItems] = item;
-    (l->nbItems)++;
-}
-
-void HBListRemove( HBList * l, void * item )
-{
-    int i;
-
-    if( !item || !l->nbItems  )
-    {
-        return;
-    }
-
-    for( i = 0; i < l->nbItems; i++ )
-    {
-        if( l->items[i] == item )
-        {
-            break;
-        }
-    }
-
-    if( l->items[i] != item )
-    {
-        HBLog( "HBListRemove: specified item is not in the list" );
-        return;
-    }
-
-    for( ; i < l->nbItems - 1; i++ )
-    {
-        l->items[i] = l->items[i+1];
-    }
-
-    (l->nbItems)--;
-}
-
-void * HBListItemAt( HBList * l, int index )
-{
-    if( index < 0 || index >= l->nbItems )
-    {
-        return NULL;
-    }
-
-    return l->items[index];
-}
-
-void HBListClose( HBList ** _l )
-{
-    HBList * l = *_l;
-
-    free( l->items );
-    free( l );
-
-    *_l = NULL;
-}
-
-HBTitle * HBTitleInit( char * device, int index )
-{
-    HBTitle * t;
-
-    if( !( t = calloc( sizeof( HBTitle ), 1 ) ) )
-    {
-        HBLog( "HBTitleInit: calloc() failed, gonna crash" );
-        return NULL;
-    }
-
-    t->device       = strdup( device );
-    t->title        = index;
-
-    t->codec        = HB_CODEC_FFMPEG;
-    t->mux          = HB_MUX_MP4;
-
-    t->audioList    = HBListInit();
-    t->ripAudioList = HBListInit();
-
-    t->start        = -1;
-
-    return t;
-}
-
-void HBTitleClose( HBTitle ** _t )
-{
-    HBTitle * t = *_t;
-
-    HBAudio * audio;
-    while( ( audio = HBListItemAt( t->audioList, 0 ) ) )
-    {
-        HBListRemove( t->audioList, audio );
-        HBAudioClose( &audio );
-    }
-    HBListClose( &t->audioList );
-    HBListClose( &t->ripAudioList );
-
-    if( t->file ) free( t->file );
-    free( t->device );
-    free( t );
-
-    *_t = NULL;
-}
-
-HBAudio * HBAudioInit( int id, char * language, int codec )
-{
-    HBAudio * a;
-    if( !( a = calloc( sizeof( HBAudio ), 1 ) ) )
-    {
-        HBLog( "HBAudioInit: calloc() failed, gonna crash" );
-        return NULL;
-    }
-
-    a->id            = id;
-    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 );
-    *_a = NULL;
-}
-
diff --git a/core/Utils.h b/core/Utils.h
deleted file mode 100644 (file)
index fce20e5..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-/* $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/>.
-   It may be used under the terms of the GNU General Public License. */
-
-#ifndef HB_UTILS_H
-#define HB_UTILS_H
-
-/* Standard headers */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <inttypes.h>
-typedef uint8_t byte_t;
-#ifdef HB_BEOS
-#  include <OS.h>
-#endif
-
-/* Handy macros */
-#ifndef MIN
-#define MIN( a, b ) ( ( (a) > (b) ) ? (b) : (a) )
-#endif
-#ifndef MAX
-#define MAX( a, b ) ( ( (a) > (b) ) ? (a) : (b) )
-#endif
-#ifndef EVEN
-#define EVEN( a ) ( ( (a) & 0x1 ) ? ( (a) + 1 ) : (a) )
-#endif
-#ifndef MULTIPLE_16
-#define MULTIPLE_16( a ) ( 16 * ( ( (a) + 8 ) / 16 ) )
-#endif
-#ifndef VOUT_ASPECT_FACTOR
-#define VOUT_ASPECT_FACTOR 432000
-#endif
-
-typedef struct HBHandle     HBHandle;
-
-/* Utils */
-typedef struct HBAudio      HBAudio;
-typedef struct HBBuffer     HBBuffer;
-typedef struct HBCond       HBCond;
-typedef struct HBFifo       HBFifo;
-typedef struct HBList       HBList;
-typedef struct HBLock       HBLock;
-typedef struct HBTitle      HBTitle;
-typedef struct HBThread     HBThread;
-
-/* (De)Muxers */
-typedef struct HBDVDRead    HBDVDRead;
-typedef struct HBScan       HBScan;
-
-typedef struct HBWork       HBWork;
-typedef struct HBMuxThread  HBMuxThread;
-typedef struct HBWorkThread HBWorkThread;
-
-/* Misc functions which may be used from anywhere */
-void     HBSnooze( int time );
-void     HBLog( char * log, ... );
-uint64_t HBGetDate();
-int      HBPStoES( HBBuffer ** psBuffer, HBList * esBufferList );
-
-/* HBList functions */
-HBList * HBListInit();
-int      HBListCount( HBList * );
-void     HBListAdd( HBList *, void * item );
-void     HBListRemove( HBList *, void * item );
-void   * HBListItemAt( HBList *, int index );
-void     HBListClose( HBList ** );
-
-/* HBTitle function */
-HBTitle * HBTitleInit();
-void      HBTitleClose( HBTitle ** );
-
-/* HBAudio functions */
-HBAudio * HBAudioInit( int id, char * language, int codec );
-void      HBAudioClose( HBAudio ** );
-
-#define HB_SUCCESS          0x00
-#define HB_CANCELED         0x01
-#define HB_ERROR_A52_SYNC   0x02
-#define HB_ERROR_AVI_WRITE  0x04
-#define HB_ERROR_DVD_OPEN   0x08
-#define HB_ERROR_DVD_READ   0x10
-#define HB_ERROR_MP3_INIT   0x20
-#define HB_ERROR_MP3_ENCODE 0x40
-#define HB_ERROR_MPEG4_INIT 0x80
-
-/* Possible codecs */
-#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
-#define HB_MUX_MP4 0x01
-#define HB_MUX_OGM 0x02
-
-struct HBTitle
-{
-    /* DVD info */
-    char * device;
-    int    title;
-    int    vts_id;
-    int    startBlock;
-    int    endBlock;
-    int    hours;
-    int    minutes;
-    int    seconds;
-
-    /* Audio infos */
-    HBList * audioList;
-    HBList * ripAudioList;
-
-    /* See DVDRead.c */
-    int64_t start;
-
-    /* Video input */
-    int inWidth;
-    int inHeight;
-    int aspect;
-    int rate;
-    int rateBase;
-
-    /* Video output */
-    int outWidth;
-    int outHeight;
-    int outWidthMax;
-    int outHeightMax;
-    int topCrop;
-    int bottomCrop;
-    int leftCrop;
-    int rightCrop;
-    int deinterlace;
-    int autoTopCrop;
-    int autoBottomCrop;
-    int autoLeftCrop;
-    int autoRightCrop;
-
-    /* Encoder settings */
-    int codec;
-    int bitrate;
-    int twoPass;
-
-    /* Muxer settings */
-    char * file;
-    int    mux;
-
-    /* Muxer data */
-    void * muxData;
-
-    /* MP4 muxer specific */
-    uint8_t * esConfig;
-    int       esConfigLength;
-
-    /* Fifos */
-    HBFifo  * inFifo;
-    HBFifo  * rawFifo;
-    HBFifo  * scaledFifo;
-    HBFifo  * outFifo;
-
-    /* Threads */
-    HBDVDRead    * dvdRead;
-    HBWorkThread * workThreads[8];
-    HBMuxThread  * muxThread;
-
-    /* Work objects */
-    HBWork * decoder;
-    HBWork * scale;
-    HBWork * encoder;
-};
-
-struct HBAudio
-{
-    /* Ident */
-    uint32_t    id;
-    char        language[512];
-
-    /* Settings */
-    int         inCodec;
-    int         outCodec;
-    int         inSampleRate;
-    int         outSampleRate;
-    int         inBitrate;
-    int         outBitrate;
-
-    int         delay; /* in ms */
-
-    /* See DVDRead.c */
-    int64_t     start;
-
-    /* MPEG-4 config, used in the MP4 muxer */
-    uint8_t       * esConfig;
-    unsigned long   esConfigLength;
-
-    /* Muxer data */
-    void * muxData;
-
-    /* Fifos */
-    HBFifo    * inFifo;
-    HBFifo    * rawFifo;
-    HBFifo    * resampleFifo;
-    HBFifo    * outFifo;
-
-    /* Work objects */
-    HBWork    * decoder;
-    HBWork    * resample;
-    HBWork    * encoder;
-};
-
-#endif
diff --git a/core/VorbisEnc.c b/core/VorbisEnc.c
deleted file mode 100644 (file)
index 8b7b10f..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-/* $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/>.
-   It may be used under the terms of the GNU General Public License. */
-
-#include "HBInternal.h"
-
-/* libvorbis */
-#include <vorbis/vorbisenc.h>
-
-#define OGGVORBIS_FRAME_SIZE 1024
-
-struct HBWork
-{
-    HB_WORK_COMMON_MEMBERS
-
-    HBHandle          * handle;
-    HBAudio           * audio;
-
-    int                inited;
-    vorbis_info        vi;
-    vorbis_comment     vc;
-    vorbis_dsp_state   vd;
-    vorbis_block       vb;
-    float position;
-
-    int32_t           * inputBuffer;
-
-};
-
-/* Local prototypes */
-static int VorbisEncWork( HBWork * );
-
-HBWork * HBVorbisEncInit ( HBHandle * handle, HBAudio * audio )
-{
-    HBWork * w = calloc( sizeof( HBWork ), 1 );
-
-    w->name = strdup( "VorbisEnc" );
-    w->work = VorbisEncWork;
-
-    w->handle = handle;
-    w->audio  = audio;
-
-    w->inputBuffer = malloc( 2 * OGGVORBIS_FRAME_SIZE * sizeof( int32_t ) );
-
-    return w;
-}
-
-void HBVorbisEncClose( HBWork ** _w )
-{
-    HBWork * w = *_w;
-
-    if( w->inited )
-    {
-        vorbis_block_clear( &w->vb );
-        vorbis_dsp_clear( &w->vd );
-        vorbis_comment_clear( &w->vc );
-        vorbis_info_clear( &w->vi );
-    }
-
-    free( w->name );
-    free( w );
-
-    *_w = NULL;
-}
-
-static HBBuffer *PacketToBuffer( ogg_packet *op )
-{
-    HBBuffer *buf = HBBufferInit( sizeof( ogg_packet ) + op->bytes );
-
-    memcpy( buf->data, op, sizeof( ogg_packet ) );
-    memcpy( buf->data + sizeof( ogg_packet ), op->packet, op->bytes );
-
-    return buf;
-}
-
-static int VorbisEncWork( HBWork * w )
-{
-    HBAudio     * audio = w->audio;
-
-    float **buffer;
-    int i;
-    float inputBuffer[OGGVORBIS_FRAME_SIZE * 2];
-    HBBuffer * vorbisBuffer;
-
-    if( HBFifoIsHalfFull( audio->outFifo ) )
-    {
-        return 0;
-    }
-
-    if( !w->inited )
-    {
-        ogg_packet header[3];
-
-        if( !HBFifoSize( audio->resampleFifo ) )
-        {
-            return 0;
-        }
-
-        w->inited = 1;
-
-        /* init */
-        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( "HBVorbisEnc: vorbis_encode_setup_managed failed" );
-            return 0;
-        }
-        /* add a comment */
-        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( &w->vd, &w->vi);
-        vorbis_block_init( &w->vd, &w->vb);
-
-
-        /* get the 3 headers */
-        vorbis_analysis_headerout( &w->vd, &w->vc,
-                                   &header[0], &header[1], &header[2] );
-        for( i = 0; i < 3; i++ )
-        {
-            vorbisBuffer = PacketToBuffer( &header[i] );
-            if( !HBFifoPush( audio->outFifo, &vorbisBuffer ) )
-            {
-                HBLog( "HBVorbisEnc: HBFifoPush failed" );
-            }
-        }
-    }
-
-    /* Try to extract more data */
-    if( vorbis_analysis_blockout( &w->vd, &w->vb ) == 1 )
-    {
-        ogg_packet op;
-
-        vorbis_analysis( &w->vb, NULL );
-        vorbis_bitrate_addblock( &w->vb );
-
-        if( vorbis_bitrate_flushpacket( &w->vd, &op ) )
-        {
-            vorbisBuffer = PacketToBuffer( &op );
-            vorbisBuffer->position = w->position;
-            if( !HBFifoPush( audio->outFifo, &vorbisBuffer ) )
-            {
-                HBLog( "HBVorbisEnc: HBFifoPush failed" );
-            }
-            return 1;
-        }
-    }
-
-    if( !HBFifoGetBytes( audio->resampleFifo, (uint8_t*) inputBuffer,
-                         OGGVORBIS_FRAME_SIZE * 2 * sizeof( float ),
-                         &w->position ) )
-    {
-        return 0;
-    }
-
-    buffer = vorbis_analysis_buffer( &w->vd, OGGVORBIS_FRAME_SIZE );
-    for( i = 0; i < OGGVORBIS_FRAME_SIZE; i++ )
-    {
-        buffer[0][i] = inputBuffer[2*i]   / 32768.f;
-        buffer[1][i] = inputBuffer[2*i+1] / 32768.f;
-    }
-    vorbis_analysis_wrote( &w->vd, OGGVORBIS_FRAME_SIZE );
-
-    return 1;
-}
-
diff --git a/core/Work.c b/core/Work.c
deleted file mode 100644 (file)
index e23af24..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/* $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/>.
-   It may be used under the terms of the GNU General Public License. */
-
-#include "HBInternal.h"
-
-/* Local prototypes */
-static void WorkThread( void * t );
-
-struct HBWork
-{
-    HB_WORK_COMMON_MEMBERS
-};
-
-struct HBWorkThread
-{
-    HBHandle     * handle;
-
-    HBList       * workList;
-    int            firstThread;
-
-    volatile int   die;
-    HBThread     * thread;
-};
-
-HBWorkThread * HBWorkThreadInit( HBHandle * handle, HBTitle * title,
-                                 int firstThread )
-{
-    int i;
-    HBWork  * w;
-    HBAudio * audio;
-
-    HBWorkThread * t;
-    if( !( t = malloc( sizeof( HBWorkThread ) ) ) )
-    {
-        HBLog( "HBWorkThreadInit: malloc() failed, gonna crash" );
-        return NULL;
-    }
-
-    t->handle = handle;
-
-    /* Build a list of work objects. They all include
-       HB_WORK_COMMON_MEMBERS, so we'll be able to do the job without
-       knowing what each one actually does */
-    t->workList = HBListInit();
-    HBListAdd( t->workList, title->decoder );
-    HBListAdd( t->workList, title->scale );
-    HBListAdd( t->workList, title->encoder );
-
-    for( i = 0; i < HBListCount( title->ripAudioList ); i++ )
-    {
-        audio = HBListItemAt( title->ripAudioList, i );
-        HBListAdd( t->workList, audio->decoder );
-        HBListAdd( t->workList, audio->resample );
-        HBListAdd( t->workList, audio->encoder );
-    }
-
-    t->firstThread = firstThread;
-
-    /* Work objects are not thread-safe, so let's init locks so each
-       one can not be called anymore when it's doing something. This
-       is done by the first worker thread (see HBStartRip) */
-    if( t->firstThread )
-    {
-        for( i = 0; i < HBListCount( t->workList ); i++ )
-        {
-            w = (HBWork*) HBListItemAt( t->workList, i );
-            w->lock = HBLockInit();
-            w->used = 0;
-            w->time = 0;
-        }
-    }
-
-    /* Actually launch the thread */
-    t->die    = 0;
-    t->thread = HBThreadInit( "work thread", WorkThread, t,
-                              HB_LOW_PRIORITY );
-
-    return t;
-}
-
-void HBWorkThreadClose( HBWorkThread ** _t )
-{
-    HBWorkThread * t = (*_t);
-    HBWork * w;
-
-    /* Stop the thread */
-    t->die = 1;
-    HBThreadClose( &t->thread );
-
-    /* Destroy locks, show stats */
-    if( t->firstThread )
-    {
-        int i;
-        uint64_t total = 0;
-
-        for( i = 0; i < HBListCount( t->workList ); i++ )
-        {
-            w = (HBWork*) HBListItemAt( t->workList, i );
-            HBLockClose( &w->lock );
-            total += w->time;
-        }
-
-        for( i = 0; i < HBListCount( t->workList ); i++ )
-        {
-            w = (HBWork*) HBListItemAt( t->workList, i );
-            HBLog( "HBWorkThread: %- 9s = %05.2f %%", w->name,
-                   100.0 * w->time / total );
-        }
-
-    }
-
-    /* Free memory */
-    HBListClose( &t->workList );
-    free( t );
-
-    *_t = NULL;
-}
-
-static void WorkThread( void * _t )
-{
-    HBWorkThread * t = (HBWorkThread*) _t;
-    HBWork       * w;
-    int            didSomething, i;
-    uint64_t       date;
-
-    didSomething = 0;
-
-    for( i = 0; !t->die; i++ )
-    {
-        HBCheckPaused( t->handle );
-
-        if( i == HBListCount( t->workList ) )
-        {
-            /* If nothing could be done, wait a bit to prevent a useless
-               CPU-consuming loop */
-            if( !didSomething )
-            {
-                HBSnooze( 5000 );
-            }
-            didSomething = 0;
-            i            = 0;
-        }
-
-        w = (HBWork*) HBListItemAt( t->workList, i );
-
-        /* Check if another thread isn't using this work object */
-        HBLockLock( w->lock );
-        if( w->used )
-        {
-            /* It's in use. Forget about this one and try the next
-               one */
-            HBLockUnlock( w->lock );
-            continue;
-        }
-        /* It's unused, lock it */
-        w->used = 1;
-        HBLockUnlock( w->lock );
-
-        /* Do the job */
-        date = HBGetDate();
-        if( w->work( w ) )
-        {
-            w->time += HBGetDate() - date;
-            didSomething = 1;
-        }
-
-        /* Unlock it */
-        HBLockLock( w->lock );
-        w->used = 0;
-        HBLockUnlock( w->lock );
-    }
-}
-
diff --git a/core/Work.h b/core/Work.h
deleted file mode 100644 (file)
index b764e11..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* $Id: Work.h,v 1.4 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. */
-
-#ifndef HB_WORK_H
-#define HB_WORK_H
-
-#define HB_WORK_COMMON_MEMBERS \
-    char   * name; \
-    HBLock * lock; \
-    int      used; \
-    uint64_t time; \
-    int      (*work) ( HBWork * );
-
-HBWorkThread * HBWorkThreadInit( HBHandle *, HBTitle *,
-                                 int firstThread );
-void           HBWorkThreadClose( HBWorkThread ** );
-
-#endif
diff --git a/core/X264Enc.c b/core/X264Enc.c
deleted file mode 100644 (file)
index be8d767..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-/* $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/>.
-   It may be used under the terms of the GNU General Public License. */
-
-#include "HBInternal.h"
-
-/* x264 */
-#include "x264.h"
-
-struct HBWork
-{
-    HB_WORK_COMMON_MEMBERS
-
-    HBHandle    *handle;
-    HBTitle     *title;
-
-    x264_t         *h;
-    x264_picture_t picture;
-};
-
-/* Local prototypes */
-static int HBX264EncWork( HBWork * );
-
-HBWork * HBX264EncInit( HBHandle * handle, HBTitle * title )
-{
-    HBWork * w = malloc( sizeof( HBWork ) );
-
-    if( w )
-    {
-        x264_param_t param;
-
-        w->name     = strdup( "X264Enc" );
-        w->work     = HBX264EncWork;
-
-        w->handle   = handle;
-        w->title    = title;
-
-        x264_param_default( &param );
-
-        param.i_width = title->outWidth;
-        param.i_height= title->outHeight;
-        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( &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 w;
-}
-
-void HBX264EncClose( HBWork ** _w )
-{
-    HBWork * w = *_w;
-    x264_encoder_close( w->h );
-    free( w->name );
-    free( w );
-    *_w = NULL;
-}
-
-/* TODO trash buffer->pass == 1
- * return 0 ->rien fait
- *        1 -> sinon
- */
-static int HBX264EncWork( HBWork * w )
-{
-    HBTitle    * title = w->title;
-
-    HBBuffer * frame, * buffer;
-
-    x264_nal_t *nal;
-    int        i_nal;
-    int        i;
-
-    if( HBFifoIsHalfFull( title->outFifo ) )
-    {
-        return 0;
-    }
-
-    if( !( frame = HBFifoPop( title->scaledFifo ) ) )
-    {
-        return 0;
-    }
-
-    if( frame->pass == 1 )
-    {
-        /* Trash all first pass buffer */
-        HBBufferClose( &frame );
-        return 1;
-    }
-
-    w->picture.i_stride[0] = title->outWidth;
-    w->picture.i_stride[1] = title->outWidth/2;
-    w->picture.i_stride[2] = title->outWidth/2;
-
-    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( w->h, &nal, &i_nal, &w->picture );
-
-    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 = buffer->alloc - buffer->size;
-        int i_size;
-
-        i_size = x264_nal_encode( &buffer->data[buffer->size],
-                                  &i_data, 1, &nal[i] );
-        if( i_size <= 0 )
-        {
-            fprintf( stderr, "#################### error" );
-        }
-
-        buffer->size += i_size;
-
-        if( nal[i].i_ref_idc == NAL_PRIORITY_HIGH ||
-            nal[i].i_ref_idc == NAL_PRIORITY_HIGHEST )
-        {
-            buffer->keyFrame = 1;
-        }
-    }
-
-    /* Inform the GUI about the current position */
-    HBPosition( w->handle, frame->position );
-
-    HBBufferClose( &frame );
-
-    if( !HBFifoPush( title->outFifo, &buffer ) )
-    {
-        HBLog( "HBX264Enc: HBFifoPush failed" );
-    }
-
-    return 1;
-}
diff --git a/core/XvidEnc.c b/core/XvidEnc.c
deleted file mode 100644 (file)
index 4c06da6..0000000
+++ /dev/null
@@ -1,247 +0,0 @@
-/* $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/>.
-   It may be used under the terms of the GNU General Public License. */
-
-#include "HBInternal.h"
-
-#include "xvid.h"
-
-struct HBWork
-{
-    HB_WORK_COMMON_MEMBERS
-
-    HBHandle * handle;
-    HBTitle  * title;
-
-    char             file[1024];
-    void           * xvid;
-    xvid_enc_frame_t frame;
-    int              pass;
-};
-
-/* Local prototypes */
-static int XvidEncWork( HBWork * );
-
-HBWork * HBXvidEncInit( HBHandle * handle, HBTitle * title )
-{
-    HBWork * w;
-    if( !( w = malloc( sizeof( HBWork ) ) ) )
-    {
-        HBLog( "HBXvidEncInit: malloc() failed, gonna crash" );
-        return NULL;
-    }
-
-    w->name = strdup( "XvidEnc" );
-    w->work = XvidEncWork;
-
-    w->handle = handle;
-    w->title  = title;
-
-    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
-
-    w->xvid        = NULL;
-    w->pass        = 42;
-
-    return w;
-}
-
-void HBXvidEncClose( HBWork ** _w )
-{
-    HBWork * w = *_w;
-
-    if( w->xvid )
-    {
-        HBLog( "HBXvidEnc: closing libxvidcore (pass %d)",
-                w->pass );
-        xvid_encore( w->xvid, XVID_ENC_DESTROY, NULL, NULL);
-    }
-    if( w->title->esConfig )
-    {
-        free( w->title->esConfig );
-        w->title->esConfig       = NULL;
-        w->title->esConfigLength = 0;
-    }
-
-    free( w->name );
-    free( w );
-    *_w = NULL;
-}
-
-static int XvidEncWork( HBWork * w )
-{
-    HBTitle        * title = w->title;
-    HBBuffer       * scaledBuffer;
-    HBBuffer       * mpeg4Buffer;
-
-    if( HBFifoIsHalfFull( title->outFifo ) )
-    {
-        return 0;
-    }
-
-    if( !( scaledBuffer = HBFifoPop( title->scaledFifo ) ) )
-    {
-        return 0;
-    }
-
-    /* Init or re-init if needed */
-    if( scaledBuffer->pass != w->pass )
-    {
-        xvid_gbl_init_t xvid_gbl_init;
-        xvid_enc_create_t xvid_enc_create;
-        xvid_plugin_single_t single;
-        xvid_plugin_2pass1_t rc2pass1;
-        xvid_plugin_2pass2_t rc2pass2;
-        xvid_enc_plugin_t plugins[7];
-
-        if( w->xvid )
-        {
-            HBLog( "HBXvidEnc: closing libxvidcore (pass %d)",
-                    w->pass );
-            xvid_encore( w->xvid, XVID_ENC_DESTROY, NULL, NULL);
-        }
-
-        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;
-        xvid_global( NULL, XVID_GBL_INIT, &xvid_gbl_init, NULL );
-
-        memset(&xvid_enc_create, 0, sizeof(xvid_enc_create));
-        xvid_enc_create.version = XVID_VERSION;
-        xvid_enc_create.width = title->outWidth;
-        xvid_enc_create.height = title->outHeight;
-        xvid_enc_create.zones = NULL;
-        xvid_enc_create.num_zones = 0;
-        xvid_enc_create.plugins = plugins;
-        xvid_enc_create.num_plugins = 0;
-
-        if( !w->pass )
-        {
-            memset( &single, 0, sizeof( single ) );
-            single.version = XVID_VERSION;
-            single.bitrate = 1024 * title->bitrate;
-            plugins[xvid_enc_create.num_plugins].func = xvid_plugin_single;
-            plugins[xvid_enc_create.num_plugins].param = &single;
-            xvid_enc_create.num_plugins++;
-        }
-        else if( w->pass == 1 )
-        {
-            memset( &rc2pass1, 0, sizeof( rc2pass1 ) );
-            rc2pass1.version = XVID_VERSION;
-            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( w->pass == 2 )
-        {
-            memset(&rc2pass2, 0, sizeof(xvid_plugin_2pass2_t));
-            rc2pass2.version = XVID_VERSION;
-            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;
-            xvid_enc_create.num_plugins++;
-        }
-
-        xvid_enc_create.num_threads = 0;
-        xvid_enc_create.fincr = title->rateBase;
-        xvid_enc_create.fbase = title->rate;
-        xvid_enc_create.max_key_interval = 10 * title->rate / title->rateBase;
-        xvid_enc_create.max_bframes = 0;
-        xvid_enc_create.bquant_ratio = 150;
-        xvid_enc_create.bquant_offset = 100;
-        xvid_enc_create.frame_drop_ratio = 0;
-        xvid_enc_create.global = 0;
-
-        xvid_encore( NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL );
-        w->xvid = xvid_enc_create.handle;
-    }
-
-    mpeg4Buffer = HBBufferInit( title->outWidth *
-                                title->outHeight * 3 / 2 );
-    mpeg4Buffer->position = scaledBuffer->position;
-
-    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;
-    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;
-    w->frame.quant_intra_matrix = NULL;
-    w->frame.quant_inter_matrix = NULL;
-
-    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( w->handle, scaledBuffer->position );
-
-    HBBufferClose( &scaledBuffer );
-
-    if( w->pass == 1 )
-    {
-        HBBufferClose( &mpeg4Buffer );
-        return 1;
-    }
-
-    if( !title->esConfig )
-    {
-        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 )
-            {
-                break;
-            }
-        }
-        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 )
-            {
-                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 );
-    }
-
-    if( !HBFifoPush( title->outFifo, &mpeg4Buffer ) )
-    {
-        HBLog( "HBXvidEnc: HBFifoPush failed" );
-    }
-
-    return 1;
-}
-
diff --git a/doc/faq.txt b/doc/faq.txt
deleted file mode 100644 (file)
index 6375637..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-$Id: faq.txt,v 1.14 2004/04/22 22:22:07 titer Exp $
-
-<h2>HandBrake FAQ</h2>
-
-<h4>1. Troubleshooting</h4>
-<p><a href="#A001001">1.1. Encoding seemed to work fine, but I don't
-get any sound</a></p>
-<p><a href="#A001002">1.2. Not every title of the DVD shows up in
-HandBrake</a></p>
-<p><a href="#A001003">1.3. Rip exits after a while with a AC3 error.
-What does that mean?</a></p>
-
-<h4>2. Features</h4>
-<p><a href="#A002001">2.1 I want to convert a movie so I can burn it on
-a VCD or a DVD-R. Is HandBrake the right application to do this?</a></p>
-<p><a href="#A002002">2.2. I want to to convert a movie so I can edit it
-in iMovie. Is HandBrake the right application to do this?</a></p>
-<p><a href="#A002003">2.3. I wish HandBrake could support subtitles, rip
-a 30 seconds sample, [...]</a></p>
-<p><a href="#A002004">2.4. Any plan to include 3ivx / DivX 5
-encoding?</a></p>
-
-<h4>3. Technical</h4>
-<p><a href="#A003001">3.1 What's the difference between Ffmpeg and
-XviD?</a></p>
-<p><a href="#A003002">3.2 What is 2-pass encoding?</a></p>
-
-<h4>4. Misc</h4>
-<p><a href="#A004001">4.1. How do I donate for HandBrake?</a></p>
-<p><a href="#A004002">4.2. Where does this stupid name / icon come
-from?</a></p>
-
-<hr>
-
-<h3>1. Troubleshooting</h3>
-
-<a name="A001001"></a>
-<h4>1.1 Encoding seemed to work fine, but I don't get any sound</h4>
-<p>I guess you are trying to read an AVI file with OS X
-/ Quicktime. Try installing the latest DivX codec from
-<a href="http://www.divx.com/divx/mac/">DivX.com</a>,
-or use <a href="http://videolan.org/vlc/">VLC</a>.</p>
-
-<a name="A001002"></a>
-<h4>1.2. Not every title of the DVD shows up in HandBrake</h4>
-<p>There are 3 reasons why HandBrake might not show a title: it is a
-menu, it has no audio track HandBrake can handle (only AC3 is supported)
-or there was a problem when trying to decode data from it (e.g. a
-decryption problem). There is no way to workaround this, these titles
-don't show up just because you can't rip them. You might check HandBrake
-logs in a terminal to know what's happening on your particular DVD.</p>
-
-<a name="A001003"></a>
-<h4>1.3. Rip exits after a while with a AC3 error. What does that
-mean?</h4>
-<p>It means HandBrake had to deal with corrupted data. It usually
-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
-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>
-
-<a name="A002001"></a>
-<h4>2.1 I want to convert a movie so I can burn it on a VCD or a DVD-R.
-Is HandBrake the right application to do this?</h4>
-<p>No. HandBrake only outputs MPEG-4, no MPEG-1 or MPEG-2. If you are
-using OS X, have a look at <a
-href="http://www.versiontracker.com/dyn/moreinfo/macosx/18193">
-forty-two</a>, <a
-href="http://www.versiontracker.com/dyn/moreinfo/macosx/15473">
-ffmpegX</a>, <a
-href="http://www.versiontracker.com/dyn/moreinfo/macosx/20778">
-DVDRemaster</a> or <a
-href="http://www.versiontracker.com/dyn/moreinfo/macosx/19238">
-DVD2oneX</a>. This will save you time and quality.</p>
-
-<a name="A002002"></a>
-<h4>2.2 I want to to convert a movie so I can edit it in iMovie. Is
-HandBrake the right application to do this?</h4>
-<p>No. MPEG-4 isn't a good format for editing, you'd better find a way
-to extract it as MJPEG or something, or edit the MPEG-2 directly.</p>
-
-<a name="A002003"></a>
-<h4>2.3. I wish HandBrake could support subtitles, rip a 30 seconds
-sample, [...]</h4>
-<p>Check the <a href="http://handbrake.m0k.org/TODO">TODO</a> list to
-see what's on the roadmap. If you wish to see a feature which isn't
-already in it, mail me and, if I think I can do it someday, I'll add
-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.
-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>
-
-<a name="A003001"></a>
-<h4>3.1 What's the difference between Ffmpeg and XviD?</h4>
-<p>Both are MPEG-4 compliant encoders, so you may choose whichever you
-want. However, I would recommend Ffmpeg as it is pretty faster on BeOS
-and OS X.</p>
-
-<a name="A003002"></a>
-<h4>3.2 What is 2-pass encoding?</h4>
-<p>It performs a slower but better compression - basically it makes
-sure you'll get a constant quality so you won't see blocks in fast
-motion scenes. Though it's disabled by default, I would strongly
-recommend to use it except if you really care about time.</p>
-
-<h3>4. Misc</h3>
-
-<a name="A004001"></a>
-<h4>4.1. How do I donate for HandBrake?</h4>
-
-<p>I'm working on HandBrake for fun, therefore I haven't set up a
-paypal account or anything (and I won't). Thanks anyway to people who
-wanted to give me money ;p<br>
-There are still two ways to make me happy:</p>
-<ul>
-<li>Send me a friendly email</li>
-<li>You may send me a DVD (for example, a DVD HandBrake has problems
-with so I can work it out). Sending a DVD through the world isn't really
-handy though (the cheapest way is probably to order it online in a
-french store with my address for shipping), so if it's a problem, you
-can just fall back on the friendly mail ;)<br>
-<br>
-Here's the address:<br>
-Eric Petit<br>
-Résidence ECP - H211<br>
-2 avenue Sully Prudhomme<br>
-92290 Chatenay Malabry<br>
-France<br>
-</li>
-</ul>
-
-<a name="A004002"></a>
-<h4>4.2 Where does this stupid name / icon come from?</h4>
-<p>Don't ask.</p>
-
diff --git a/doc/genhtml.sh b/doc/genhtml.sh
deleted file mode 100755 (executable)
index a88d414..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-#! /bin/sh
-
-rm -f faq.html
-
-DATE=$( grep "^\$Id" faq.txt | awk '{ print $4 " " $5; }' )
-
-cat > faq.html << EOF
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-<title>HandBrake FAQ</title>
-<style type="text/css">
-body,p,th,td  { font-family: Verdana,Arial,Helvetica,sans-serif;
-                font-size: 8pt;
-                font-weight: normal;
-                color: #000000; }
-body          { margin-left: 10;
-                margin-top: 10;
-                margin-right: 10;
-                margin-bottom: 10;
-                background-color: #FFFFFF; }
-a             { color: #000000;
-                text-decoration: underline; }
-a:hover       { color: #888888; }
-</style>
-</head>
-<body bgcolor="#ffffff">
-
-<p>
-Last updated: ${DATE}<br>
-The latest version of this FAQ can be found <a
-href="http://handbrake.m0k.org/faq.php">here</a>.
-</p>
-EOF
-
-cat faq.txt | grep -v "^\$Id" >> faq.html
-
-cat >> faq.html << EOF
-</body>
-</html>
-EOF
-
diff --git a/libhb/Jamfile b/libhb/Jamfile
new file mode 100644 (file)
index 0000000..29f9c77
--- /dev/null
@@ -0,0 +1,18 @@
+# $Id: Jamfile,v 1.34 2005/10/15 18:05:03 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.
+
+SubDir TOP libhb ;
+
+LIBHB_SRC =
+common.c hb.c ports.c scan.c work.c decmpeg2.c encavcodec.c update.c
+demuxmpeg.c fifo.c render.c reader.c muxcommon.c muxmp4.c sync.c
+decsub.c deca52.c encfaac.c declpcm.c encx264.c decavcodec.c encxvid.c
+muxavi.c enclame.c muxogm.c encvorbis.c dvd.c ;
+
+Library libhb : $(LIBHB_SRC) ;
+
+ObjectCcFlags $(LIBHB_SRC) : -I$(TOP)/contrib/include ;
+ObjectDefines $(LIBHB_SRC) : __LIBHB__ ;
diff --git a/libhb/common.c b/libhb/common.c
new file mode 100644 (file)
index 0000000..7bd125c
--- /dev/null
@@ -0,0 +1,502 @@
+/* $Id: common.c,v 1.15 2005/03/17 19:22:47 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 <stdarg.h>
+#include <time.h> 
+#include <sys/time.h>
+
+#include "common.h"
+
+/**********************************************************************
+ * Global variables
+ *********************************************************************/
+hb_rate_t hb_video_rates[] =
+{ { "5",  5400000 }, { "10",     2700000 }, { "12", 2250000 },
+  { "15", 1800000 }, { "23.976", 1126125 }, { "24", 1125000 },
+  { "25", 1080000 }, { "29.97",  900900  } };
+int hb_video_rates_count = sizeof( hb_video_rates ) /
+                           sizeof( hb_rate_t );
+
+hb_rate_t hb_audio_rates[] =
+{ { "22050", 22050 }, { "24000", 24000 },
+  { "44100", 44100 }, { "48000", 48000 } };
+int hb_audio_rates_count   = sizeof( hb_audio_rates ) /
+                             sizeof( hb_rate_t );
+int hb_audio_rates_default = 2; /* 44100 Hz */
+
+hb_rate_t hb_audio_bitrates[] =
+{ {  "32",  32 }, {  "40",  40 }, {  "48",  48 }, {  "56",  56 },
+  {  "64",  64 }, {  "80",  80 }, {  "96",  96 }, { "112", 112 },
+  { "128", 128 }, { "160", 160 }, { "192", 192 }, { "224", 224 },
+  { "256", 256 }, { "320", 320 } };
+int hb_audio_bitrates_count = sizeof( hb_audio_bitrates ) /
+                              sizeof( hb_rate_t );
+int hb_audio_bitrates_default = 8; /* 128 kbps */
+
+/**********************************************************************
+ * hb_fix_aspect
+ **********************************************************************
+ * Given the output width (if HB_KEEP_WIDTH) or height
+ * (HB_KEEP_HEIGHT) and the current crop values, calculates the
+ * correct height or width in order to respect the DVD aspect ratio
+ *********************************************************************/
+void hb_fix_aspect( hb_job_t * job, int keep )
+{
+    hb_title_t * title = job->title;
+    int          i;
+
+    /* Sanity checks:
+       Widths and heights must be multiples of 16 and greater than or
+       equal to 16
+       Crop values must be multiples of 2, greater than or equal to 0
+       and less than half of the dimension */
+    job->width   = MULTIPLE_16( job->width );
+    job->height  = MULTIPLE_16( job->height );
+    job->width   = MAX( 16, job->width );
+    job->height  = MAX( 16, job->height );
+    for( i = 0; i < 4; i++ )
+    {
+        job->crop[i] = EVEN( job->crop[i] );
+        job->crop[i] = MAX( 0, job->crop[i] );
+        if( i < 2 )
+        {
+            /* Top, bottom */
+            job->crop[i] = MIN( job->crop[i], ( title->height / 2 ) - 2 );
+        }
+        else
+        {
+            /* Left, right */
+            job->crop[i] = MIN( job->crop[i], ( title->width / 2 ) - 2 );
+        }
+    }
+
+    if( keep == HB_KEEP_WIDTH )
+    {
+        job->height = MULTIPLE_16(
+            (uint64_t) job->width * title->width * HB_ASPECT_BASE *
+              ( title->height - job->crop[0] - job->crop[1] ) /
+            ( (uint64_t) title->height * title->aspect *
+              ( title->width - job->crop[2] - job->crop[3] ) ) );
+        job->height = MAX( 16, job->height );
+    }
+    else
+    {
+        job->width = MULTIPLE_16(
+            (uint64_t) job->height * title->height * title->aspect *
+              ( title->width - job->crop[2] - job->crop[3] ) /
+            ( (uint64_t) title->width * HB_ASPECT_BASE *
+              ( title->height - job->crop[0] - job->crop[1] ) ) );
+        job->width = MAX( 16, job->width );
+    }
+}
+
+/**********************************************************************
+ * hb_calc_bitrate
+ **********************************************************************
+ * size: in megabytes
+ *********************************************************************/
+int hb_calc_bitrate( hb_job_t * job, int size )
+{
+    int64_t avail = (int64_t) size * 1024 * 1024;
+    int64_t length;
+    int     overhead;
+    int     samples_per_frame;
+    int     i;
+
+    hb_title_t   * title = job->title;
+    hb_chapter_t * chapter;
+    hb_audio_t   * audio;
+
+    /* How many overhead bytes are used for each frame
+       (quite guessed) */
+    switch( job->mux )
+    {
+       case HB_MUX_MP4:
+            overhead = 6;
+            break; 
+        case HB_MUX_AVI:
+            overhead = 24;
+            break; 
+        case HB_MUX_OGM:
+            overhead = 6;
+            break;
+        default:
+            return 0;
+    }
+
+    /* How many audio samples we put in each frame */
+    switch( job->acodec )
+    {
+        case HB_ACODEC_FAAC:
+        case HB_ACODEC_VORBIS:
+            samples_per_frame = 1024;
+            break;
+        case HB_ACODEC_LAME:
+            samples_per_frame = 1152;
+            break;
+        case HB_ACODEC_AC3:
+            samples_per_frame = 1536;
+            break;
+        default:
+            return 0;
+    }
+
+    /* Get the duration in seconds */
+    length = 0;
+    for( i = job->chapter_start; i <= job->chapter_end; i++ )
+    {
+        chapter = hb_list_item( title->list_chapter, i - 1 );
+        length += chapter->duration;
+    }
+    length += 135000;
+    length /= 90000;
+
+    /* Video overhead */
+    avail -= length * job->vrate * overhead / job->vrate_base;
+
+    for( i = 0; job->audios[i] >= 0; i++ )
+    {
+        /* Audio data */
+        int abitrate;
+        if( job->acodec & HB_ACODEC_AC3 )
+        {
+            audio = hb_list_item( title->list_audio, job->audios[i] );
+            abitrate = audio->bitrate / 8;
+        }
+        else
+        {
+            abitrate = job->abitrate * 1000 / 8;
+        }
+        avail -= length * abitrate;
+        
+        /* Audio overhead */
+        avail -= length * job->arate * overhead / samples_per_frame;
+    }
+
+    if( avail < 0 )
+    {
+        return 0;
+    }
+
+    return ( avail / ( 125 * length ) );
+}
+
+/**********************************************************************
+ * hb_list implementation
+ **********************************************************************
+ * Basic and slow, but enough for what we need
+ *********************************************************************/
+
+#define HB_LIST_DEFAULT_SIZE 20
+
+struct hb_list_s
+{
+    /* Pointers to items in the list */
+    void ** items;
+
+    /* How many (void *) allocated in 'items' */
+    int     items_alloc;
+
+    /* How many valid pointers in 'items' */
+    int     items_count;
+};
+
+/**********************************************************************
+ * hb_list_init
+ **********************************************************************
+ * Allocates an empty list ready for HB_LIST_DEFAULT_SIZE items
+ *********************************************************************/
+hb_list_t * hb_list_init()
+{
+    hb_list_t * l;
+
+    l              = calloc( sizeof( hb_list_t ), 1 );
+    l->items       = calloc( HB_LIST_DEFAULT_SIZE * sizeof( void * ), 1 );
+    l->items_alloc = HB_LIST_DEFAULT_SIZE;
+
+    return l;
+}
+
+/**********************************************************************
+ * hb_list_count
+ **********************************************************************
+ * Returns the number of items currently in the list
+ *********************************************************************/
+int hb_list_count( hb_list_t * l )
+{
+    return l->items_count;
+}
+
+/**********************************************************************
+ * hb_list_add
+ **********************************************************************
+ * Adds an item at the end of the list, making it bigger if necessary.
+ * Can safely be called with a NULL pointer to add, it will be ignored.
+ *********************************************************************/
+void hb_list_add( hb_list_t * l, void * p )
+{
+    if( !p )
+    {
+        return;
+    }
+
+    if( l->items_count == l->items_alloc )
+    {
+        /* We need a bigger boat */
+        l->items_alloc += HB_LIST_DEFAULT_SIZE;
+        l->items        = realloc( l->items,
+                                   l->items_alloc * sizeof( void * ) );
+    }
+
+    l->items[l->items_count] = p;
+    (l->items_count)++;
+}
+
+/**********************************************************************
+ * hb_list_rem
+ **********************************************************************
+ * Remove an item from the list. Bad things will happen if called
+ * with a NULL pointer or if the item is not in the list.
+ *********************************************************************/
+void hb_list_rem( hb_list_t * l, void * p )
+{
+    int i;
+
+    /* Find the item in the list */
+    for( i = 0; i < l->items_count; i++ )
+    {
+        if( l->items[i] == p )
+        {
+            break;
+        }
+    }
+
+    /* Shift all items after it sizeof( void * ) bytes earlier */
+    memmove( &l->items[i], &l->items[i+1],
+             ( l->items_count - i - 1 ) * sizeof( void * ) );
+
+    (l->items_count)--;
+}
+
+/**********************************************************************
+ * hb_list_item
+ **********************************************************************
+ * Returns item at position i, or NULL if there are not that many
+ * items in the list
+ *********************************************************************/
+void * hb_list_item( hb_list_t * l, int i )
+{
+    if( i < 0 || i >= l->items_count )
+    {
+        return NULL;
+    }
+
+    return l->items[i];
+}
+
+/**********************************************************************
+ * hb_list_bytes
+ **********************************************************************
+ * Assuming all items are of type hb_buffer_t, returns the total
+ * number of bytes in the list
+ *********************************************************************/
+int hb_list_bytes( hb_list_t * l )
+{
+    hb_buffer_t * buf;
+    int           ret;
+    int           i;
+
+    ret = 0;
+    for( i = 0; i < hb_list_count( l ); i++ )
+    {
+        buf  = hb_list_item( l, i );
+        ret += buf->size - buf->cur;
+    }
+
+    return ret;                                                                 
+}
+
+/**********************************************************************
+ * hb_list_seebytes
+ **********************************************************************
+ * Assuming all items are of type hb_buffer_t, copy <size> bytes from
+ * the list to <dst>, keeping the list unmodified.
+ *********************************************************************/
+void hb_list_seebytes( hb_list_t * l, uint8_t * dst, int size )
+{
+    hb_buffer_t * buf;
+    int           copied;
+    int           copying;
+    int           i;
+    
+    for( i = 0, copied = 0; copied < size; i++ )
+    {
+        buf     = hb_list_item( l, i );
+        copying = MIN( buf->size - buf->cur, size - copied );
+        memcpy( &dst[copied], &buf->data[buf->cur], copying );
+        copied += copying;
+    }                                                                           
+}
+
+/**********************************************************************
+ * hb_list_getbytes
+ **********************************************************************
+ * Assuming all items are of type hb_buffer_t, copy <size> bytes from
+ * the list to <dst>. What's copied is removed from the list.
+ * The variable pointed by <pts> is set to the PTS of the buffer the
+ * first byte has been got from.
+ * The variable pointed by <pos> is set to the position of that byte
+ * in that buffer.
+ *********************************************************************/
+void hb_list_getbytes( hb_list_t * l, uint8_t * dst, int size,
+                       uint64_t * pts, int * pos )
+{
+    hb_buffer_t * buf;
+    int           copied;
+    int           copying;
+    uint8_t       has_pts;
+    
+    /* So we won't have to deal with NULL pointers */
+    uint64_t dummy1;
+    int      dummy2;
+    if( !pts ) pts = &dummy1;
+    if( !pos ) pos = &dummy2;
+
+    for( copied = 0, has_pts = 0; copied < size;  )
+    {
+        buf     = hb_list_item( l, 0 );
+        copying = MIN( buf->size - buf->cur, size - copied );
+        memcpy( &dst[copied], &buf->data[buf->cur], copying );
+
+        if( !has_pts )
+        {
+            *pts    = buf->start;
+            *pos    = buf->cur;
+            has_pts = 1;
+        }
+
+        buf->cur += copying;
+        if( buf->cur >= buf->size )
+        {
+            hb_list_rem( l, buf );
+            hb_buffer_close( &buf );
+        }
+
+        copied += copying;
+    }                                                                           
+}
+
+/**********************************************************************
+ * hb_list_empty
+ **********************************************************************
+ * Assuming all items are of type hb_buffer_t, close them all and
+ * close the list.
+ *********************************************************************/
+void hb_list_empty( hb_list_t ** _l )
+{
+    hb_list_t * l = *_l;
+    hb_buffer_t * b;
+
+    while( ( b = hb_list_item( l, 0 ) ) )
+    {
+        hb_list_rem( l, b );
+        hb_buffer_close( &b );
+    }
+
+    hb_list_close( _l );
+}
+
+/**********************************************************************
+ * hb_list_close
+ **********************************************************************
+ * Free memory allocated by hb_list_init. Does NOT free contents of
+ * items still in the list.
+ *********************************************************************/
+void hb_list_close( hb_list_t ** _l )
+{
+    hb_list_t * l = *_l;
+
+    free( l->items );
+    free( l );
+
+    *_l = NULL;
+}
+
+/**********************************************************************
+ * hb_log
+ **********************************************************************
+ * If verbose mode is one, print message with timestamp. Messages
+ * longer than 80 characters are stripped ;p
+ *********************************************************************/
+void hb_log( char * log, ... )
+{
+    char        string[82]; /* 80 chars + \n + \0 */
+    time_t      _now;
+    struct tm * now;
+    va_list     args;
+
+    if( !getenv( "HB_DEBUG" ) )
+    {
+        /* We don't want to print it */
+        return;
+    }
+
+    /* Get the time */
+    _now = time( NULL );
+    now  = localtime( &_now );
+    sprintf( string, "[%02d:%02d:%02d] ",
+             now->tm_hour, now->tm_min, now->tm_sec );
+
+    /* Convert the message to a string */
+    va_start( args, log );
+    vsnprintf( string + 11, 69, log, args );
+    va_end( args );
+
+    /* Add the end of line */
+    strcat( string, "\n" );
+
+    /* Print it */
+    fprintf( stderr, "%s", string );
+}
+
+/**********************************************************************
+ * hb_title_init
+ **********************************************************************
+ * 
+ *********************************************************************/
+hb_title_t * hb_title_init( char * dvd, int index )
+{
+    hb_title_t * t;
+
+    t = calloc( sizeof( hb_title_t ), 1 );
+
+    t->index         = index;
+    t->list_audio    = hb_list_init();
+    t->list_chapter  = hb_list_init();
+    t->list_subtitle = hb_list_init();
+    strcat( t->dvd, dvd );
+
+    return t;
+}
+
+/**********************************************************************
+ * hb_title_close
+ **********************************************************************
+ * 
+ *********************************************************************/
+void hb_title_close( hb_title_t ** _t )
+{
+    hb_title_t * t = *_t;
+
+    hb_list_close( &t->list_audio );
+    hb_list_close( &t->list_chapter );
+    hb_list_close( &t->list_subtitle );
+    free( t->job );
+
+    free( t );
+    *_t = NULL;
+}
+
diff --git a/libhb/common.h b/libhb/common.h
new file mode 100644 (file)
index 0000000..402ae7f
--- /dev/null
@@ -0,0 +1,349 @@
+/* $Id: common.h,v 1.51 2005/11/04 13:09: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. */
+
+#ifndef HB_COMMON_H
+#define HB_COMMON_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+
+#ifndef MIN
+#define MIN( a, b ) ( (a) > (b) ? (b) : (a) )
+#endif
+#ifndef MAX
+#define MAX( a, b ) ( (a) > (b) ? (a) : (b) )
+#endif
+
+#define EVEN( a )        ( (a) + ( (a) & 1 ) )
+#define MULTIPLE_16( a ) ( 16 * ( ( (a) + 8 ) / 16 ) )
+
+typedef struct hb_handle_s hb_handle_t;
+typedef struct hb_list_s hb_list_t;
+typedef struct hb_rate_s hb_rate_t;
+typedef struct hb_job_s  hb_job_t;
+typedef struct hb_title_s hb_title_t;
+typedef struct hb_chapter_s hb_chapter_t;
+typedef struct hb_audio_s hb_audio_t;
+typedef struct hb_subtitle_s hb_subtitle_t;
+typedef struct hb_state_s hb_state_t;
+
+#include "ports.h"
+#ifdef __LIBHB__
+#include "internal.h"
+#endif
+
+hb_list_t * hb_list_init();
+int         hb_list_count( hb_list_t * );
+void        hb_list_add( hb_list_t *, void * );
+void        hb_list_rem( hb_list_t *, void * );
+void      * hb_list_item( hb_list_t *, int );
+void        hb_list_close( hb_list_t ** );
+
+#define HB_KEEP_WIDTH  0
+#define HB_KEEP_HEIGHT 1
+void hb_fix_aspect( hb_job_t * job, int keep );
+
+int hb_calc_bitrate( hb_job_t *, int size );
+
+struct hb_rate_s
+{
+    char * string;
+    int    rate;
+};
+
+#define HB_ASPECT_BASE 9
+#define HB_VIDEO_RATE_BASE   27000000
+
+extern hb_rate_t hb_video_rates[];
+extern int       hb_video_rates_count;
+extern hb_rate_t hb_audio_rates[];
+extern int       hb_audio_rates_count;
+extern int       hb_audio_rates_default;
+extern hb_rate_t hb_audio_bitrates[];
+extern int       hb_audio_bitrates_count;
+extern int       hb_audio_bitrates_default;
+
+/******************************************************************************
+ * hb_job_t: settings to be filled by the UI
+ *****************************************************************************/
+struct hb_job_s
+{
+    /* Pointer to the title to be ripped */
+    hb_title_t    * title;
+    
+    /* Chapter selection */
+    int             chapter_start;
+    int             chapter_end;
+
+    /* Picture settings:
+         crop:        must be multiples of 2 (top/bottom/left/right)
+         deinterlace: 0 or 1
+         width:       must be a multiple of 16
+         height:      must be a multiple of 16
+         keep_ratio:  used by UIs */
+    int             crop[4];
+    int             deinterlace;
+    int             width;
+    int             height;
+    int             keep_ratio;
+    int             grayscale;
+
+    /* Video settings:
+         vcodec:            output codec
+         vquality:          output quality (0.0..1.0)
+                            if < 0.0 or > 1.0, bitrate is used instead
+         vbitrate:          output bitrate (kbps)
+         pass:              0, 1 or 2
+         vrate, vrate_base: output framerate is vrate / vrate_base */
+#define HB_VCODEC_MASK   0x0000FF
+#define HB_VCODEC_FFMPEG 0x000001
+#define HB_VCODEC_XVID   0x000002
+#define HB_VCODEC_X264   0x000004
+    int             vcodec;
+    float           vquality;
+    int             vbitrate;
+    int             vrate;
+    int             vrate_base;
+    int             pass;
+    int             h264_13;
+
+    /* Audio tracks:
+         Indexes in hb_title_t's audios list, starting from 0.
+         -1 indicates the end of the list */
+    int             audios[8];
+
+    /* Audio settings:
+         acodec:   output codec
+         abitrate: output bitrate (kbps)
+         arate:    output samplerate (Hz)
+       HB_ACODEC_AC3 means pass-through, then abitrate and arate are
+       ignored */
+#define HB_ACODEC_MASK   0x00FF00
+#define HB_ACODEC_FAAC   0x000100
+#define HB_ACODEC_LAME   0x000200
+#define HB_ACODEC_VORBIS 0x000400
+#define HB_ACODEC_AC3    0x000800
+#define HB_ACODEC_MPGA   0x001000
+#define HB_ACODEC_LPCM   0x002000
+    int             acodec;
+    int             abitrate;
+    int             arate;
+
+    /* Subtitle settings:
+         subtitle: index in hb_title_t's subtitles list, starting
+         from 0. -1 means no subtitle */
+    int             subtitle;
+
+    /* Muxer settings
+         mux:  output file format
+         file: file path */
+#define HB_MUX_MASK 0xFF0000
+#define HB_MUX_MP4  0x010000
+#define HB_MUX_AVI  0x020000
+#define HB_MUX_OGM  0x040000
+    int             mux;
+    char          * file;
+
+#ifdef __LIBHB__
+    /* Internal data */
+    hb_handle_t   * h;
+    hb_lock_t     * pause;
+    volatile int  * die;
+    volatile int    done;
+
+    hb_fifo_t     * fifo_mpeg2;   /* MPEG-2 video ES */
+    hb_fifo_t     * fifo_raw;     /* Raw pictures */
+    hb_fifo_t     * fifo_sync;    /* Raw pictures, framerate corrected */
+    hb_fifo_t     * fifo_render;  /* Raw pictures, scaled */
+    hb_fifo_t     * fifo_mpeg4;   /* MPEG-4 video ES */
+
+    hb_thread_t   * reader;
+    hb_thread_t   * muxer;
+
+    hb_list_t     * list_work;
+
+    union
+    {
+        struct
+        {
+            uint8_t * config;
+            int       config_length;
+        } mpeg4;
+
+        struct
+        {
+            uint8_t * sps;
+            int       sps_length;
+            uint8_t * pps;
+            int       pps_length;
+        } h264;
+
+    } config;
+
+    /* MPEG-4 / AVC */
+    uint8_t       * es_config;
+    int             es_config_length;
+
+    hb_mux_data_t * mux_data;
+#endif
+};
+
+struct hb_audio_s
+{
+    int  id;
+    char lang[1024];
+    int  codec;
+    int  rate;
+    int  bitrate;
+    int  channels;
+
+#ifdef __LIBHB__
+    /* Internal data */
+    hb_fifo_t * fifo_in;   /* AC3/MPEG/LPCM ES */
+    hb_fifo_t * fifo_raw;  /* Raw audio */
+    hb_fifo_t * fifo_sync; /* Resampled, synced raw audio */
+    hb_fifo_t * fifo_out;  /* MP3/AAC/Vorbis ES */
+
+    union
+    {
+        struct
+        {
+            uint8_t       * decinfo;
+            unsigned long   size;
+        } faac;
+
+        struct
+        {
+            uint8_t * headers[3];
+            int       sizes[3];
+        } vorbis;
+
+    } config;
+
+    hb_mux_data_t * mux_data;
+#endif
+};
+
+struct hb_chapter_s
+{
+    int      index;
+    int      cell_start;
+    int      cell_end;
+    int      block_start;
+    int      block_end;
+    int      block_count;
+
+    /* Visual-friendly duration */
+    int      hours;
+    int      minutes;
+    int      seconds;
+
+    /* Exact duration (in 1/90000s) */
+    uint64_t duration;
+};
+
+struct hb_subtitle_s
+{
+    int  id;
+    char lang[1024];
+
+#ifdef __LIBHB__
+    /* Internal data */
+    hb_fifo_t * fifo_in;  /* SPU ES */
+    hb_fifo_t * fifo_raw; /* Decodec SPU */
+#endif
+};
+
+struct hb_title_s
+{
+    char        dvd[1024];
+    int         index;
+    int         vts;
+    int         ttn;
+    int         cell_start;
+    int         cell_end;
+    int         block_start;
+    int         block_end;
+    int         block_count;
+
+    /* Visual-friendly duration */
+    int         hours;
+    int         minutes;
+    int         seconds;
+
+    /* Exact duration (in 1/90000s) */
+    uint64_t    duration;
+
+    int         width;
+    int         height;
+    int         aspect;
+    int         rate;
+    int         rate_base;
+    int         crop[4];
+
+    uint32_t    palette[16];
+
+    hb_list_t * list_chapter;
+    hb_list_t * list_audio;
+    hb_list_t * list_subtitle;
+
+    /* Job template for this title */
+    hb_job_t  * job;
+};
+
+
+struct hb_state_s
+{
+#define HB_STATE_IDLE     1
+#define HB_STATE_SCANNING 2
+#define HB_STATE_SCANDONE 4
+#define HB_STATE_WORKING  8
+#define HB_STATE_PAUSED   16
+#define HB_STATE_WORKDONE 32
+    int state;
+
+    union
+    {
+        struct
+        {
+            /* HB_STATE_SCANNING */
+            int title_cur;
+            int title_count;
+        } scanning;
+
+        struct
+        {
+            /* HB_STATE_WORKING */
+            float progress;
+            int   job_cur;
+            int   job_count;
+            float rate_cur;
+            float rate_avg;
+            int   hours;
+            int   minutes;
+            int   seconds;
+        } working;
+
+        struct
+        {
+            /* HB_STATE_WORKDONE */
+#define HB_ERROR_NONE     0
+#define HB_ERROR_CANCELED 1
+#define HB_ERROR_UNKNOWN  2
+            int error;
+        } workdone;
+
+    } param;
+};
+
+#endif
diff --git a/libhb/deca52.c b/libhb/deca52.c
new file mode 100644 (file)
index 0000000..a4f7492
--- /dev/null
@@ -0,0 +1,200 @@
+/* $Id: deca52.c,v 1.14 2005/03/03 17:21:57 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 "hb.h"
+
+#include "a52dec/a52.h"
+
+struct hb_work_object_s
+{
+    HB_WORK_COMMON;
+
+    hb_job_t    * job;
+    hb_audio_t  * audio;
+
+    /* liba52 handle */
+    a52_state_t * state;
+
+    int           flags_in;
+    int           flags_out;
+    int           rate;
+    int           bitrate;
+    float         level;
+    
+    int           error;
+    int           sync;
+    int           size;
+
+    uint8_t       frame[3840];
+
+    hb_list_t   * list;
+};
+
+/***********************************************************************
+ * Local prototypes
+ **********************************************************************/
+static void          Close( hb_work_object_t ** _w );
+static int           Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+                           hb_buffer_t ** buf_out );
+static hb_buffer_t * Decode( hb_work_object_t * w );
+
+/***********************************************************************
+ * hb_work_deca52_init
+ ***********************************************************************
+ * Allocate the work object, initialize liba52
+ **********************************************************************/
+hb_work_object_t * hb_work_deca52_init( hb_job_t * job, hb_audio_t * audio )
+{
+    hb_work_object_t * w = calloc( sizeof( hb_work_object_t ), 1 );
+    w->name  = strdup( "AC3 decoder" );
+    w->work  = Work;
+    w->close = Close;
+
+    w->job   = job;
+    w->audio = audio;
+
+    w->list      = hb_list_init();
+    w->state     = a52_init( 0 );
+    w->flags_out = A52_STEREO;
+    w->level     = 32768.0;
+
+    return w;
+}
+
+/***********************************************************************
+ * Close
+ ***********************************************************************
+ * Free memory
+ **********************************************************************/
+static void Close( hb_work_object_t ** _w )
+{
+    hb_work_object_t * w = *_w;
+    a52_free( w->state );
+    free( w->name );
+    free( w );
+    *_w = NULL;
+}
+
+/***********************************************************************
+ * Work
+ ***********************************************************************
+ * Add the given buffer to the data we already have, and decode as much
+ * as we can
+ **********************************************************************/
+static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+                 hb_buffer_t ** buf_out )
+{
+    hb_buffer_t * buf;
+
+    hb_list_add( w->list, *buf_in );
+    *buf_in = NULL;
+
+    /* If we got more than a frame, chain raw buffers */
+    *buf_out = buf = Decode( w );
+    while( buf )
+    {
+        buf->next = Decode( w );
+        buf       = buf->next;
+    }
+
+    return HB_WORK_OK;
+}
+
+/***********************************************************************
+ * Decode
+ ***********************************************************************
+ * 
+ **********************************************************************/
+static hb_buffer_t * Decode( hb_work_object_t * w )
+{
+    hb_buffer_t * buf;
+    int           i, j;
+    uint64_t      pts;
+    int           pos;
+
+    /* Get a frame header if don't have one yet */
+    if( !w->sync )
+    {
+        while( hb_list_bytes( w->list ) >= 7 )
+        {
+            /* We have 7 bytes, check if this is a correct header */
+            hb_list_seebytes( w->list, w->frame, 7 );
+            w->size = a52_syncinfo( w->frame, &w->flags_in, &w->rate,
+                                    &w->bitrate );
+            if( w->size )
+            {
+                /* It is. W00t. */
+                if( w->error )
+                {
+                    hb_log( "a52_syncinfo ok" );
+                }
+                w->error = 0;
+                w->sync  = 1;
+                break;
+            }
+
+            /* It is not */
+            if( !w->error )
+            {
+                hb_log( "a52_syncinfo failed" );
+                w->error = 1;
+            }
+
+            /* Try one byte later */
+            hb_list_getbytes( w->list, w->frame, 1, NULL, NULL );
+        }
+    }
+
+    if( !w->sync ||
+        hb_list_bytes( w->list ) < w->size )
+    {
+        /* Need more data */
+        return NULL;
+    }
+
+    /* Get the whole frame */
+    hb_list_getbytes( w->list, w->frame, w->size, &pts, &pos );
+
+    /* AC3 passthrough: don't decode the AC3 frame */
+    if( w->job->acodec & HB_ACODEC_AC3 )
+    {
+        buf = hb_buffer_init( w->size );
+        memcpy( buf->data, w->frame, w->size );
+        buf->start = pts + ( pos / w->size ) * 6 * 256 * 90000 / w->rate;
+        buf->stop  = buf->start + 6 * 256 * 90000 / w->rate;
+        w->sync = 0;
+        return buf;
+    }
+
+    /* Feed liba52 */
+    a52_frame( w->state, w->frame, &w->flags_out, &w->level, 0 );
+
+    /* 6 blocks per frame, 256 samples per block, 2 channels */
+    buf        = hb_buffer_init( 3072 * sizeof( float ) );
+    buf->start = pts + ( pos / w->size ) * 6 * 256 * 90000 / w->rate;
+    buf->stop  = buf->start + 6 * 256 * 90000 / w->rate;
+
+    for( i = 0; i < 6; i++ )
+    {
+        sample_t * samples_in;
+        float    * samples_out;
+
+        a52_block( w->state );
+        samples_in  = a52_samples( w->state );
+        samples_out = ((float *) buf->data) + 512 * i;
+
+        /* Interleave */
+        for( j = 0; j < 256; j++ )
+        {
+            samples_out[2*j]   = samples_in[j];
+            samples_out[2*j+1] = samples_in[256+j];
+        }
+    }
+
+    w->sync = 0;
+    return buf;
+}
+
diff --git a/libhb/decavcodec.c b/libhb/decavcodec.c
new file mode 100644 (file)
index 0000000..f18579f
--- /dev/null
@@ -0,0 +1,137 @@
+/* $Id: decavcodec.c,v 1.6 2005/03/06 04:08:54 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 "hb.h"
+
+#include "ffmpeg/avcodec.h"
+
+struct hb_work_object_s
+{
+    HB_WORK_COMMON;
+
+    hb_job_t       * job;
+    hb_audio_t     * audio;
+
+    AVCodecContext * context;
+    int64_t          pts_last;
+};
+
+
+/***********************************************************************
+ * Local prototypes
+ **********************************************************************/
+static int  Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+                  hb_buffer_t ** buf_out );
+static void Close( hb_work_object_t ** _w );
+
+/***********************************************************************
+ * hb_work_decavcodec_init
+ ***********************************************************************
+ *
+ **********************************************************************/
+hb_work_object_t * hb_work_decavcodec_init( hb_job_t * job,
+                                            hb_audio_t * audio )
+{
+    hb_work_object_t * w = calloc( sizeof( hb_work_object_t ), 1 );
+    AVCodec * codec;
+    w->name  = strdup( "MPGA decoder (libavcodec)" );
+    w->work  = Work;
+    w->close = Close;
+
+    w->job   = job;
+    w->audio = audio;
+
+    codec = avcodec_find_decoder( CODEC_ID_MP2 );
+    w->context = avcodec_alloc_context();
+    avcodec_open( w->context, codec );
+    w->pts_last = -1;
+
+    return w;
+}
+
+/***********************************************************************
+ * Close
+ ***********************************************************************
+ *
+ **********************************************************************/
+static void Close( hb_work_object_t ** _w )
+{
+    hb_work_object_t * w = *_w;
+    avcodec_close( w->context );
+    free( w->name );
+    free( w );
+    *_w = NULL;
+}
+
+/***********************************************************************
+ * Work
+ ***********************************************************************
+ *
+ **********************************************************************/
+static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+                 hb_buffer_t ** buf_out )
+{
+    hb_buffer_t * in = *buf_in, * buf, * last = NULL;
+    int   pos, len, out_size, i;
+    short buffer[AVCODEC_MAX_AUDIO_FRAME_SIZE];
+    uint64_t cur;
+
+    *buf_out = NULL;
+
+    if( in->start < 0 ||
+        ( w->pts_last > 0 &&
+          in->start > w->pts_last &&
+          in->start - w->pts_last < 5000 ) ) /* Hacky */
+    {
+        cur = w->pts_last;
+    }
+    else
+    {
+        cur = in->start;
+    }
+
+    pos = 0;
+    while( pos < in->size )
+    {
+        len = avcodec_decode_audio( w->context, buffer, &out_size,
+                                    in->data + pos, in->size - pos );
+        if( out_size )
+        {
+            short * s16;
+            float * fl32;
+
+            buf = hb_buffer_init( 2 * out_size );
+
+            buf->start = cur;
+            buf->stop  = cur + 90000 * ( out_size / 4 ) /
+                         w->context->sample_rate;
+            cur = buf->stop;
+
+            s16  = buffer;
+            fl32 = (float *) buf->data;
+            for( i = 0; i < out_size / 2; i++ )
+            {
+                fl32[i] = s16[i];
+            }
+
+            if( last )
+            {
+                last = last->next = buf;
+            }
+            else
+            {
+                *buf_out = last = buf;
+            }
+        }
+
+        pos += len;
+    }
+
+    w->pts_last = cur;
+
+    return HB_WORK_OK;
+}
+
diff --git a/libhb/declpcm.c b/libhb/declpcm.c
new file mode 100644 (file)
index 0000000..59163c3
--- /dev/null
@@ -0,0 +1,113 @@
+/* $Id: declpcm.c,v 1.8 2005/11/04 14:44:01 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 "hb.h"
+
+struct hb_work_object_s
+{
+    HB_WORK_COMMON;
+
+    hb_job_t    * job;
+    hb_audio_t  * audio;
+
+    int64_t       pts_last;
+};
+
+static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+                 hb_buffer_t ** buf_out )
+{
+    hb_buffer_t * in = *buf_in, * out;
+    int samplerate = 0;
+    int count;
+    uint8_t * samples_u8;
+    float   * samples_fl32;
+    int i;
+    uint64_t duration;
+
+    *buf_out = NULL;
+
+    if( in->data[5] != 0x80 )
+    {
+        hb_log( "no LPCM frame sync (%02x)", in->data[5] );
+        return HB_WORK_OK;
+    }
+
+    switch( ( in->data[4] >> 4 ) & 0x3 )
+    {
+        case 0:
+            samplerate = 48000;
+            break;
+        case 1:
+            samplerate = 96000;//32000; /* FIXME vlc says it is 96000 */
+            break;
+        case 2:
+            samplerate = 44100;
+            break;
+        case 3:
+            samplerate = 32000;
+            break;
+    }
+
+    count      = ( in->size - 6 ) / 2;
+    out        = hb_buffer_init( count * sizeof( float ) );
+    duration   = count * 90000 / samplerate / 2;
+    if( w->pts_last > 0 &&
+        in->start < w->pts_last + duration / 6 &&
+        in->start > w->pts_last - duration / 6 )
+    {
+        /* Workaround for DVDs where dates aren't exact */
+        out->start = w->pts_last;
+    }
+    else
+    {
+        out->start = in->start;
+    }
+    out->stop   = out->start + duration;
+    w->pts_last = out->stop;
+
+    samples_u8   = in->data + 6;
+    samples_fl32 = (float *) out->data;
+
+    /* Big endian int16 -> float conversion */
+    for( i = 0; i < count; i++ )
+    {
+#ifdef WORDS_BIGENDIAN
+        samples_fl32[0] = *( (int16_t *) samples_u8 );
+#else
+        samples_fl32[0] = (int16_t) ( ( samples_u8[0] << 8 ) | samples_u8[1] );
+#endif
+        samples_u8   += 2;
+        samples_fl32 += 1;
+    }
+
+    *buf_out = out;
+
+    return HB_WORK_OK;
+}
+
+static void Close( hb_work_object_t ** _w )
+{
+    hb_work_object_t * w = *_w;
+    free( w->name );
+    free( w );
+    *_w = NULL;
+}
+
+hb_work_object_t * hb_work_declpcm_init( hb_job_t * job, hb_audio_t * audio )
+{
+    hb_work_object_t * w = calloc( sizeof( hb_work_object_t ), 1 );
+    w->name  = strdup( "LPCM decoder" );
+    w->work  = Work;
+    w->close = Close;
+
+    w->job   = job;
+    w->audio = audio;
+
+    w->pts_last = -1;
+
+    return w;
+}
+
diff --git a/libhb/decmpeg2.c b/libhb/decmpeg2.c
new file mode 100644 (file)
index 0000000..d914c03
--- /dev/null
@@ -0,0 +1,253 @@
+/* $Id: decmpeg2.c,v 1.12 2005/03/03 16:30:42 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 "hb.h"
+
+#include "mpeg2dec/mpeg2.h"
+
+/**********************************************************************
+ * hb_libmpeg2_t
+ **********************************************************************
+ * A convenient libmpeg wrapper, used both here and in scan.c
+ *********************************************************************/
+struct hb_libmpeg2_s
+{
+    mpeg2dec_t         * libmpeg2;
+    const mpeg2_info_t * info;
+    int                  width;
+    int                  height;
+    int                  rate;
+    int                  got_iframe;
+    int64_t              last_pts;
+};
+
+/**********************************************************************
+ * hb_libmpeg2_init
+ **********************************************************************
+ * 
+ *********************************************************************/
+hb_libmpeg2_t * hb_libmpeg2_init()
+{
+    hb_libmpeg2_t * m = calloc( sizeof( hb_libmpeg2_t ), 1 );
+    
+    m->libmpeg2 = mpeg2_init();
+    m->info     = mpeg2_info( m->libmpeg2 );
+    m->last_pts = -1;
+
+    return m;
+}
+
+/**********************************************************************
+ * hb_libmpeg2_decode
+ **********************************************************************
+ * 
+ *********************************************************************/
+int hb_libmpeg2_decode( hb_libmpeg2_t * m, hb_buffer_t * buf_es,
+                        hb_list_t * list_raw )
+{
+    mpeg2_state_t   state;
+    hb_buffer_t   * buf;
+    uint8_t       * data;
+
+    /* Feed libmpeg2 */
+    if( buf_es->start > -1 )
+    {
+        mpeg2_tag_picture( m->libmpeg2, buf_es->start >> 32,
+                           buf_es->start & 0xFFFFFFFF );
+    }
+    mpeg2_buffer( m->libmpeg2, buf_es->data,
+                  buf_es->data + buf_es->size );
+
+    for( ;; )
+    {
+        state = mpeg2_parse( m->libmpeg2 );
+        if( state == STATE_BUFFER )
+        {
+            /* Require some more data */
+            break;
+        }
+        else if( state == STATE_SEQUENCE )
+        {
+            if( !( m->width && m->height && m->rate ) )
+            {
+                m->width  = m->info->sequence->width;
+                m->height = m->info->sequence->height;
+                m->rate   = m->info->sequence->frame_period;
+                
+                if( m->rate == 900900 )
+                {
+                    /* 29.97 fps. 3:2 pulldown might, or might not be
+                       used. I can't find a way to know, so we always
+                       output 23.976 */
+                    m->rate = 1126125;
+                }
+            }
+        }
+        else if( ( state == STATE_SLICE || state == STATE_END ) &&
+                 m->info->display_fbuf )
+        {
+            if( ( m->info->display_picture->flags &
+                  PIC_MASK_CODING_TYPE ) == PIC_FLAG_CODING_TYPE_I )
+            {
+                m->got_iframe = 1;
+            }
+
+            if( m->got_iframe )
+            {
+                buf  = hb_buffer_init( m->width * m->height * 3 / 2 );
+                data = buf->data;
+
+                memcpy( data, m->info->display_fbuf->buf[0],
+                        m->width * m->height );
+                data += m->width * m->height;
+                memcpy( data, m->info->display_fbuf->buf[1],
+                        m->width * m->height / 4 );
+                data += m->width * m->height / 4;
+                memcpy( data, m->info->display_fbuf->buf[2],
+                        m->width * m->height / 4 );
+
+                if( m->info->display_picture->flags & PIC_FLAG_TAGS )
+                {
+                    buf->start =
+                        ( (uint64_t) m->info->display_picture->tag << 32 ) |
+                        ( (uint64_t) m->info->display_picture->tag2 );
+                }
+                else if( m->last_pts > -1 )
+                {
+                    /* For some reason nb_fields is sometimes 1 while it
+                       should be 2 */
+                    buf->start = m->last_pts +
+                        MAX( 2, m->info->display_picture->nb_fields ) *
+                        m->info->sequence->frame_period / 600;
+                }
+                else
+                {
+                    buf->start = -1;
+                }
+                m->last_pts = buf->start;
+
+                hb_list_add( list_raw, buf );
+            }
+        }
+        else if( state == STATE_INVALID )
+        {
+            mpeg2_reset( m->libmpeg2, 0 );
+        }
+    }
+    return 1;
+}
+
+/**********************************************************************
+ * hb_libmpeg2_info
+ **********************************************************************
+ * 
+ *********************************************************************/
+void hb_libmpeg2_info( hb_libmpeg2_t * m, int * width, int * height,
+                        int * rate )
+{
+    *width  = m->width;
+    *height = m->height;
+    *rate   = m->rate;
+}
+
+/**********************************************************************
+ * hb_libmpeg2_close
+ **********************************************************************
+ * 
+ *********************************************************************/
+void hb_libmpeg2_close( hb_libmpeg2_t ** _m )
+{
+    hb_libmpeg2_t * m = *_m;
+
+    mpeg2_close( m->libmpeg2 );
+
+    free( m );
+    *_m = NULL;
+}
+
+/**********************************************************************
+ * The decmpeg2 work object
+ **********************************************************************
+ * 
+ *********************************************************************/
+struct hb_work_object_s
+{
+    HB_WORK_COMMON;
+
+    hb_libmpeg2_t * libmpeg2;
+    hb_list_t     * list;
+};
+
+/***********************************************************************
+ * Local prototypes
+ **********************************************************************/
+static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+                 hb_buffer_t ** buf_out );
+static void Close( hb_work_object_t ** _w );
+
+/**********************************************************************
+ * hb_work_decmpeg2_init
+ **********************************************************************
+ * 
+ *********************************************************************/
+hb_work_object_t * hb_work_decmpeg2_init( hb_job_t * job )
+{
+    hb_work_object_t * w = calloc( sizeof( hb_work_object_t ), 1 );
+    w->name  = strdup( "MPEG-2 decoder (libmpeg2)" );
+    w->work  = Work;
+    w->close = Close;
+
+    w->libmpeg2 = hb_libmpeg2_init();
+    w->list     = hb_list_init();
+    return w;
+}
+
+/**********************************************************************
+ * Work
+ **********************************************************************
+ * 
+ *********************************************************************/
+static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+                 hb_buffer_t ** buf_out )
+{
+    hb_buffer_t * buf, * last = NULL;
+
+    hb_libmpeg2_decode( w->libmpeg2, *buf_in, w->list );
+
+    *buf_out = NULL;
+
+    while( ( buf = hb_list_item( w->list, 0 ) ) )
+    {
+        hb_list_rem( w->list, buf );
+        if( last )
+        {
+            last->next = buf;
+            last       = buf;
+        }
+        else
+        {
+            *buf_out = buf;
+            last     = buf;
+        }
+    }
+
+    return HB_WORK_OK;
+}
+
+/**********************************************************************
+ * Close
+ **********************************************************************
+ * 
+ *********************************************************************/
+static void Close( hb_work_object_t ** _w )
+{
+    hb_work_object_t * w = *_w;
+    hb_list_close( &w->list );
+    hb_libmpeg2_close( &w->libmpeg2 );
+    free( w->name );
+    free( w );
+    *_w = NULL;
+}
diff --git a/libhb/decsub.c b/libhb/decsub.c
new file mode 100644 (file)
index 0000000..72f742b
--- /dev/null
@@ -0,0 +1,420 @@
+/* $Id: decsub.c,v 1.12 2005/04/14 17:37:54 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 "hb.h"
+
+struct hb_work_object_s
+{
+    HB_WORK_COMMON;
+
+    hb_job_t * job;
+
+    uint8_t    buf[0xFFFF];
+    int        size_sub;
+    int        size_got;
+    int        size_rle;
+    int64_t    pts;
+    int64_t    pts_start;
+    int64_t    pts_stop;
+    int        x;
+    int        y;
+    int        width;
+    int        height;
+
+    int        offsets[2];
+    uint8_t    lum[4];
+    uint8_t    alpha[4];
+};
+
+
+/***********************************************************************
+ * Local prototypes
+ **********************************************************************/
+static void          Close( hb_work_object_t ** _w );
+static int           Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+                           hb_buffer_t ** buf_out );
+static hb_buffer_t * Decode( hb_work_object_t * w );
+static void          ParseControls( hb_work_object_t * w );
+static hb_buffer_t * CropSubtitle( hb_work_object_t * w,
+                                   uint8_t * raw );
+
+/***********************************************************************
+ * hb_work_decsub_init
+ ***********************************************************************
+ *
+ **********************************************************************/
+hb_work_object_t * hb_work_decsub_init( hb_job_t * job )
+{
+    hb_work_object_t * w = calloc( sizeof( hb_work_object_t ), 1 );
+    w->name  = strdup( "Subtitle decoder" );
+    w->work  = Work;
+    w->close = Close;
+
+    w->job   = job;
+    w->pts   = -1;
+
+    return w;
+}
+
+/***********************************************************************
+ * Close
+ ***********************************************************************
+ * Free memory
+ **********************************************************************/
+static void Close( hb_work_object_t ** _w )
+{
+    hb_work_object_t * w = *_w;
+    free( w->name );
+    free( w );
+    *_w = NULL;
+}
+
+/***********************************************************************
+ * Work
+ ***********************************************************************
+ *
+ **********************************************************************/
+static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+                 hb_buffer_t ** buf_out )
+{
+    hb_buffer_t * in = *buf_in;
+
+    int size_sub, size_rle;
+
+    size_sub = ( in->data[0] << 8 ) | in->data[1];
+    size_rle = ( in->data[2] << 8 ) | in->data[3];
+
+    if( !w->size_sub )
+    {
+        /* We are looking for the start of a new subtitle */
+        if( size_sub && size_rle && size_sub > size_rle &&
+            in->size <= size_sub )
+        {
+            /* Looks all right so far */
+            w->size_sub = size_sub;
+            w->size_rle = size_rle;
+
+            memcpy( w->buf, in->data, in->size );
+            w->size_got = in->size;
+            w->pts      = in->start;
+        }
+    }
+    else
+    {
+        /* We are waiting for the end of the current subtitle */
+        if( in->size <= w->size_sub - w->size_got )
+        {
+            memcpy( w->buf + w->size_got, in->data, in->size );
+            w->size_got += in->size;
+            if( in->start >= 0 )
+            {
+                w->pts = in->start;
+            }
+        }
+    }
+
+    *buf_out = NULL;
+
+    if( w->size_sub && w->size_sub == w->size_got )
+    {
+        /* We got a complete subtitle, decode it */
+        *buf_out = Decode( w );
+
+        /* Wait for the next one */
+        w->size_sub = 0;
+        w->size_got = 0;
+        w->size_rle = 0;
+        w->pts      = -1;
+    }
+
+    return HB_WORK_OK;
+}
+
+static hb_buffer_t * Decode( hb_work_object_t * w )
+{
+    int code, line, col;
+    int offsets[2];
+    int * offset;
+    hb_buffer_t * buf;
+    uint8_t * buf_raw = NULL;
+
+    /* Get infos about the subtitle */
+    ParseControls( w );
+
+    /* Do the actual decoding now */
+    buf_raw = malloc( w->width * w->height * 2 );
+
+#define GET_NEXT_NIBBLE code = ( code << 4 ) | ( ( ( *offset & 1 ) ? \
+( w->buf[((*offset)>>1)] & 0xF ) : ( w->buf[((*offset)>>1)] >> 4 ) ) ); \
+(*offset)++
+    
+    offsets[0] = w->offsets[0] * 2;
+    offsets[1] = w->offsets[1] * 2;
+
+    for( line = 0; line < w->height; line++ )
+    {
+        /* Select even or odd field */
+        offset = ( line & 1 ) ? &offsets[1] : &offsets[0];
+
+        for( col = 0; col < w->width; col += code >> 2 )
+        {
+            uint8_t * lum, * alpha;
+
+            code = 0;
+            GET_NEXT_NIBBLE;
+            if( code < 0x4 )
+            {
+                GET_NEXT_NIBBLE;
+                if( code < 0x10 )
+                {
+                    GET_NEXT_NIBBLE;
+                    if( code < 0x40 )
+                    {
+                        GET_NEXT_NIBBLE;
+                        if( code < 0x100 )
+                        {
+                            /* End of line */
+                            code |= ( w->width - col ) << 2;
+                        }
+                    }
+                }
+            }
+
+            lum   = buf_raw;
+            alpha = lum + w->width * w->height;
+            memset( lum + line * w->width + col,
+                    w->lum[code & 3], code >> 2 );
+            memset( alpha + line * w->width + col,
+                    w->alpha[code & 3], code >> 2 );
+        }
+
+        /* Byte-align */
+        if( *offset & 1 )
+        {
+            (*offset)++;
+        }
+    }
+
+    /* Crop subtitle (remove transparent borders) */
+    buf = CropSubtitle( w, buf_raw );
+
+    free( buf_raw );
+
+    return buf;
+}
+
+/***********************************************************************
+ * ParseControls
+ ***********************************************************************
+ * Get the start and end dates (relative to the PTS from the PES
+ * header), the width and height of the subpicture and the colors and
+ * alphas used in it
+ **********************************************************************/
+static void ParseControls( hb_work_object_t * w )
+{
+    hb_job_t * job = w->job;
+    hb_title_t * title = job->title;
+
+    int i;
+    int command;
+    int date, next;
+
+    for( i = w->size_rle; ; )
+    {
+        date = ( w->buf[i] << 8 ) | w->buf[i+1]; i += 2;
+        next = ( w->buf[i] << 8 ) | w->buf[i+1]; i += 2;
+
+        for( ;; )
+        {
+            command = w->buf[i++];
+
+            if( command == 0xFF )
+            {
+                break;
+            }
+
+            switch( command )
+            {
+                case 0x00:
+                    break;
+
+                case 0x01:
+                    w->pts_start = w->pts + date * 900;
+                    break;
+
+                case 0x02:
+                    w->pts_stop = w->pts + date * 900;
+                    break;
+
+                case 0x03:
+                {
+                    int colors[4];
+                    int j;
+
+                    colors[0] = (w->buf[i+0]>>4)&0x0f;
+                    colors[1] = (w->buf[i+0])&0x0f;
+                    colors[2] = (w->buf[i+1]>>4)&0x0f;
+                    colors[3] = (w->buf[i+1])&0x0f;
+
+                    for( j = 0; j < 4; j++ )
+                    {
+                        uint32_t color = title->palette[colors[j]];
+                        w->lum[3-j] = (color>>16) & 0xff;
+                    }
+                    i += 2;
+                    break;
+                }
+                case 0x04:
+                {
+                    w->alpha[3] = (w->buf[i+0]>>4)&0x0f;
+                    w->alpha[2] = (w->buf[i+0])&0x0f;
+                    w->alpha[1] = (w->buf[i+1]>>4)&0x0f;
+                    w->alpha[0] = (w->buf[i+1])&0x0f;
+                    i += 2;
+                    break;
+                }
+                case 0x05:
+                {
+                    w->x     = (w->buf[i+0]<<4) | ((w->buf[i+1]>>4)&0x0f);
+                    w->width = (((w->buf[i+1]&0x0f)<<8)| w->buf[i+2]) - w->x + 1;
+                    w->y     = (w->buf[i+3]<<4)| ((w->buf[i+4]>>4)&0x0f);
+                    w->height = (((w->buf[i+4]&0x0f)<<8)| w->buf[i+5]) - w->y + 1;
+                    i += 6;
+                    break;
+                }
+                case 0x06:
+                {
+                    w->offsets[0] = ( w->buf[i] << 8 ) | w->buf[i+1]; i += 2;
+                    w->offsets[1] = ( w->buf[i] << 8 ) | w->buf[i+1]; i += 2;
+                    break;
+                }
+            }
+        }
+
+        if( i > next )
+        {
+            break;
+        }
+        i = next;
+    }
+}
+
+/***********************************************************************
+ * CropSubtitle
+ ***********************************************************************
+ * Given a raw decoded subtitle, detects transparent borders and
+ * returns a cropped subtitle in a hb_buffer_t ready to be used by
+ * the renderer, or NULL if the subtitle was completely transparent
+ **********************************************************************/
+static int LineIsTransparent( hb_work_object_t * w, uint8_t * p )
+{
+    int i;
+    for( i = 0; i < w->width; i++ )
+    {
+        if( p[i] )
+        {
+            return 0;
+        }
+    }
+    return 1;
+}
+static int ColumnIsTransparent( hb_work_object_t * w, uint8_t * p )
+{
+    int i;
+    for( i = 0; i < w->height; i++ )
+    {
+        if( p[i*w->width] )
+        {
+            return 0;
+        }
+    }
+    return 1;
+}
+static hb_buffer_t * CropSubtitle( hb_work_object_t * w, uint8_t * raw )
+{
+    int i;
+    int crop[4] = { -1,-1,-1,-1 };
+    uint8_t * alpha;
+    int realwidth, realheight;
+    hb_buffer_t * buf;
+    uint8_t * lum_in, * lum_out, * alpha_in, * alpha_out;
+
+    alpha = raw + w->width * w->height;
+
+    /* Top */
+    for( i = 0; i < w->height; i++ )
+    {
+        if( !LineIsTransparent( w, &alpha[i*w->width] ) )
+        {
+            crop[0] = i;
+            break;
+        }
+    }
+
+    if( crop[0] < 0 )
+    {
+        /* Empty subtitle */
+        return NULL;
+    }
+
+    /* Bottom */
+    for( i = w->height - 1; i >= 0; i-- )
+    {
+        if( !LineIsTransparent( w, &alpha[i*w->width] ) )
+        {
+            crop[1] = i;
+            break;
+        }
+    }
+
+    /* Left */
+    for( i = 0; i < w->width; i++ )
+    {
+        if( !ColumnIsTransparent( w, &alpha[i] ) )
+        {
+            crop[2] = i;
+            break;
+        }
+    }
+
+    /* Right */
+    for( i = w->width - 1; i >= 0; i-- )
+    {
+        if( !ColumnIsTransparent( w, &alpha[i] ) )
+        {
+            crop[3] = i;
+            break;
+        }
+    }
+
+    realwidth  = crop[3] - crop[2] + 1;
+    realheight = crop[1] - crop[0] + 1;
+
+    buf         = hb_buffer_init( realwidth * realheight * 2 );
+    buf->start  = w->pts_start;
+    buf->stop   = w->pts_stop;
+    buf->x      = w->x + crop[2];
+    buf->y      = w->y + crop[0];
+    buf->width  = realwidth;
+    buf->height = realheight;
+
+    lum_in    = raw + crop[0] * w->width + crop[2];
+    alpha_in  = lum_in + w->width * w->height;
+    lum_out   = buf->data;
+    alpha_out = lum_out + realwidth * realheight;
+
+    for( i = 0; i < realheight; i++ )
+    {
+        memcpy( lum_out, lum_in, realwidth );
+        memcpy( alpha_out, alpha_in, realwidth );
+        lum_in    += w->width;
+        alpha_in  += w->width;
+        lum_out   += realwidth;
+        alpha_out += realwidth;
+    }
+
+    return buf;
+}
diff --git a/libhb/demuxmpeg.c b/libhb/demuxmpeg.c
new file mode 100644 (file)
index 0000000..721478e
--- /dev/null
@@ -0,0 +1,125 @@
+/* $Id: demuxmpeg.c,v 1.4 2004/10/19 23:11:36 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 "hb.h"
+
+/* Basic MPEG demuxer, only works with DVDs (2048 bytes packets) */
+
+int hb_demux_ps( hb_buffer_t * buf_ps, hb_list_t * list_es )
+{
+    hb_buffer_t * buf_es;
+    int           pos;
+
+    pos = 0;
+
+#define d (buf_ps->data)
+
+    /* pack_header */
+    if( d[pos] != 0 || d[pos+1] != 0 ||
+        d[pos+2] != 0x1 || d[pos+3] != 0xBA )
+    {
+        hb_log( "hb_demux_ps: not a PS packet (%02x%02x%02x%02x)",
+                d[pos], d[pos+1], d[pos+2], d[pos+3] );
+        return 0;
+    }
+    pos += 4;                    /* pack_start_code */
+    pos += 9;                    /* pack_header */
+    pos += 1 + ( d[pos] & 0x7 ); /* stuffing bytes */
+
+    /* system_header */
+    if( d[pos] == 0 && d[pos+1] == 0 &&
+        d[pos+2] == 0x1 && d[pos+3] == 0xBB )
+    {
+        int header_length;
+
+        pos           += 4; /* system_header_start_code */
+        header_length  = ( d[pos] << 8 ) + d[pos+1];
+        pos           += 2 + header_length;
+    }
+
+    /* pes */
+    while( pos + 6 < buf_ps->size &&
+           d[pos] == 0 && d[pos+1] == 0 && d[pos+2] == 0x1 )
+    {
+        int      id;
+        int      pes_packet_length;
+        int      pes_packet_end;
+        int      pes_header_d_length;
+        int      pes_header_end;
+        int      has_pts;
+        int64_t  pts = -1;
+
+        pos               += 3;               /* packet_start_code_prefix */
+        id           = d[pos];
+        pos               += 1;
+
+        pes_packet_length  = ( d[pos] << 8 ) + d[pos+1];
+        pos               += 2;               /* pes_packet_length */
+        pes_packet_end     = pos + pes_packet_length;
+
+        if( id != 0xE0 && id != 0xBD &&
+            ( id & 0xC0 ) != 0xC0  )
+        {
+            /* Not interesting */
+            pos = pes_packet_end;
+            continue;
+        }
+
+        has_pts             = ( ( d[pos+1] >> 6 ) & 0x2 ) ? 1 : 0;
+        pos               += 2;               /* Required headers */
+
+        pes_header_d_length  = d[pos];
+        pos                    += 1;
+        pes_header_end          = pos + pes_header_d_length;
+
+        if( has_pts )
+        {
+            pts = ( ( ( (uint64_t) d[pos] >> 1 ) & 0x7 ) << 30 ) +
+                  ( d[pos+1] << 22 ) +
+                  ( ( d[pos+2] >> 1 ) << 15 ) +
+                  ( d[pos+3] << 7 ) +
+                  ( d[pos+4] >> 1 );
+        }
+
+        pos = pes_header_end;
+
+        if( id == 0xBD )
+        {
+            id |= ( d[pos] << 8 );
+            if( ( id & 0xF0FF ) == 0x80BD ) /* A52 */
+            {
+                pos += 4;
+            }
+            else if( ( id & 0xE0FF ) == 0x20BD || /* SPU */
+                     ( id & 0xF0FF ) == 0xA0BD )  /* LPCM */
+            {
+                pos += 1;
+            }
+        }
+
+        /* Sanity check */
+        if( pos >= pes_packet_end )
+        {
+            pos = pes_packet_end;
+            continue;
+        }
+
+        /* Here we hit we ES payload */
+        buf_es = hb_buffer_init( pes_packet_end - pos );
+
+        buf_es->id    = id;
+        buf_es->start = pts;
+        memcpy( buf_es->data, d + pos, pes_packet_end - pos );
+
+        hb_list_add( list_es, buf_es );
+
+        pos = pes_packet_end;
+    }
+
+#undef d
+
+    return 1;
+}
diff --git a/libhb/dvd.c b/libhb/dvd.c
new file mode 100644 (file)
index 0000000..9b2aef1
--- /dev/null
@@ -0,0 +1,735 @@
+/* $Id: dvd.c,v 1.11 2005/11/04 15:30:47 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 "hb.h"
+#include "lang.h"
+
+#include "dvdread/ifo_read.h"
+#include "dvdread/nav_read.h"
+
+struct hb_dvd_s
+{
+    char         * path;
+
+    dvd_reader_t * reader;
+    ifo_handle_t * vmg;
+
+    int            vts;
+    int            ttn;
+    ifo_handle_t * ifo;
+    dvd_file_t   * file;
+
+    pgc_t        * pgc;
+    int            cell_start;
+    int            cell_end;
+    int            title_start;
+    int            title_end;
+    int            title_block_count;
+    int            cell_cur;
+    int            cell_next;
+    int            block;
+    int            pack_len;
+    int            next_vobu;
+};
+
+/***********************************************************************
+ * Local prototypes
+ **********************************************************************/
+static void FindNextCell( hb_dvd_t * );
+static int  dvdtime2msec( dvd_time_t * );
+
+/***********************************************************************
+ * hb_dvd_init
+ ***********************************************************************
+ *
+ **********************************************************************/
+hb_dvd_t * hb_dvd_init( char * path )
+{
+    hb_dvd_t * d;
+
+    d = calloc( sizeof( hb_dvd_t ), 1 );
+
+    /* Open device */
+    if( !( d->reader = DVDOpen( path ) ) )
+    {
+        hb_log( "dvd: DVDOpen failed (%s)", path );
+        goto fail;
+    }
+
+    /* Open main IFO */
+    if( !( d->vmg = ifoOpen( d->reader, 0 ) ) )
+    {
+        hb_log( "dvd: ifoOpen failed" );
+        goto fail;
+    }
+
+    d->path = strdup( path );
+
+    return d;
+
+fail:
+    if( d->vmg )    ifoClose( d->vmg );
+    if( d->reader ) DVDClose( d->reader );
+    free( d );
+    return NULL;
+}
+
+/***********************************************************************
+ * hb_dvd_title_count
+ **********************************************************************/
+int hb_dvd_title_count( hb_dvd_t * d )
+{
+    return d->vmg->tt_srpt->nr_of_srpts;
+}
+
+/***********************************************************************
+ * hb_dvd_title_scan
+ **********************************************************************/
+hb_title_t * hb_dvd_title_scan( hb_dvd_t * d, int t )
+{
+
+    hb_title_t   * title;
+    ifo_handle_t * vts = NULL;
+    int            pgc_id, pgn, i;
+    hb_chapter_t * chapter, * chapter_old;
+    int            c;
+    uint64_t       duration;
+    float          duration_correction;
+
+    title = hb_title_init( d->path, t );
+
+    hb_log( "scan: scanning title %d", t );
+
+    /* VTS which our title is in */
+    title->vts = d->vmg->tt_srpt->title[t-1].title_set_nr;
+
+    hb_log( "scan: opening IFO for VTS %d", title->vts );
+    if( !( vts = ifoOpen( d->reader, title->vts ) ) )
+    {
+        hb_log( "scan: ifoOpen failed" );
+        goto fail;
+    }
+
+    /* Position of the title in the VTS */
+    title->ttn = d->vmg->tt_srpt->title[t-1].vts_ttn;
+
+    /* Get pgc */
+    pgc_id = vts->vts_ptt_srpt->title[title->ttn-1].ptt[0].pgcn;
+    pgn    = vts->vts_ptt_srpt->title[title->ttn-1].ptt[0].pgn;
+    d->pgc = vts->vts_pgcit->pgci_srp[pgc_id-1].pgc;
+
+    /* Start cell */
+    title->cell_start  = d->pgc->program_map[pgn-1] - 1;
+    title->block_start = d->pgc->cell_playback[title->cell_start].first_sector;
+
+    /* End cell */
+    title->cell_end  = d->pgc->nr_of_cells - 1;
+    title->block_end = d->pgc->cell_playback[title->cell_end].last_sector;
+
+    /* Block count */
+    title->block_count = 0;
+    d->cell_cur = title->cell_start;
+    while( d->cell_cur <= title->cell_end )
+    {
+#define cp d->pgc->cell_playback[d->cell_cur]
+        title->block_count += cp.last_sector + 1 - cp.first_sector;
+#undef cp
+        FindNextCell( d );
+        d->cell_cur = d->cell_next;
+    }
+
+    hb_log( "scan: vts=%d, ttn=%d, cells=%d->%d, blocks=%d->%d, "
+            "%d blocks", title->vts, title->ttn, title->cell_start,
+            title->cell_end, title->block_start, title->block_end,
+            title->block_count );
+
+    if( title->block_count < 2048 )
+    {
+        hb_log( "scan: title too short (%d blocks), ignoring",
+                title->block_count );
+        goto fail;
+    }
+
+
+    /* Get duration */
+    title->duration = 90LL * dvdtime2msec( &d->pgc->playback_time );
+    title->hours    = title->duration / 90000 / 3600;
+    title->minutes  = ( ( title->duration / 90000 ) % 3600 ) / 60;
+    title->seconds  = ( title->duration / 90000 ) % 60;
+    hb_log( "scan: duration is %02d:%02d:%02d (%lld ms)",
+            title->hours, title->minutes, title->seconds,
+            title->duration / 90 );
+
+    /* Discard titles under 10 seconds */
+    if( !( title->hours | title->minutes ) && title->seconds < 10 )
+    {
+        hb_log( "scan: ignoring title (too short)" );
+        goto fail;
+    }
+
+    /* Detect languages */
+    for( i = 0; i < vts->vtsi_mat->nr_of_vts_audio_streams; i++ )
+    {
+        hb_audio_t * audio, * audio_tmp;
+        int          audio_format, lang_code, audio_control,
+                     position, j;
+
+        hb_log( "scan: checking audio %d", i + 1 );
+
+        audio = calloc( sizeof( hb_audio_t ), 1 );
+
+        audio_format  = vts->vtsi_mat->vts_audio_attr[i].audio_format;
+        lang_code     = vts->vtsi_mat->vts_audio_attr[i].lang_code;
+        audio_control =
+            vts->vts_pgcit->pgci_srp[pgc_id-1].pgc->audio_control[i];
+
+        if( !( audio_control & 0x8000 ) )
+        {
+            hb_log( "scan: audio channel is not active" );
+            free( audio );
+            continue;
+        }
+
+        position = ( audio_control & 0x7F00 ) >> 8;
+
+        switch( audio_format )
+        {
+            case 0x00:
+                audio->id    = ( ( 0x80 + position ) << 8 ) | 0xbd;
+                audio->codec = HB_ACODEC_AC3;
+                break;
+
+            case 0x02:
+            case 0x03:
+                audio->id    = 0xc0 + position;
+                audio->codec = HB_ACODEC_MPGA;
+                break;
+
+            case 0x04:
+                audio->id    = ( ( 0xa0 + position ) << 8 ) | 0xbd;
+                audio->codec = HB_ACODEC_LPCM;
+                break;
+
+            default:
+                audio->id    = 0;
+                audio->codec = 0;
+                hb_log( "scan: unknown audio codec (%x)",
+                        audio_format );
+                break;
+        }
+        if( !audio->id )
+        {
+            continue;
+        }
+
+        /* Check for duplicate tracks */
+        audio_tmp = NULL;
+        for( j = 0; j < hb_list_count( title->list_audio ); j++ )
+        {
+            audio_tmp = hb_list_item( title->list_audio, j );
+            if( audio->id == audio_tmp->id )
+            {
+                break;
+            }
+            audio_tmp = NULL;
+        }
+        if( audio_tmp )
+        {
+            hb_log( "scan: duplicate audio track" );
+            free( audio );
+            continue;
+        }
+
+        snprintf( audio->lang, sizeof( audio->lang ), "%s (%s)",
+            lang_for_code( vts->vtsi_mat->vts_audio_attr[i].lang_code ),
+            audio->codec == HB_ACODEC_AC3 ? "AC3" : ( audio->codec ==
+                HB_ACODEC_MPGA ? "MPEG" : "LPCM" ) );
+
+        hb_log( "scan: id=%x, lang=%s", audio->id,
+                audio->lang );
+
+        hb_list_add( title->list_audio, audio );
+    }
+
+    if( !hb_list_count( title->list_audio ) )
+    {
+        hb_log( "scan: ignoring title (no audio track)" );
+        goto fail;
+    }
+
+    memcpy( title->palette,
+            vts->vts_pgcit->pgci_srp[pgc_id-1].pgc->palette,
+            16 * sizeof( uint32_t ) );
+
+    /* Check for subtitles */
+    for( i = 0; i < vts->vtsi_mat->nr_of_vts_subp_streams; i++ )
+    {
+        hb_subtitle_t * subtitle;
+        int spu_control;
+        int position;
+
+        hb_log( "scan: checking subtitle %d", i + 1 );
+
+        spu_control =
+            vts->vts_pgcit->pgci_srp[pgc_id-1].pgc->subp_control[i];
+
+        if( !( spu_control & 0x80000000 ) )
+        {
+            hb_log( "scan: subtitle channel is not active" );
+            continue;
+        }
+
+        if( vts->vtsi_mat->vts_video_attr.display_aspect_ratio )
+        {
+            switch( vts->vtsi_mat->vts_video_attr.permitted_df )
+            {
+                case 1:
+                    position = spu_control & 0xFF;
+                    break;
+                case 2:
+                    position = ( spu_control >> 8 ) & 0xFF;
+                    break;
+                default:
+                    position = ( spu_control >> 16 ) & 0xFF;
+            }
+        }
+        else
+        {
+            position = ( spu_control >> 24 ) & 0x7F;
+        }
+
+        subtitle = calloc( sizeof( hb_subtitle_t ), 1 );
+        subtitle->id = ( ( 0x20 + position ) << 8 ) | 0xbd;
+        snprintf( subtitle->lang, sizeof( subtitle->lang ), "%s",
+            lang_for_code( vts->vtsi_mat->vts_subp_attr[i].lang_code ) );
+
+        hb_log( "scan: id=%x, lang=%s", subtitle->id,
+                subtitle->lang );
+
+        hb_list_add( title->list_subtitle, subtitle );
+    }
+
+    /* Chapters */
+    hb_log( "scan: title %d has %d chapters", t,
+            vts->vts_ptt_srpt->title[title->ttn-1].nr_of_ptts );
+    for( i = 0, c = 1;
+         i < vts->vts_ptt_srpt->title[title->ttn-1].nr_of_ptts; i++ )
+    {
+        int pgc_id_next, pgn_next;
+        pgc_t * pgc_next;
+
+        chapter = calloc( sizeof( hb_chapter_t ), 1 );
+        chapter->index = c;
+
+        pgc_id = vts->vts_ptt_srpt->title[title->ttn-1].ptt[i].pgcn;
+        pgn    = vts->vts_ptt_srpt->title[title->ttn-1].ptt[i].pgn;
+        d->pgc = vts->vts_pgcit->pgci_srp[pgc_id-1].pgc;
+
+        /* Start cell */
+        chapter->cell_start  = d->pgc->program_map[pgn-1] - 1;
+        chapter->block_start =
+            d->pgc->cell_playback[chapter->cell_start].first_sector;
+
+        /* End cell */
+        if( i != vts->vts_ptt_srpt->title[title->ttn-1].nr_of_ptts - 1 )
+        {
+            /* The cell before the starting cell of the next chapter,
+               or... */
+            pgc_id_next = vts->vts_ptt_srpt->title[title->ttn-1].ptt[i+1].pgcn;
+            pgn_next    = vts->vts_ptt_srpt->title[title->ttn-1].ptt[i+1].pgn;
+            pgc_next    = vts->vts_pgcit->pgci_srp[pgc_id_next-1].pgc;
+            chapter->cell_end = pgc_next->program_map[pgn_next-1] - 2;
+            if( chapter->cell_end < 0 )
+            {
+                /* Huh? */
+                free( chapter );
+                continue;
+            }
+        }
+        else
+        {
+            /* ... the last cell of the title */
+            chapter->cell_end = title->cell_end;
+        }
+        chapter->block_end =
+            d->pgc->cell_playback[chapter->cell_end].last_sector;
+
+        /* Block count, duration */
+        pgc_id = vts->vts_ptt_srpt->title[title->ttn-1].ptt[0].pgcn;
+        pgn    = vts->vts_ptt_srpt->title[title->ttn-1].ptt[0].pgn;
+        d->pgc = vts->vts_pgcit->pgci_srp[pgc_id-1].pgc;
+        chapter->block_count = 0;
+        chapter->duration = 0;
+
+        d->cell_cur = chapter->cell_start;
+        while( d->cell_cur <= chapter->cell_end )
+        {
+#define cp d->pgc->cell_playback[d->cell_cur]
+            chapter->block_count += cp.last_sector + 1 - cp.first_sector;
+            chapter->duration += 90LL * dvdtime2msec( &cp.playback_time );
+#undef cp
+            FindNextCell( d );
+            d->cell_cur = d->cell_next;
+        }
+
+        if( chapter->block_count < 2048 && chapter->index > 1 )
+        {
+            hb_log( "scan: chapter %d too short (%d blocks, "
+                    "cells=%d->%d), merging", chapter->index,
+                    chapter->block_count, chapter->cell_start,
+                    chapter->cell_end );
+            chapter_old = hb_list_item( title->list_chapter,
+                                        chapter->index - 2 );
+            chapter_old->cell_end    = chapter->cell_end;
+            chapter_old->block_end   = chapter->block_end;
+            chapter_old->block_count += chapter->block_count;
+            free( chapter );
+            chapter = chapter_old;
+        }
+        else
+        {
+            hb_list_add( title->list_chapter, chapter );
+            c++;
+        }
+    }
+
+    /* The durations we get for chapters aren't precise. Scale them so
+       the total matches the title duration */
+    duration = 0;
+    for( i = 0; i < hb_list_count( title->list_chapter ); i++ )
+    {
+        chapter = hb_list_item( title->list_chapter, i );
+        duration += chapter->duration;
+    }
+    duration_correction = (float) title->duration / (float) duration;
+    for( i = 0; i < hb_list_count( title->list_chapter ); i++ )
+    {
+        int seconds;
+        chapter            = hb_list_item( title->list_chapter, i );
+        chapter->duration  = duration_correction * chapter->duration;
+        seconds            = ( chapter->duration + 45000 ) / 90000;
+        chapter->hours     = seconds / 3600;
+        chapter->minutes   = ( seconds % 3600 ) / 60;
+        chapter->seconds   = seconds % 60;
+
+        hb_log( "scan: chap %d c=%d->%d, b=%d->%d (%d), %lld ms",
+                chapter->index, chapter->cell_start, chapter->cell_end,
+                chapter->block_start, chapter->block_end,
+                chapter->block_count, chapter->duration / 90 );
+    }
+
+    /* Get aspect. We don't get width/height/rate infos here as
+       they tend to be wrong */
+    switch( vts->vtsi_mat->vts_video_attr.display_aspect_ratio )
+    {
+        case 0:
+            title->aspect = HB_ASPECT_BASE * 4 / 3;
+            break;
+        case 3:
+            title->aspect = HB_ASPECT_BASE * 16 / 9;
+            break;
+        default:
+            hb_log( "scan: unknown aspect" );
+            goto fail;
+    }
+
+    hb_log( "scan: aspect = %d", title->aspect );
+
+    /* This title is ok so far */
+    goto cleanup;
+
+fail:
+    hb_list_close( &title->list_audio );
+    free( title );
+    title = NULL;
+
+cleanup:
+    if( vts ) ifoClose( vts );
+
+    return title;
+}
+
+/***********************************************************************
+ * hb_dvd_start
+ ***********************************************************************
+ * Title and chapter start at 1
+ **********************************************************************/
+int hb_dvd_start( hb_dvd_t * d, int title, int chapter )
+{
+    int pgc_id, pgn;
+    int i;
+
+    /* Open the IFO and the VOBs for this title */
+    d->vts = d->vmg->tt_srpt->title[title-1].title_set_nr;
+    d->ttn = d->vmg->tt_srpt->title[title-1].vts_ttn;
+    if( !( d->ifo = ifoOpen( d->reader, d->vts ) ) )
+    {
+        hb_log( "dvd: ifoOpen failed for VTS %d", d->vts );
+        return 0;
+    }
+    if( !( d->file = DVDOpenFile( d->reader, d->vts,
+                                  DVD_READ_TITLE_VOBS ) ) )
+    {
+        hb_log( "dvd: DVDOpenFile failed for VTS %d", d->vts );
+        return 0;
+    }
+
+    /* Get title first and last blocks */
+    pgc_id         = d->ifo->vts_ptt_srpt->title[d->ttn-1].ptt[0].pgcn;
+    pgn            = d->ifo->vts_ptt_srpt->title[d->ttn-1].ptt[0].pgn;
+    d->pgc         = d->ifo->vts_pgcit->pgci_srp[pgc_id-1].pgc;
+    d->cell_start  = d->pgc->program_map[pgn - 1] - 1;
+    d->cell_end    = d->pgc->nr_of_cells - 1;
+    d->title_start = d->pgc->cell_playback[d->cell_start].first_sector;
+    d->title_end   = d->pgc->cell_playback[d->cell_end].last_sector;
+
+    /* Block count */
+    d->title_block_count = 0;
+    for( i = d->cell_start; i <= d->cell_end; i++ )
+    {
+        d->title_block_count += d->pgc->cell_playback[i].last_sector + 1 -
+            d->pgc->cell_playback[i].first_sector;
+    }
+
+    /* Get pgc for the current chapter */
+    pgc_id = d->ifo->vts_ptt_srpt->title[d->ttn-1].ptt[chapter-1].pgcn;
+    pgn    = d->ifo->vts_ptt_srpt->title[d->ttn-1].ptt[chapter-1].pgn;
+    d->pgc = d->ifo->vts_pgcit->pgci_srp[pgc_id-1].pgc;
+
+    /* Get the two first cells */
+    d->cell_cur = d->pgc->program_map[pgn-1] - 1;
+    FindNextCell( d );
+
+    d->block     = d->pgc->cell_playback[d->cell_cur].first_sector;
+    d->next_vobu = d->block;
+    d->pack_len  = 0;
+
+    return 1;
+}
+
+/***********************************************************************
+ * hb_dvd_seek
+ ***********************************************************************
+ *
+ **********************************************************************/
+int hb_dvd_seek( hb_dvd_t * d, float f )
+{
+    int target;
+
+    target = d->title_start + (int) ( f * d->title_block_count );
+
+    /* Find the cell we shall start in */
+    d->cell_cur = d->cell_start;
+    FindNextCell( d );
+    for( ;; )
+    {
+        if( target < d->pgc->cell_playback[d->cell_cur].last_sector )
+        {
+            break;
+        }
+        d->cell_cur = d->cell_next;
+        FindNextCell( d );
+    }
+
+    /* Now let hb_dvd_read find the next VOBU */
+    d->next_vobu = target;
+    d->pack_len  = 0;
+
+    return 1;
+}
+
+/***********************************************************************
+ * hb_dvd_read
+ ***********************************************************************
+ *
+ **********************************************************************/
+int hb_dvd_read( hb_dvd_t * d, hb_buffer_t * b )
+{
+    if( !d->pack_len )
+    {
+        /* New pack */
+        dsi_t dsi_pack;
+        int   error;
+
+        error = 0;
+        
+        for( ;; )
+        {
+            int block, pack_len, next_vobu;
+
+            if( DVDReadBlocks( d->file, d->next_vobu, 1, b->data ) != 1 )
+            {
+                hb_log( "dvd: DVDReadBlocks failed (%d)", d->next_vobu );
+                return 0;
+            }
+
+            navRead_DSI( &dsi_pack, &b->data[DSI_START_BYTE] );
+            
+            block     = dsi_pack.dsi_gi.nv_pck_lbn;
+            pack_len  = dsi_pack.dsi_gi.vobu_ea;
+            next_vobu = block + ( dsi_pack.vobu_sri.next_vobu & 0x7fffffff );
+
+            if( pack_len >  0    &&
+                pack_len <  1024 &&
+                block    >= d->next_vobu &&
+                ( block <= d->title_start + d->title_block_count ||
+                  block <= d->title_end ) )
+            {
+                /* XXX
+                   This looks like a valid VOBU, but actually we are
+                   just hoping */
+                if( error )
+                {
+#if 0
+                    hb_log( "dvd: found VOBU at %d (b %d, l %d, n %d)",
+                            d->next_vobu, block, pack_len, next_vobu );
+#endif
+                }
+                d->block     = block;
+                d->pack_len  = pack_len;
+                d->next_vobu = next_vobu;
+                break;
+            }
+
+            /* Wasn't a valid VOBU, try next block */
+            if( !error )
+            {
+#if 0
+                hb_log( "dvd: looking for a VOBU (%d)", d->next_vobu );
+#endif
+            }
+
+            if( ++error > 1024 )
+            {
+                hb_log( "dvd: couldn't find a VOBU after 1024 blocks" );
+                return 0;
+            }
+
+            (d->next_vobu)++;
+        }
+
+        if( dsi_pack.vobu_sri.next_vobu == SRI_END_OF_CELL )
+        {
+            d->cell_cur  = d->cell_next;
+            d->next_vobu = d->pgc->cell_playback[d->cell_cur].first_sector;
+            FindNextCell( d );
+        }
+    }
+    else
+    {
+        if( DVDReadBlocks( d->file, d->block, 1, b->data ) != 1 )
+        {
+            hb_log( "reader: DVDReadBlocks failed (%d)", d->block );
+            return 0;
+        }
+        d->pack_len--;
+    }
+
+    d->block++;
+
+    return 1;
+}
+
+/***********************************************************************
+ * hb_dvd_chapter
+ ***********************************************************************
+ * Returns in which chapter the next block to be read is.
+ * Chapter numbers start at 1.
+ **********************************************************************/
+int hb_dvd_chapter( hb_dvd_t * d )
+{
+    int     i;
+    int     pgc_id, pgn;
+    pgc_t * pgc;
+
+    for( i = 0;
+         i < d->ifo->vts_ptt_srpt->title[d->ttn-1].nr_of_ptts;
+         i++ )
+    {
+        /* Get pgc for chapter (i+1) */
+        pgc_id = d->ifo->vts_ptt_srpt->title[d->ttn-1].ptt[i].pgcn;
+        pgn    = d->ifo->vts_ptt_srpt->title[d->ttn-1].ptt[i].pgn;
+        pgc    = d->ifo->vts_pgcit->pgci_srp[pgc_id-1].pgc;
+
+        if( d->cell_cur >= pgc->program_map[pgn-1] - 1 &&
+            d->cell_cur <= pgc->nr_of_cells - 1 )
+        {
+            /* We are in this chapter */
+            return i + 1;
+        }
+    }
+
+    /* End of title */
+    return -1;
+}
+
+/***********************************************************************
+ * hb_dvd_close
+ ***********************************************************************
+ * Closes and frees everything
+ **********************************************************************/
+void hb_dvd_close( hb_dvd_t ** _d )
+{
+    hb_dvd_t * d = *_d;
+
+    if( d->ifo )    ifoClose( d->ifo );
+    if( d->vmg )    ifoClose( d->vmg );
+    if( d->file )   DVDCloseFile( d->file );
+    if( d->reader ) DVDClose( d->reader );
+
+    free( d );
+    *_d = NULL;
+}
+
+/***********************************************************************
+ * FindNextCell
+ ***********************************************************************
+ * Assumes pgc and cell_cur are correctly set, and sets cell_next to the
+ * cell to be read when we will be done with cell_cur.
+ **********************************************************************/
+static void FindNextCell( hb_dvd_t * d )
+{
+    int i = 0;
+
+    if( d->pgc->cell_playback[d->cell_cur].block_type ==
+            BLOCK_TYPE_ANGLE_BLOCK )
+    {
+
+        while( d->pgc->cell_playback[d->cell_cur+i].block_mode !=
+                   BLOCK_MODE_LAST_CELL )
+        {
+             i++;
+        }
+        d->cell_next = d->cell_cur + i + 1;
+    }
+    else
+    {
+        d->cell_next = d->cell_cur + 1;
+    }
+}
+
+/***********************************************************************
+ * dvdtime2msec
+ ***********************************************************************
+ * From lsdvd
+ **********************************************************************/
+static int dvdtime2msec(dvd_time_t * dt)
+{
+    double frames_per_s[4] = {-1.0, 25.00, -1.0, 29.97};
+    double fps = frames_per_s[(dt->frame_u & 0xc0) >> 6];
+    long   ms;
+    ms  = (((dt->hour &   0xf0) >> 3) * 5 + (dt->hour   & 0x0f)) * 3600000;
+    ms += (((dt->minute & 0xf0) >> 3) * 5 + (dt->minute & 0x0f)) * 60000;
+    ms += (((dt->second & 0xf0) >> 3) * 5 + (dt->second & 0x0f)) * 1000;
+
+    if( fps > 0 )
+    {
+        ms += ((dt->frame_u & 0x30) >> 3) * 5 +
+              (dt->frame_u & 0x0f) * 1000.0 / fps;
+    }
+
+    return ms;
+}
diff --git a/libhb/encavcodec.c b/libhb/encavcodec.c
new file mode 100644 (file)
index 0000000..deff7c5
--- /dev/null
@@ -0,0 +1,201 @@
+/* $Id: encavcodec.c,v 1.23 2005/10/13 23:47:06 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 "hb.h"
+
+#include "ffmpeg/avcodec.h"
+
+struct hb_work_object_s
+{
+    HB_WORK_COMMON;
+
+    hb_job_t * job;
+    AVCodecContext * context;
+    FILE * file;
+};
+
+/***********************************************************************
+ * Local prototypes
+ **********************************************************************/
+static void Close( hb_work_object_t ** _w );
+static int  Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+                  hb_buffer_t ** buf_out );
+
+/***********************************************************************
+ * hb_work_encavcodec_init
+ ***********************************************************************
+ *
+ **********************************************************************/
+hb_work_object_t * hb_work_encavcodec_init( hb_job_t * job )
+{
+    AVCodec * codec;
+    AVCodecContext * context;
+    
+    hb_work_object_t * w = calloc( sizeof( hb_work_object_t ), 1 );
+    w->name  = strdup( "MPEG-4 encoder (libavcodec)" );
+    w->work  = Work;
+    w->close = Close;
+
+    w->job = job;
+
+    codec = avcodec_find_encoder( CODEC_ID_MPEG4 );
+    if( !codec )
+    {
+        hb_log( "hb_work_encavcodec_init: avcodec_find_encoder "
+                "failed" );
+    }
+    context = avcodec_alloc_context();
+    if( job->vquality < 0.0 || job->vquality > 1.0 )
+    {
+        /* Rate control */
+        context->bit_rate = 1000 * job->vbitrate;
+        context->bit_rate_tolerance = 10 * context->bit_rate;
+    }
+    else
+    {
+        /* Constant quantizer */
+        context->qmin = 31 - job->vquality * 30;
+        context->qmax = context->qmin;
+        hb_log( "encavcodec: encoding at constant quantizer %d",
+                context->qmin );
+    }
+    context->width     = job->width;
+    context->height    = job->height;
+    context->time_base = (AVRational) { job->vrate_base, job->vrate };
+    context->gop_size  = 10 * job->vrate / job->vrate_base;
+    context->pix_fmt   = PIX_FMT_YUV420P;
+
+    if( job->mux & HB_MUX_MP4 )
+    {
+        context->flags |= CODEC_FLAG_GLOBAL_HEADER;
+    }
+    if( job->grayscale )
+    {
+        context->flags |= CODEC_FLAG_GRAY;
+    }
+
+    if( job->pass )
+    {
+        char filename[1024]; memset( filename, 0, 1024 );
+        hb_get_tempory_filename( job->h, filename, "ffmpeg.log" );
+
+        if( job->pass == 1 )
+        {
+            w->file = fopen( filename, "wb" );
+            context->flags |= CODEC_FLAG_PASS1;
+        }
+        else
+        {
+            int    size;
+            char * log;
+
+            w->file = fopen( filename, "rb" );
+            fseek( w->file, 0, SEEK_END );
+            size = ftell( w->file );
+            fseek( w->file, 0, SEEK_SET );
+            log = malloc( size + 1 );
+            log[size] = '\0';
+            fread( log, size, 1, w->file );
+            fclose( w->file );
+            w->file = NULL;
+
+            context->flags    |= CODEC_FLAG_PASS2;
+            context->stats_in  = log;
+        }
+    }
+
+    if( avcodec_open( context, codec ) )
+    {
+        hb_log( "hb_work_encavcodec_init: avcodec_open failed" );
+    }
+    w->context = context;
+
+    if( ( job->mux & HB_MUX_MP4 ) && job->pass != 1 )
+    {
+#define c job->config.mpeg4
+        /* Hem hem */
+        c.config        = malloc( 15 );
+        c.config_length = 15;
+        memcpy( c.config, context->extradata + 15, 15 );
+#undef c
+    }
+    
+    return w;
+}
+
+/***********************************************************************
+ * Close
+ ***********************************************************************
+ *
+ **********************************************************************/
+static void Close( hb_work_object_t ** _w )
+{
+    hb_work_object_t * w = *_w;
+    hb_job_t * job = w->job;
+
+    if( w->context )
+    {
+        hb_log( "encavcodec: closing libavcodec" );
+        avcodec_close( w->context );
+    }
+    if( w->file )
+    {
+        fclose( w->file );
+    }
+    if( job->es_config )
+    {
+        free( job->es_config );
+        job->es_config = NULL;
+        job->es_config_length = 0;
+    }
+
+    free( w->name );
+    free( w );
+    *_w = NULL;
+}
+
+/***********************************************************************
+ * Work
+ ***********************************************************************
+ *
+ **********************************************************************/
+static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+                 hb_buffer_t ** buf_out )
+{
+    hb_job_t * job = w->job;
+    AVFrame  * frame;
+    hb_buffer_t * in = *buf_in, * buf;
+
+    frame              = avcodec_alloc_frame();
+    frame->data[0]     = in->data;
+    frame->data[1]     = frame->data[0] + job->width * job->height;
+    frame->data[2]     = frame->data[1] + job->width * job->height / 4;
+    frame->linesize[0] = job->width;
+    frame->linesize[1] = job->width / 2;
+    frame->linesize[2] = job->width / 2;
+
+    /* Should be way too large */
+    buf = hb_buffer_init( 3 * job->width * job->height / 2 );
+    buf->size = avcodec_encode_video( w->context, buf->data, buf->alloc,
+                                      frame );
+    buf->start = in->start;
+    buf->stop  = in->stop;
+    buf->key   = w->context->coded_frame->key_frame;
+
+    av_free( frame );
+
+    if( job->pass == 1 )
+    {
+        /* Write stats */
+        fprintf( w->file, "%s", w->context->stats_out );
+    }
+
+    *buf_out = buf;
+
+    return HB_WORK_OK;
+}
+
+
diff --git a/libhb/encfaac.c b/libhb/encfaac.c
new file mode 100644 (file)
index 0000000..a5b704f
--- /dev/null
@@ -0,0 +1,166 @@
+/* $Id: encfaac.c,v 1.13 2005/03/03 17:21:57 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 "hb.h"
+
+#include "faac.h"
+
+struct hb_work_object_s
+{
+    HB_WORK_COMMON;
+
+    hb_job_t   * job;
+    hb_audio_t * audio;
+
+    faacEncHandle * faac;
+    unsigned long   input_samples;
+    unsigned long   output_bytes;
+    uint8_t       * buf;
+
+    hb_list_t     * list;
+    int64_t         pts;
+};
+
+/***********************************************************************
+ * Local prototypes
+ **********************************************************************/
+static void Close( hb_work_object_t ** _w );
+static int  Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+                  hb_buffer_t ** buf_out );
+
+/***********************************************************************
+ * hb_work_encfaac_init
+ ***********************************************************************
+ *
+ **********************************************************************/
+hb_work_object_t * hb_work_encfaac_init( hb_job_t * job, hb_audio_t * audio )
+{
+    hb_work_object_t * w = calloc( sizeof( hb_work_object_t ), 1 );
+    faacEncConfigurationPtr cfg;
+    w->name  = strdup( "AAC encoder (libfaac)" );
+    w->work  = Work;
+    w->close = Close;
+
+    w->job   = job;
+    w->audio = audio;
+
+    w->faac = faacEncOpen( job->arate, 2, &w->input_samples,
+                           &w->output_bytes );
+    w->buf  = malloc( w->input_samples * sizeof( float ) );
+    
+    cfg                = faacEncGetCurrentConfiguration( w->faac );
+    cfg->mpegVersion   = MPEG4;
+    cfg->aacObjectType = LOW;
+    cfg->allowMidside  = 1;
+    cfg->useLfe        = 0;
+    cfg->useTns        = 0;
+    cfg->bitRate       = job->abitrate * 500; /* Per channel */
+    cfg->bandWidth     = 0;
+    cfg->outputFormat  = 0;
+    cfg->inputFormat   =  FAAC_INPUT_FLOAT;
+    if( !faacEncSetConfiguration( w->faac, cfg ) )
+    {
+        hb_log( "faacEncSetConfiguration failed" );
+    }
+    if( faacEncGetDecoderSpecificInfo( w->faac, &audio->config.faac.decinfo,
+                                       &audio->config.faac.size ) < 0 )
+    {
+        hb_log( "faacEncGetDecoderSpecificInfo failed" );
+    }
+
+    w->list = hb_list_init();
+    w->pts  = -1;
+
+    return w;
+}
+
+/***********************************************************************
+ * Close
+ ***********************************************************************
+ *
+ **********************************************************************/
+static void Close( hb_work_object_t ** _w )
+{
+    hb_work_object_t * w = *_w;
+
+    faacEncClose( w->faac );
+    free( w->buf );
+    hb_list_empty( &w->list );
+    free( w->audio->config.faac.decinfo );
+
+    free( w->name );
+    free( w );
+    *_w = NULL;
+}
+
+/***********************************************************************
+ * Encode
+ ***********************************************************************
+ *
+ **********************************************************************/
+static hb_buffer_t * Encode( hb_work_object_t * w )
+{
+    hb_buffer_t * buf;
+    uint64_t      pts;
+    int           pos;
+
+    if( hb_list_bytes( w->list ) < w->input_samples * sizeof( float ) )
+    {
+        /* Need more data */
+        return NULL;
+    }
+
+    hb_list_getbytes( w->list, w->buf, w->input_samples * sizeof( float ),
+                      &pts, &pos );
+
+    buf        = hb_buffer_init( w->output_bytes );
+    buf->start = pts + 90000 * pos / 2 / sizeof( float ) / w->job->arate;
+    buf->stop  = buf->start + 90000 * w->input_samples / w->job->arate / 2;
+    buf->size  = faacEncEncode( w->faac, (int32_t *) w->buf,
+            w->input_samples, buf->data, w->output_bytes );
+    buf->key   = 1;
+
+    if( !buf->size )
+    {
+        /* Encoding was successful but we got no data. Try to encode
+           more */
+        hb_buffer_close( &buf );
+        return Encode( w );
+    }
+    else if( buf->size < 0 )
+    {
+        hb_log( "faacEncEncode failed" );
+        hb_buffer_close( &buf );
+        return NULL;
+    }
+
+    return buf;
+}
+
+/***********************************************************************
+ * Work
+ ***********************************************************************
+ *
+ **********************************************************************/
+static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+                 hb_buffer_t ** buf_out )
+{
+    hb_buffer_t * buf;
+
+    hb_list_add( w->list, *buf_in );
+    *buf_in = NULL;
+
+    *buf_out = buf = Encode( w );
+
+    while( buf )
+    {
+        buf->next = Encode( w );
+        buf       = buf->next;
+    }
+    
+    return HB_WORK_OK;
+}
+
diff --git a/libhb/enclame.c b/libhb/enclame.c
new file mode 100644 (file)
index 0000000..19014ac
--- /dev/null
@@ -0,0 +1,154 @@
+/* $Id: enclame.c,v 1.9 2005/03/05 14:27:05 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 "hb.h"
+
+#include "lame/lame.h"
+
+struct hb_work_object_s
+{
+    HB_WORK_COMMON;
+
+    hb_job_t   * job;
+    hb_audio_t * audio;
+
+    /* LAME handle */
+    lame_global_flags * lame;
+
+    unsigned long   input_samples;
+    unsigned long   output_bytes;
+    uint8_t       * buf;
+
+    hb_list_t     * list;
+    int64_t         pts;
+};
+
+/***********************************************************************
+ * Local prototypes
+ **********************************************************************/
+static void Close( hb_work_object_t ** _w );
+static int  Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+                  hb_buffer_t ** buf_out );
+
+/***********************************************************************
+ * hb_work_enclame_init
+ ***********************************************************************
+ *
+ **********************************************************************/
+hb_work_object_t * hb_work_enclame_init( hb_job_t * job, hb_audio_t * audio )
+{
+    hb_work_object_t * w = calloc( sizeof( hb_work_object_t ), 1 );
+    w->name  = strdup( "MP3 encoder (libmp3lame)" );
+    w->work  = Work;
+    w->close = Close;
+
+    w->job   = job;
+    w->audio = audio;
+
+    hb_log( "enclame: opening libmp3lame" );
+
+    w->lame = lame_init();
+    lame_set_brate( w->lame, job->abitrate );
+    lame_set_in_samplerate( w->lame, job->arate );
+    lame_set_out_samplerate( w->lame, job->arate );
+    lame_init_params( w->lame );
+    
+    w->input_samples = 1152 * 2;
+    w->output_bytes = LAME_MAXMP3BUFFER;
+    w->buf  = malloc( w->input_samples * sizeof( float ) );
+
+    w->list = hb_list_init();
+    w->pts  = -1;
+
+    return w;
+}
+
+/***********************************************************************
+ * Close
+ ***********************************************************************
+ *
+ **********************************************************************/
+static void Close( hb_work_object_t ** _w )
+{
+    hb_work_object_t * w = *_w;
+    free( w->name );
+    free( w );
+    *_w = NULL;
+}
+
+/***********************************************************************
+ * Encode
+ ***********************************************************************
+ *
+ **********************************************************************/
+static hb_buffer_t * Encode( hb_work_object_t * w )
+{
+    hb_buffer_t * buf;
+    int16_t samples_s16[1152 * 2];
+    uint64_t pts;
+    int      pos, i;
+
+    if( hb_list_bytes( w->list ) < w->input_samples * sizeof( float ) )
+    {
+        return NULL;
+    }
+
+    hb_list_getbytes( w->list, w->buf, w->input_samples * sizeof( float ),
+                      &pts, &pos);
+
+    for( i = 0; i < 1152 * 2; i++ )
+    {
+        samples_s16[i] = ((float*) w->buf)[i];
+    }
+
+    buf        = hb_buffer_init( w->output_bytes );
+    buf->start = pts + 90000 * pos / 2 / sizeof( float ) / w->job->arate;
+    buf->stop  = buf->start + 90000 * 1152 / w->job->arate;
+    buf->size  = lame_encode_buffer_interleaved( w->lame, samples_s16,
+            1152, buf->data, LAME_MAXMP3BUFFER );
+    buf->key   = 1;
+
+    if( !buf->size )
+    {
+        /* Encoding was successful but we got no data. Try to encode
+           more */
+        hb_buffer_close( &buf );
+        return Encode( w );
+    }
+    else if( buf->size < 0 )
+    {
+        hb_log( "enclame: lame_encode_buffer failed" );
+        hb_buffer_close( &buf );
+        return NULL;
+    }
+
+    return buf;
+}
+
+/***********************************************************************
+ * Work
+ ***********************************************************************
+ *
+ **********************************************************************/
+static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+                 hb_buffer_t ** buf_out )
+{
+    hb_buffer_t * buf;
+
+    hb_list_add( w->list, *buf_in );
+    *buf_in = NULL;
+
+    *buf_out = buf = Encode( w );
+
+    while( buf )
+    {
+        buf->next = Encode( w );
+        buf       = buf->next;
+    }
+
+    return HB_WORK_OK;
+}
+
diff --git a/libhb/encvorbis.c b/libhb/encvorbis.c
new file mode 100644 (file)
index 0000000..86b8243
--- /dev/null
@@ -0,0 +1,205 @@
+/* $Id: encvorbis.c,v 1.6 2005/03/05 15:08:32 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 "hb.h"
+
+#include "vorbis/vorbisenc.h"
+
+#define OGGVORBIS_FRAME_SIZE 1024
+
+struct hb_work_object_s
+{
+    HB_WORK_COMMON;
+
+    hb_job_t   * job;
+    hb_audio_t * audio;
+
+    vorbis_info        vi;
+    vorbis_comment     vc;
+    vorbis_dsp_state   vd;
+    vorbis_block       vb;
+
+    unsigned long   input_samples;
+    uint8_t       * buf;
+    uint64_t        pts;
+
+    hb_list_t     * list;
+};
+
+/***********************************************************************
+ * Local prototypes
+ **********************************************************************/
+static void Close( hb_work_object_t ** _w );
+static int  Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+                  hb_buffer_t ** buf_out );
+
+/***********************************************************************
+ * hb_work_encvorbis_init
+ ***********************************************************************
+ *
+ **********************************************************************/
+hb_work_object_t * hb_work_encvorbis_init( hb_job_t * job, hb_audio_t * audio )
+{
+    int i;
+    ogg_packet header[3];
+
+    hb_work_object_t * w = calloc( sizeof( hb_work_object_t ), 1 );
+    w->name  = strdup( "Vorbis encoder (libvorbis)" );
+    w->work  = Work;
+    w->close = Close;
+
+    w->job   = job;
+    w->audio = audio;
+
+    hb_log( "encvorbis: opening libvorbis" );
+
+    /* init */
+    vorbis_info_init( &w->vi );
+    if( vorbis_encode_setup_managed( &w->vi, 2,
+          job->arate, -1, 1000 * job->abitrate, -1 ) ||
+        vorbis_encode_ctl( &w->vi, OV_ECTL_RATEMANAGE_AVG, NULL ) ||
+          vorbis_encode_setup_init( &w->vi ) )
+    {
+        hb_log( "encvorbis: vorbis_encode_setup_managed failed" );
+    }
+
+    /* add a comment */
+    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( &w->vd, &w->vi);
+    vorbis_block_init( &w->vd, &w->vb);
+
+    /* get the 3 headers */
+    vorbis_analysis_headerout( &w->vd, &w->vc,
+                               &header[0], &header[1], &header[2] );
+    for( i = 0; i < 3; i++ )
+    {
+        audio->config.vorbis.headers[i] =
+            malloc( sizeof( ogg_packet ) + header[i].bytes );
+        memcpy( audio->config.vorbis.headers[i], &header[i],
+                sizeof( ogg_packet ) );
+        memcpy( audio->config.vorbis.headers[i] + sizeof( ogg_packet ),
+                header[i].packet, header[i].bytes );
+    }
+
+    w->input_samples = 2 * OGGVORBIS_FRAME_SIZE;
+    w->buf = malloc( w->input_samples * sizeof( float ) );
+
+    w->list = hb_list_init();
+
+    return w;
+}
+
+/***********************************************************************
+ * Close
+ ***********************************************************************
+ *
+ **********************************************************************/
+static void Close( hb_work_object_t ** _w )
+{
+    hb_work_object_t * w = *_w;
+    free( w->name );
+    free( w );
+    *_w = NULL;
+}
+
+/***********************************************************************
+ * Flush
+ ***********************************************************************
+ *
+ **********************************************************************/
+static hb_buffer_t * Flush( hb_work_object_t * w )
+{
+    hb_buffer_t * buf;
+
+    if( vorbis_analysis_blockout( &w->vd, &w->vb ) == 1 )
+    {
+        ogg_packet op;
+
+        vorbis_analysis( &w->vb, NULL );
+        vorbis_bitrate_addblock( &w->vb );
+
+        if( vorbis_bitrate_flushpacket( &w->vd, &op ) )
+        {
+            buf = hb_buffer_init( sizeof( ogg_packet ) + op.bytes );
+            memcpy( buf->data, &op, sizeof( ogg_packet ) );
+            memcpy( buf->data + sizeof( ogg_packet ), op.packet,
+                    op.bytes );
+            buf->key   = 1;
+            buf->start = w->pts; /* No exact, but who cares - the OGM
+                                    muxer doesn't use it */
+            buf->stop  = buf->start +
+                90000 * OGGVORBIS_FRAME_SIZE + w->job->arate;
+
+            return buf;
+        }
+    }
+
+    return NULL;
+}
+
+/***********************************************************************
+ * Encode
+ ***********************************************************************
+ *
+ **********************************************************************/
+static hb_buffer_t * Encode( hb_work_object_t * w )
+{
+    hb_buffer_t * buf;
+    float ** buffer;
+    int i;
+
+    /* Try to extract more data */
+    if( ( buf = Flush( w ) ) )
+    {
+        return buf;
+    }
+
+    if( hb_list_bytes( w->list ) < w->input_samples * sizeof( float ) )
+    {
+        return NULL;
+    }
+
+    /* Process more samples */
+    hb_list_getbytes( w->list, w->buf, w->input_samples * sizeof( float ),
+                      &w->pts, NULL );
+    buffer = vorbis_analysis_buffer( &w->vd, OGGVORBIS_FRAME_SIZE );
+    for( i = 0; i < OGGVORBIS_FRAME_SIZE; i++ )
+    {
+        buffer[0][i] = ((float *) w->buf)[2*i]   / 32768.f;
+        buffer[1][i] = ((float *) w->buf)[2*i+1] / 32768.f;
+    }
+    vorbis_analysis_wrote( &w->vd, OGGVORBIS_FRAME_SIZE );
+
+    /* Try to extract again */
+    return Flush( w );
+}
+
+/***********************************************************************
+ * Work
+ ***********************************************************************
+ *
+ **********************************************************************/
+static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+                 hb_buffer_t ** buf_out )
+{
+    hb_buffer_t * buf;
+
+    hb_list_add( w->list, *buf_in );
+    *buf_in = NULL;
+
+    *buf_out = buf = Encode( w );
+
+    while( buf )
+    {
+        buf->next = Encode( w );
+        buf       = buf->next;
+    }
+
+    return HB_WORK_OK;
+}
diff --git a/libhb/encx264.c b/libhb/encx264.c
new file mode 100644 (file)
index 0000000..cf58452
--- /dev/null
@@ -0,0 +1,221 @@
+/* $Id: encx264.c,v 1.21 2005/11/04 13:09:41 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 <stdarg.h>
+
+#include "hb.h"
+
+#include "x264.h"
+
+struct hb_work_object_s
+{
+    HB_WORK_COMMON;
+
+    hb_job_t       * job;
+    x264_t         * x264;
+    x264_picture_t   pic_in;
+    x264_picture_t   pic_out;
+
+    char             filename[1024];
+};
+
+/***********************************************************************
+ * Local prototypes
+ **********************************************************************/
+static int  Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+                  hb_buffer_t ** buf_out );
+static void Close( hb_work_object_t ** _w );
+
+/***********************************************************************
+ * hb_work_encx264_init
+ ***********************************************************************
+ *
+ **********************************************************************/
+hb_work_object_t * hb_work_encx264_init( hb_job_t * job )
+{
+    hb_work_object_t * w;
+    x264_param_t       param;
+    x264_nal_t       * nal;
+    int                nal_count;
+
+    w        = calloc( sizeof( hb_work_object_t ), 1 );
+    w->name  = strdup( "AVC encoder (libx264)" );
+    w->work  = Work;
+    w->close = Close;
+
+    w->job = job;
+
+    memset( w->filename, 0, 1024 );
+    hb_get_tempory_filename( job->h, w->filename, "x264.log" );
+
+    x264_param_default( &param );
+
+    param.i_threads    = hb_get_cpu_count();
+    param.i_width      = job->width;
+    param.i_height     = job->height;
+    param.i_fps_num    = job->vrate;
+    param.i_fps_den    = job->vrate_base;
+    param.i_keyint_max = 20 * job->vrate / job->vrate_base;
+    param.i_log_level  = X264_LOG_NONE;
+    if( job->h264_13 )
+    {
+        param.b_cabac     = 0;
+        param.i_level_idc = 13;
+    }
+
+    /* Slightly faster with minimal quality lost */
+    param.analyse.i_subpel_refine = 4;
+
+    if( job->vquality >= 0.0 && job->vquality <= 1.0 )
+    {
+        /* Constant QP */
+        param.rc.i_qp_constant = 51 - job->vquality * 51;
+        hb_log( "encx264: encoding at constant QP %d",
+                param.rc.i_qp_constant );
+    }
+    else
+    {
+        /* Rate control */
+        param.rc.b_cbr     = 1;
+        param.rc.i_bitrate = job->vbitrate;
+        switch( job->pass )
+        {
+            case 1:
+                param.rc.b_stat_write  = 1;
+                param.rc.psz_stat_out = w->filename;
+                break;
+            case 2:
+                param.rc.b_stat_read = 1;
+                param.rc.psz_stat_in = w->filename;
+                break;
+        }
+    }
+
+    hb_log( "encx264: opening libx264 (pass %d)", job->pass );
+    w->x264 = x264_encoder_open( &param );
+
+#define c job->config.h264
+    x264_encoder_headers( w->x264, &nal, &nal_count );
+
+    /* Sequence Parameter Set */
+    c.sps_length = 1 + nal[1].i_payload;
+    c.sps        = malloc( c.sps_length);
+    c.sps[0]     = 0x67;
+    memcpy( &c.sps[1], nal[1].p_payload, nal[1].i_payload );
+
+    /* Picture Parameter Set */
+    c.pps_length = 1 + nal[2].i_payload;
+    c.pps        = malloc( c.pps_length );
+    c.pps[0]     = 0x68;
+    memcpy( &c.pps[1], nal[2].p_payload, nal[2].i_payload );
+#undef c
+
+    x264_picture_alloc( &w->pic_in, X264_CSP_I420,
+                        job->width, job->height );
+
+    return w;
+}
+
+static void Close( hb_work_object_t ** _w )
+{
+    hb_work_object_t * w = *_w;
+
+    x264_encoder_close( w->x264 );
+
+    /* TODO */
+
+    free( w->name );
+    free( w );
+    *_w = NULL;
+}
+
+static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+                 hb_buffer_t ** buf_out )
+{
+    hb_job_t    * job = w->job;
+    hb_buffer_t * in = *buf_in, * buf;
+    int           i_nal;
+    x264_nal_t  * nal;
+    int i;
+
+    /* XXX avoid this memcpy ? */
+    memcpy( w->pic_in.img.plane[0], in->data, job->width * job->height );
+    if( job->grayscale )
+    {
+        /* XXX x264 has currently no option for grayscale encoding */
+        memset( w->pic_in.img.plane[1], 0x80, job->width * job->height / 4 );
+        memset( w->pic_in.img.plane[2], 0x80, job->width * job->height / 4 );
+    }
+    else
+    {
+        memcpy( w->pic_in.img.plane[1], in->data + job->width * job->height,
+                job->width * job->height / 4 );
+        memcpy( w->pic_in.img.plane[2], in->data + 5 * job->width *
+                job->height / 4, job->width * job->height / 4 );
+    }
+
+    w->pic_in.i_type    = X264_TYPE_AUTO;
+    w->pic_in.i_qpplus1 = 0;
+
+    x264_encoder_encode( w->x264, &nal, &i_nal,
+                         &w->pic_in, &w->pic_out );
+
+    /* Should be way too large */
+    buf        = hb_buffer_init( 3 * job->width * job->height / 2 );
+    buf->size  = 0;
+    buf->start = in->start;
+    buf->stop  = in->stop;
+    buf->key   = 0;
+
+    for( i = 0; i < i_nal; i++ )
+    {
+        int size, data;
+
+        data = buf->alloc - buf->size;
+        if( ( size = x264_nal_encode( buf->data + buf->size, &data,
+                                      1, &nal[i] ) ) < 1 )
+        {
+            continue;
+        }
+
+        if( job->mux & HB_MUX_AVI )
+        {
+            if( nal[i].i_ref_idc == NAL_PRIORITY_HIGHEST )
+            {
+                buf->key = 1;
+            }
+            buf->size += size;
+            continue;
+        }
+
+        /* H.264 in .mp4 */
+        switch( buf->data[buf->size+4] & 0x1f )
+        {
+            case 0x7:
+            case 0x8:
+                /* SPS, PPS */
+                break;
+
+            default:
+                /* H.264 in mp4 (stolen from mp4creator) */
+                buf->data[buf->size+0] = ( ( size - 4 ) >> 24 ) & 0xFF;
+                buf->data[buf->size+1] = ( ( size - 4 ) >> 16 ) & 0xFF;
+                buf->data[buf->size+2] = ( ( size - 4 ) >>  8 ) & 0xFF;
+                buf->data[buf->size+3] = ( ( size - 4 ) >>  0 ) & 0xFF;
+                if( nal[i].i_ref_idc == NAL_PRIORITY_HIGHEST )
+                {
+                    buf->key = 1;
+                }
+                buf->size += size;
+        }
+    }
+
+    *buf_out = buf;
+
+    return HB_WORK_OK;
+}
+
+
diff --git a/libhb/encxvid.c b/libhb/encxvid.c
new file mode 100644 (file)
index 0000000..a874d9f
--- /dev/null
@@ -0,0 +1,222 @@
+/* $Id: encxvid.c,v 1.10 2005/03/09 23:28:39 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 "hb.h"
+
+#include "xvid.h"
+
+struct hb_work_object_s
+{
+    HB_WORK_COMMON;
+
+    hb_job_t * job;
+    void     * xvid;
+    char       filename[1024];
+    int        quant;
+};
+
+/***********************************************************************
+ * Local prototypes
+ **********************************************************************/
+static void Close( hb_work_object_t ** _w );
+static int  Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+                  hb_buffer_t ** buf_out );
+
+/***********************************************************************
+ * hb_work_encxvid_init
+ ***********************************************************************
+ *
+ **********************************************************************/
+hb_work_object_t * hb_work_encxvid_init( hb_job_t * job )
+{
+    xvid_gbl_init_t xvid_gbl_init;
+    xvid_enc_create_t create;
+    xvid_plugin_single_t single;
+    xvid_plugin_2pass1_t rc2pass1;
+    xvid_plugin_2pass2_t rc2pass2;
+    xvid_enc_plugin_t plugins[1];
+
+    hb_work_object_t * w = calloc( sizeof( hb_work_object_t ), 1 );
+    w->name  = strdup( "MPEG-4 encoder (libxvidcore)" );
+    w->work  = Work;
+    w->close = Close;
+
+    w->job = job;
+
+    memset( w->filename, 0, 1024 );
+    hb_get_tempory_filename( job->h, w->filename, "xvid.log" );
+
+    memset( &xvid_gbl_init, 0, sizeof( xvid_gbl_init ) );
+    xvid_gbl_init.version = XVID_VERSION;
+    xvid_global( NULL, XVID_GBL_INIT, &xvid_gbl_init, NULL );
+
+    memset( &create, 0, sizeof( create ) );
+    create.version   = XVID_VERSION;
+    create.width     = job->width;
+    create.height    = job->height;
+    create.zones     = NULL;
+    create.num_zones = 0;
+
+    switch( job->pass )
+    {
+        case 0:
+            memset( &single, 0, sizeof( single ) );
+            single.version   = XVID_VERSION;
+            if( job->vquality < 0.0 || job->vquality > 1.0 )
+            {
+                /* Rate control */
+                single.bitrate = 1000 * job->vbitrate;
+                w->quant = 0;
+            }
+            else
+            {
+                /* Constant quantizer */
+                w->quant = 31 - job->vquality * 30;
+                hb_log( "encxvid: encoding at constant quantizer %d",
+                        w->quant );
+            }
+            plugins[0].func  = xvid_plugin_single;
+            plugins[0].param = &single;
+            break;
+
+        case 1:
+            memset( &rc2pass1, 0, sizeof( rc2pass1 ) );
+            rc2pass1.version  = XVID_VERSION;
+            rc2pass1.filename = w->filename;
+            plugins[0].func   = xvid_plugin_2pass1;
+            plugins[0].param  = &rc2pass1;
+            break;
+
+        case 2:
+            memset( &rc2pass2, 0, sizeof( rc2pass2 ) );
+            rc2pass2.version  = XVID_VERSION;
+            rc2pass2.filename = w->filename;
+            rc2pass2.bitrate  = 1000 * job->vbitrate;
+            plugins[0].func   = xvid_plugin_2pass2;
+            plugins[0].param  = &rc2pass2;
+            break;
+    }
+
+    create.plugins     = plugins;
+    create.num_plugins = 1;
+
+    create.num_threads      = 0;
+    create.fincr            = job->vrate_base;
+    create.fbase            = job->vrate;
+    create.max_key_interval = 10 * job->vrate / job->vrate_base;
+    create.max_bframes      = 0;
+    create.bquant_ratio     = 150;
+    create.bquant_offset    = 100;
+    create.frame_drop_ratio = 0;
+    create.global           = 0;
+
+    xvid_encore( NULL, XVID_ENC_CREATE, &create, NULL );
+    w->xvid = create.handle;
+
+    return w;
+}
+
+/***********************************************************************
+ * Close
+ ***********************************************************************
+ *
+ **********************************************************************/
+static void Close( hb_work_object_t ** _w )
+{
+    hb_work_object_t * w = *_w;
+
+    if( w->xvid )
+    {
+        hb_log( "encxvid: closing libxvidcore" );
+        xvid_encore( w->xvid, XVID_ENC_DESTROY, NULL, NULL);
+    }
+
+    free( w->name );
+    free( w );
+    *_w = NULL;
+}
+
+/***********************************************************************
+ * Work
+ ***********************************************************************
+ *
+ **********************************************************************/
+static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+                 hb_buffer_t ** buf_out )
+{
+    hb_job_t * job = w->job;
+    xvid_enc_frame_t frame;
+    hb_buffer_t * in = *buf_in, * buf;
+
+    /* Should be way too large */
+    buf = hb_buffer_init( 3 * job->width * job->height / 2 );
+    buf->start = in->start;
+    buf->stop  = in->stop;
+
+    memset( &frame, 0, sizeof( frame ) );
+
+    frame.version = XVID_VERSION;
+    frame.bitstream = buf->data;
+    frame.length = -1;
+    frame.input.plane[0] = in->data;
+    frame.input.csp = XVID_CSP_I420;
+    frame.input.stride[0] = job->width;
+    frame.vol_flags = 0;
+    frame.vop_flags = XVID_VOP_HALFPEL | XVID_VOP_INTER4V |
+                      XVID_VOP_TRELLISQUANT | XVID_VOP_HQACPRED;
+    if( job->grayscale )
+    {
+        frame.vop_flags |= XVID_VOP_GREYSCALE;
+    }
+    frame.type = XVID_TYPE_AUTO;
+    frame.quant = w->quant;
+    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;
+    frame.quant_intra_matrix = NULL;
+    frame.quant_inter_matrix = NULL;
+
+    buf->size = xvid_encore( w->xvid, XVID_ENC_ENCODE, &frame, NULL );
+    buf->key = ( frame.out_flags & XVID_KEYFRAME );
+
+#define c job->config.mpeg4
+    if( !c.config )
+    {
+        int vol_start, vop_start;
+        for( vol_start = 0; ; vol_start++ )
+        {
+            if( buf->data[vol_start]   == 0x0 &&
+                buf->data[vol_start+1] == 0x0 &&
+                buf->data[vol_start+2] == 0x1 &&
+                buf->data[vol_start+3] == 0x20 )
+            {
+                break;
+            }
+        }
+        for( vop_start = vol_start + 4; ; vop_start++ )
+        {
+            if( buf->data[vop_start]   == 0x0 &&
+                buf->data[vop_start+1] == 0x0 &&
+                buf->data[vop_start+2] == 0x1 &&
+                buf->data[vop_start+3] == 0xB6 )
+            {
+                break;
+            }
+        }
+
+        hb_log( "encxvid: VOL size is %d bytes", vop_start - vol_start );
+        c.config        = malloc( vop_start - vol_start );
+        c.config_length = vop_start - vol_start;
+        memcpy( c.config, &buf->data[vol_start], c.config_length );
+    }
+#undef c
+
+    *buf_out = buf;
+
+    return HB_WORK_OK;
+}
+
diff --git a/libhb/fifo.c b/libhb/fifo.c
new file mode 100644 (file)
index 0000000..81ca2a1
--- /dev/null
@@ -0,0 +1,180 @@
+/* $Id: fifo.c,v 1.17 2005/10/15 18:05:03 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 "hb.h"
+
+#ifndef SYS_DARWIN
+#include <malloc.h>
+#endif
+
+hb_buffer_t * hb_buffer_init( int size )
+{
+    hb_buffer_t * b;
+    
+    if( !( b = calloc( sizeof( hb_buffer_t ), 1 ) ) )
+    {
+        hb_log( "out of memory" );
+        return NULL;
+    }
+
+    b->alloc = size;
+    b->size  = size;
+#if defined( SYS_DARWIN ) || defined( SYS_FREEBSD )
+    b->data  = malloc( size );
+#elif defined( SYS_CYGWIN )
+    /* FIXME */
+    b->data  = malloc( size + 17 );
+#else
+    b->data  = memalign( 16, size );
+#endif
+
+    if( !b->data )
+    {
+        hb_log( "out of memory" );
+        free( b );
+        return NULL;
+    }
+    return b;
+}
+
+void hb_buffer_realloc( hb_buffer_t * b, int size )
+{
+    /* No more alignment, but we don't care */
+    b->data  = realloc( b->data, size );
+    b->alloc = size;
+}
+
+void hb_buffer_close( hb_buffer_t ** _b )
+{
+    hb_buffer_t * b = *_b;
+
+    if( b->data )
+    {
+        free( b->data );
+    }
+    free( b );
+
+    *_b = NULL;
+}
+
+/* Fifo */
+struct hb_fifo_s
+{
+    hb_lock_t    * lock;
+    int            capacity;
+    int            size;
+    hb_buffer_t  * first;
+    hb_buffer_t  * last;
+};
+
+hb_fifo_t * hb_fifo_init( int capacity )
+{
+    hb_fifo_t * f;
+    f           = calloc( sizeof( hb_fifo_t ), 1 );
+    f->lock     = hb_lock_init();
+    f->capacity = capacity;
+    return f;
+}
+
+int hb_fifo_size( hb_fifo_t * f )
+{
+    int ret;
+
+    hb_lock( f->lock );
+    ret = f->size;
+    hb_unlock( f->lock );
+
+    return ret;
+}
+
+int hb_fifo_is_full( hb_fifo_t * f )
+{
+    int ret;
+
+    hb_lock( f->lock );
+    ret = ( f->size >= f->capacity );
+    hb_unlock( f->lock );
+
+    return ret;
+}
+
+hb_buffer_t * hb_fifo_get( hb_fifo_t * f )
+{
+    hb_buffer_t * b;
+
+    hb_lock( f->lock );
+    if( f->size < 1 )
+    {
+        hb_unlock( f->lock );
+        return NULL;
+    }
+    b         = f->first;
+    f->first  = b->next;
+    b->next   = NULL;
+    f->size  -= 1;
+    hb_unlock( f->lock );
+
+    return b;
+}
+
+hb_buffer_t * hb_fifo_see( hb_fifo_t * f )
+{
+    hb_buffer_t * b;
+
+    hb_lock( f->lock );
+    if( f->size < 1 )
+    {
+        hb_unlock( f->lock );
+        return NULL;
+    }
+    b = f->first;
+    hb_unlock( f->lock );
+
+    return b;
+}
+
+void hb_fifo_push( hb_fifo_t * f, hb_buffer_t * b )
+{
+    if( !b )
+    {
+        return;
+    }
+
+    hb_lock( f->lock );
+    if( f->size > 0 )
+    {
+        f->last->next = b;
+    }
+    else
+    {
+        f->first = b;
+    }
+    f->last  = b;
+    f->size += 1;
+    while( f->last->next )
+    {
+        f->size += 1;
+        f->last  = f->last->next;
+    }
+    hb_unlock( f->lock );
+}
+
+void hb_fifo_close( hb_fifo_t ** _f )
+{
+    hb_fifo_t   * f = *_f;
+    hb_buffer_t * b;
+    
+    hb_log( "fifo_close: trashing %d buffer(s)", hb_fifo_size( f ) );
+    while( ( b = hb_fifo_get( f ) ) )
+    {
+        hb_buffer_close( &b );
+    }
+
+    hb_lock_close( &f->lock );
+    free( f );
+
+    *_f = NULL;
+}
diff --git a/libhb/hb.c b/libhb/hb.c
new file mode 100644 (file)
index 0000000..f27a353
--- /dev/null
@@ -0,0 +1,514 @@
+/* $Id: hb.c,v 1.43 2005/04/27 21:05:24 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 "hb.h"
+
+#include "ffmpeg/avcodec.h"
+
+struct hb_handle_s
+{
+    /* The "Check for update" thread */
+    int            build;
+    char           version[16];
+    hb_thread_t  * update_thread;
+
+    /* This thread's only purpose is to check other threads'
+       states */
+    volatile int   die;
+    hb_thread_t  * main_thread;
+    int            pid;
+
+    /* DVD/file scan thread */
+    hb_list_t    * list_title;
+    hb_thread_t  * scan_thread;
+
+    /* The thread which processes the jobs. Others threads are launched
+       from this one (see work.c) */
+    hb_list_t    * jobs;
+    int            job_count;
+    volatile int   work_die;
+    int            work_error;
+    hb_thread_t  * work_thread;
+
+    int            cpu_count;
+
+    hb_lock_t    * state_lock;
+    hb_state_t     state;
+
+    int            paused;
+    hb_lock_t    * pause_lock;
+};
+
+static void thread_func( void * );
+
+hb_handle_t * hb_init( int verbose, int update_check )
+{
+    hb_handle_t * h = calloc( sizeof( hb_handle_t ), 1 );
+    uint64_t      date;
+
+    /* See hb_log() in common.c */
+    if( verbose > HB_DEBUG_NONE )
+    {
+        putenv( "HB_DEBUG=1" );
+    }
+
+    /* Check for an update on the website if asked to */
+    h->build = -1;
+
+    if( update_check )
+    {
+        hb_log( "hb_init: checking for updates" );
+        date             = hb_get_date();
+        h->update_thread = hb_update_init( &h->build, h->version );
+
+        for( ;; )
+        {
+            if( hb_thread_has_exited( h->update_thread ) )
+            {
+                /* Immediate success or failure */
+                hb_thread_close( &h->update_thread );
+                break;
+            }
+            if( hb_get_date() > date + 1000 )
+            {
+                /* Still nothing after one second. Connection problem,
+                   let the thread die */
+                hb_log( "hb_init: connection problem, not waiting for "
+                        "update_thread" );
+                break;
+            }
+            hb_snooze( 50 );
+        }
+    }
+
+    /* CPU count detection */
+    hb_log( "hb_init: checking cpu count" );
+    h->cpu_count = hb_get_cpu_count();
+
+    h->list_title = hb_list_init();
+    h->jobs       = hb_list_init();
+
+    h->state_lock  = hb_lock_init();
+    h->state.state = HB_STATE_IDLE;
+
+    h->pause_lock = hb_lock_init();
+
+    /* libavcodec */
+    avcodec_init();
+    register_avcodec( &mpeg4_encoder );
+    register_avcodec( &mp2_decoder );
+    register_avcodec( &ac3_encoder );
+
+    /* Start library thread */
+    hb_log( "hb_init: starting libhb thread" );
+    h->die         = 0;
+    h->main_thread = hb_thread_init( "libhb", thread_func, h,
+                                     HB_NORMAL_PRIORITY );
+
+    return h;
+}
+
+char * hb_get_version( hb_handle_t * h )
+{
+    return HB_VERSION;
+}
+
+int hb_get_build( hb_handle_t * h )
+{
+    return HB_BUILD;
+}
+
+int hb_check_update( hb_handle_t * h, char ** version )
+{
+    *version = ( h->build < 0 ) ? NULL : h->version;
+    return h->build;
+}
+
+void hb_set_cpu_count( hb_handle_t * h, int cpu_count )
+{
+    cpu_count    = MAX( 1, cpu_count );
+    cpu_count    = MIN( cpu_count, 8 );
+    h->cpu_count = cpu_count;
+}
+
+void hb_scan( hb_handle_t * h, const char * path, int title_index )
+{
+    hb_title_t * title;
+
+    /* Clean up from previous scan */
+    while( ( title = hb_list_item( h->list_title, 0 ) ) )
+    {
+        hb_list_rem( h->list_title, title );
+        hb_title_close( &title );
+    }
+    
+    hb_log( "hb_scan: path=%s, title_index=%d", path, title_index );
+    h->scan_thread = hb_scan_init( h, path, title_index, h->list_title );
+}
+
+hb_list_t * hb_get_titles( hb_handle_t * h )
+{
+    return h->list_title;
+}
+
+void hb_get_preview( hb_handle_t * h, hb_title_t * title, int picture,
+                     uint8_t * buffer )
+{
+    hb_job_t           * job = title->job;
+    char                 filename[1024];
+    FILE               * file;
+    uint8_t            * buf1, * buf2, * buf3, * buf4, * pen;
+    uint32_t           * p32;
+    AVPicture            pic1, pic2, pic3, pic4;
+    ImgReSampleContext * context;
+    int                  i;
+
+    buf1 = malloc( title->width * title->height * 3 / 2 );
+    buf2 = malloc( title->width * title->height * 3 / 2 );
+    buf3 = malloc( title->width * title->height * 3 / 2 );
+    buf4 = malloc( title->width * title->height * 4 );
+    avpicture_fill( &pic1, buf1, PIX_FMT_YUV420P,
+                    title->width, title->height );
+    avpicture_fill( &pic2, buf2, PIX_FMT_YUV420P,
+                    title->width, title->height );
+    avpicture_fill( &pic3, buf3, PIX_FMT_YUV420P,
+                    job->width, job->height );
+    avpicture_fill( &pic4, buf4, PIX_FMT_RGBA32,
+                    job->width, job->height );
+    
+    memset( filename, 0, 1024 );
+
+    hb_get_tempory_filename( h, filename, "%x%d",
+                             (int) title, picture );
+
+    file = fopen( filename, "r" );
+    if( !file )
+    {
+        hb_log( "hb_get_preview: fopen failed" );
+        return;
+    }
+
+    fread( buf1, title->width * title->height * 3 / 2, 1, file );
+    fclose( file );
+
+    context = img_resample_full_init(
+            job->width, job->height, title->width, title->height,
+            job->crop[0], job->crop[1], job->crop[2], job->crop[3],
+            0, 0, 0, 0 );
+
+    if( job->deinterlace )
+    {
+        avpicture_deinterlace( &pic2, &pic1, PIX_FMT_YUV420P,
+                               title->width, title->height );
+        img_resample( context, &pic3, &pic2 );
+    }
+    else
+    {
+        img_resample( context, &pic3, &pic1 );
+    }
+    img_convert( &pic4, PIX_FMT_RGBA32, &pic3, PIX_FMT_YUV420P,
+                 job->width, job->height );
+
+    /* Gray background */
+    p32 = (uint32_t *) buffer;
+    for( i = 0; i < ( title->width + 2 ) * ( title->height + 2 ); i++ )
+    {
+        p32[i] = 0xFF808080;
+    }
+
+    /* Draw the picture, centered, and draw the cropping zone */
+    pen = buffer + ( title->height - job->height ) *
+        ( title->width + 2 ) * 2 + ( title->width - job->width ) * 2;
+    memset( pen, 0xFF, 4 * ( job->width + 2 ) );
+    pen += 4 * ( title->width + 2 );
+    for( i = 0; i < job->height; i++ )
+    {
+        uint8_t * nextLine;
+        nextLine = pen + 4 * ( title->width + 2 );
+        memset( pen, 0xFF, 4 );
+        pen += 4;
+        memcpy( pen, buf4 + 4 * job->width * i, 4 * job->width );
+        pen += 4 * job->width;
+        memset( pen, 0xFF, 4 );
+        pen = nextLine;
+    }
+    memset( pen, 0xFF, 4 * ( job->width + 2 ) );
+
+    free( buf1 );
+    free( buf2 );
+    free( buf3 );
+    free( buf4 );
+}
+
+int hb_count( hb_handle_t * h )
+{
+    return hb_list_count( h->jobs );
+}
+
+hb_job_t * hb_job( hb_handle_t * h, int i )
+{
+    return hb_list_item( h->jobs, i );
+}
+
+/* hb_add: memcpy() party. That's ugly, for if someone has a better
+   idea... */
+void hb_add( hb_handle_t * h, hb_job_t * job )
+{
+    hb_job_t      * job_copy;
+    hb_title_t    * title,    * title_copy;
+    hb_chapter_t  * chapter,  * chapter_copy;
+    hb_audio_t    * audio,    * audio_copy;
+    hb_subtitle_t * subtitle, * subtitle_copy;
+    int             i;
+
+    /* Copy the title */
+    title      = job->title;
+    title_copy = malloc( sizeof( hb_title_t ) );
+    memcpy( title_copy, title, sizeof( hb_title_t ) );
+
+    title_copy->list_chapter = hb_list_init();
+    for( i = 0; i < hb_list_count( title->list_chapter ); i++ )
+    {
+        chapter      = hb_list_item( title->list_chapter, i );
+        chapter_copy = malloc( sizeof( hb_chapter_t ) );
+        memcpy( chapter_copy, chapter, sizeof( hb_chapter_t ) );
+        hb_list_add( title_copy->list_chapter, chapter_copy );
+    }
+
+    /* Copy the audio track(s) we want */
+    title_copy->list_audio = hb_list_init();
+
+    /* Do nothing about audio during first pass */
+    if( job->pass != 1 )
+    {
+        for( i = 0; i < 8; i++ )
+        {
+            if( job->audios[i] < 0 )
+            {
+                break;
+            }
+            if( ( audio = hb_list_item( title->list_audio, job->audios[i] ) ) )
+            {
+                audio_copy = malloc( sizeof( hb_audio_t ) );
+                memcpy( audio_copy, audio, sizeof( hb_audio_t ) );
+                hb_list_add( title_copy->list_audio, audio_copy );
+            }
+        }
+    }
+
+    /* Copy the subtitle we want (or not) */
+    title_copy->list_subtitle = hb_list_init();
+    if( ( subtitle = hb_list_item( title->list_subtitle, job->subtitle ) ) )
+    {
+        subtitle_copy = malloc( sizeof( hb_subtitle_t ) );
+        memcpy( subtitle_copy, subtitle, sizeof( hb_subtitle_t ) );
+        hb_list_add( title_copy->list_subtitle, subtitle_copy );
+    }
+
+    /* Copy the job */
+    job_copy        = calloc( sizeof( hb_job_t ), 1 );
+    memcpy( job_copy, job, sizeof( hb_job_t ) );
+    job_copy->title = title_copy;
+    job_copy->file  = strdup( job->file );
+    job_copy->h     = h;
+    job_copy->pause = h->pause_lock;
+
+    /* Add the job to the list */
+    hb_list_add( h->jobs, job_copy );
+}
+
+void hb_rem( hb_handle_t * h, hb_job_t * job )
+{
+    hb_list_rem( h->jobs, job );
+
+    /* XXX free everything XXX */
+}
+
+void hb_start( hb_handle_t * h )
+{
+    /* XXX Hack */
+    h->job_count = hb_list_count( h->jobs );
+
+    hb_lock( h->state_lock );
+    h->state.state = HB_STATE_WORKING;
+#define p h->state.param.working
+    p.progress  = 0.0;
+    p.job_cur   = 1;
+    p.job_count = h->job_count;
+    p.rate_cur  = 0.0;
+    p.rate_avg  = 0.0;
+    p.hours     = -1;
+    p.minutes   = -1;
+    p.seconds   = -1;
+#undef p
+    hb_unlock( h->state_lock );
+
+    h->paused = 0;
+
+    h->work_die    = 0;
+    h->work_thread = hb_work_init( h->jobs, h->cpu_count,
+                                   &h->work_die, &h->work_error );
+}
+
+void hb_pause( hb_handle_t * h )
+{
+    if( !h->paused )
+    {
+        hb_lock( h->pause_lock );
+        h->paused = 1;
+
+        hb_lock( h->state_lock );
+        h->state.state = HB_STATE_PAUSED;
+        hb_unlock( h->state_lock );
+    }
+}
+
+void hb_resume( hb_handle_t * h )
+{
+    if( h->paused )
+    {
+        hb_unlock( h->pause_lock );
+        h->paused = 0;
+    }
+}
+
+void hb_stop( hb_handle_t * h )
+{
+    h->work_die = 1;
+
+    hb_resume( h );
+}
+
+void hb_get_state( hb_handle_t * h, hb_state_t * s )
+{
+    hb_lock( h->state_lock );
+
+    memcpy( s, &h->state, sizeof( hb_state_t ) );
+    h->state.state = HB_STATE_IDLE;
+
+    hb_unlock( h->state_lock );
+}
+
+void hb_close( hb_handle_t ** _h )
+{
+    hb_handle_t * h = *_h;
+    hb_title_t * title;
+
+    h->die = 1;
+    hb_thread_close( &h->main_thread );
+
+    while( ( title = hb_list_item( h->list_title, 0 ) ) )
+    {
+        hb_list_rem( h->list_title, title );
+        hb_title_close( &title );
+    }
+    hb_list_close( &h->list_title );
+
+    hb_list_close( &h->jobs );
+    hb_lock_close( &h->state_lock );
+    hb_lock_close( &h->pause_lock );
+    free( h );
+    *_h = NULL;
+}
+
+static void thread_func( void * _h )
+{
+    hb_handle_t * h = (hb_handle_t *) _h;
+    char dirname[1024];
+    DIR * dir;
+    struct dirent * entry;
+
+    h->pid = getpid();
+
+    /* Create folder for temporary files */
+    memset( dirname, 0, 1024 );
+    hb_get_tempory_directory( h, dirname );
+
+    hb_mkdir( dirname );
+
+    while( !h->die )
+    {
+        /* In case the check_update thread hangs, it'll die sooner or
+           later. Then, we join it here */
+        if( h->update_thread &&
+            hb_thread_has_exited( h->update_thread ) )
+        {
+            hb_thread_close( &h->update_thread );
+        }
+
+        /* Check if the scan thread is done */
+        if( h->scan_thread &&
+            hb_thread_has_exited( h->scan_thread ) )
+        {
+            hb_thread_close( &h->scan_thread );
+
+            hb_log( "libhb: scan thread found %d valid title(s)",
+                    hb_list_count( h->list_title ) );
+            hb_lock( h->state_lock );
+            h->state.state = HB_STATE_SCANDONE;
+            hb_unlock( h->state_lock );
+        }
+
+        /* Check if the work thread is done */
+        if( h->work_thread &&
+            hb_thread_has_exited( h->work_thread ) )
+        {
+            hb_thread_close( &h->work_thread );
+
+            hb_log( "libhb: work result = %d",
+                    h->work_error );
+            hb_lock( h->state_lock );
+            h->state.state                = HB_STATE_WORKDONE;
+            h->state.param.workdone.error = h->work_error;
+            hb_unlock( h->state_lock );
+        }
+
+        hb_snooze( 50 );
+    }
+
+    if( h->work_thread )
+    {
+        hb_stop( h );
+        hb_thread_close( &h->work_thread );
+    }
+
+    /* Remove temp folder */
+    dir = opendir( dirname );
+    while( ( entry = readdir( dir ) ) )
+    {
+        char filename[1024];
+        if( entry->d_name[0] == '.' )
+        {
+            continue;
+        }
+        memset( filename, 0, 1024 );
+        snprintf( filename, 1023, "%s/%s", dirname, entry->d_name );
+        unlink( filename );
+    }
+    closedir( dir );
+    rmdir( dirname );
+}
+
+int hb_get_pid( hb_handle_t * h )
+{
+    return h->pid;
+}
+
+void hb_set_state( hb_handle_t * h, hb_state_t * s )
+{
+    hb_lock( h->pause_lock );
+    hb_lock( h->state_lock );
+    memcpy( &h->state, s, sizeof( hb_state_t ) );
+    if( h->state.state == HB_STATE_WORKING )
+    {
+        /* XXX Hack */
+        h->state.param.working.job_cur =
+            h->job_count - hb_list_count( h->jobs );
+        h->state.param.working.job_count = h->job_count;
+    }
+    hb_unlock( h->state_lock );
+    hb_unlock( h->pause_lock );
+}
diff --git a/libhb/hb.h b/libhb/hb.h
new file mode 100644 (file)
index 0000000..4a64c90
--- /dev/null
@@ -0,0 +1,76 @@
+/* $Id: hb.h,v 1.12 2005/03/29 09:40:28 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_HB_H
+#define HB_HB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "common.h"
+
+/* hb_init()
+   Initializes a libhb session (launches his own thread, detects CPUs,
+   etc) */
+#define HB_DEBUG_NONE 0
+#define HB_DEBUG_ALL  1
+hb_handle_t * hb_init( int verbose, int update_check );
+
+/* hb_get_version() */
+char        * hb_get_version( hb_handle_t * );
+int           hb_get_build( hb_handle_t * );
+
+/* hb_check_update()
+   Checks for an update on the website. If there is, returns the build
+   number and points 'version' to a version description. Returns a
+   negative value otherwise. */
+int           hb_check_update( hb_handle_t * h, char ** version );
+
+/* hb_set_cpu_count()
+   Force libhb to act as if you had X CPU(s).
+   Default is to use the detected count (see also hb_get_cpu_count() in
+   ports.h) */
+void          hb_set_cpu_count( hb_handle_t *, int );
+
+/* hb_scan()
+   Scan the specified path. Can be a DVD device, a VIDEO_TS folder or
+   a VOB file. If title_index is 0, scan all titles. */
+void          hb_scan( hb_handle_t *, const char * path,
+                       int title_index );
+
+/* hb_get_titles()
+   Returns the list of valid titles detected by the latest scan. */
+hb_list_t   * hb_get_titles( hb_handle_t * );
+
+void          hb_get_preview( hb_handle_t *, hb_title_t *, int,
+                              uint8_t * );
+
+/* Handling jobs */
+int           hb_count( hb_handle_t * );
+hb_job_t *    hb_job( hb_handle_t *, int );
+void          hb_add( hb_handle_t *, hb_job_t * );
+void          hb_rem( hb_handle_t *, hb_job_t * );
+
+void          hb_start( hb_handle_t * );
+void          hb_pause( hb_handle_t * );
+void          hb_resume( hb_handle_t * );
+void          hb_stop( hb_handle_t * );
+
+/* hb_get_state()
+   Should be regularly called by the UI (like 5 or 10 times a second).
+   Look at test/test.c to see how to use it. */
+void hb_get_state( hb_handle_t *, hb_state_t * );
+
+/* hb_close()
+   Aborts all current jobs if any, frees memory. */
+void          hb_close( hb_handle_t ** );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libhb/internal.h b/libhb/internal.h
new file mode 100644 (file)
index 0000000..e22da82
--- /dev/null
@@ -0,0 +1,172 @@
+/* $Id: internal.h,v 1.40 2005/04/27 10:14:02 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. */
+
+/***********************************************************************
+ * common.c
+ **********************************************************************/
+void hb_log( char * log, ... );
+
+int  hb_list_bytes( hb_list_t * );
+void hb_list_seebytes( hb_list_t * l, uint8_t * dst, int size );
+void hb_list_getbytes( hb_list_t * l, uint8_t * dst, int size,
+                       uint64_t * pts, int * pos );
+void hb_list_empty( hb_list_t ** );
+
+hb_title_t * hb_title_init( char * dvd, int index );
+void         hb_title_close( hb_title_t ** );
+
+/***********************************************************************
+ * hb.c
+ **********************************************************************/
+int  hb_get_pid( hb_handle_t * );
+void hb_set_state( hb_handle_t *, hb_state_t * );
+
+/***********************************************************************
+ * fifo.c
+ **********************************************************************/
+typedef struct hb_buffer_s hb_buffer_t;
+struct hb_buffer_s
+{
+    int           size;
+    int           alloc;
+    uint8_t *     data;
+    int           cur;
+
+    int           id;
+    int64_t       start;
+    int64_t       stop;
+    int           key;
+
+    int           x;
+    int           y;
+    int           width;
+    int           height;
+
+    hb_buffer_t * sub;
+
+    hb_buffer_t * next;
+};
+
+hb_buffer_t * hb_buffer_init( int size );
+void          hb_buffer_realloc( hb_buffer_t *, int size );
+void          hb_buffer_close( hb_buffer_t ** );
+
+typedef struct hb_fifo_s hb_fifo_t;
+
+hb_fifo_t   * hb_fifo_init();
+int           hb_fifo_size( hb_fifo_t * );
+int           hb_fifo_is_full( hb_fifo_t * );
+hb_buffer_t * hb_fifo_get( hb_fifo_t * );
+hb_buffer_t * hb_fifo_see( hb_fifo_t * );
+void          hb_fifo_push( hb_fifo_t *, hb_buffer_t * );
+void          hb_fifo_close( hb_fifo_t ** );
+
+/***********************************************************************
+ * Threads: update.c, scan.c, work.c, reader.c, muxcommon.c
+ **********************************************************************/
+hb_thread_t * hb_update_init( int * build, char * version );
+hb_thread_t * hb_scan_init( hb_handle_t *, const char * path,
+                            int title_index, hb_list_t * list_title );
+hb_thread_t * hb_work_init( hb_list_t * jobs, int cpu_count,
+                            volatile int * die, int * error );
+hb_thread_t  * hb_reader_init( hb_job_t * );
+hb_thread_t  * hb_muxer_init( hb_job_t * );
+
+/***********************************************************************
+ * libmpeg2 wrapper
+ ***********************************************************************
+ * It is exported here because it is used at several places
+ **********************************************************************/
+typedef struct   hb_libmpeg2_s hb_libmpeg2_t;
+
+hb_libmpeg2_t  * hb_libmpeg2_init();
+int              hb_libmpeg2_decode( hb_libmpeg2_t *,
+                                      hb_buffer_t * es_buf,
+                                      hb_list_t * raw_list );
+void             hb_libmpeg2_info( hb_libmpeg2_t * m, int * width,
+                                    int * height, int * rate );
+void             hb_libmpeg2_close( hb_libmpeg2_t ** );
+
+/***********************************************************************
+ * mpegdemux.c
+ **********************************************************************/
+int hb_demux_ps( hb_buffer_t * ps_buf, hb_list_t * es_list );
+
+/***********************************************************************
+ * dvd.c
+ **********************************************************************/
+typedef struct hb_dvd_s hb_dvd_t;
+
+hb_dvd_t *   hb_dvd_init( char * path );
+int          hb_dvd_title_count( hb_dvd_t * );
+hb_title_t * hb_dvd_title_scan( hb_dvd_t *, int title );
+int          hb_dvd_start( hb_dvd_t *, int title, int chapter );
+int          hb_dvd_seek( hb_dvd_t *, float );
+int          hb_dvd_read( hb_dvd_t *, hb_buffer_t * );
+int          hb_dvd_chapter( hb_dvd_t * );
+void         hb_dvd_close( hb_dvd_t ** );
+
+/***********************************************************************
+ * Work objects
+ **********************************************************************/
+typedef struct hb_work_object_s hb_work_object_t;
+
+#define HB_WORK_COMMON \
+    hb_lock_t  * lock; \
+    int          used; \
+    uint64_t     time; \
+    char       * name; \
+    hb_fifo_t  * fifo_in; \
+    hb_fifo_t  * fifo_out; \
+    int       (* work)  ( hb_work_object_t *, hb_buffer_t **, \
+                          hb_buffer_t ** ); \
+    void      (* close) ( hb_work_object_t ** )
+
+#define HB_WORK_IDLE     0
+#define HB_WORK_OK       1
+#define HB_WORK_ERROR    2
+#define HB_WORK_DONE     3
+
+
+#define DECLARE_WORK_NORMAL( a ) \
+    hb_work_object_t * hb_work_##a##_init( hb_job_t * );
+
+#define DECLARE_WORK_AUDIO( a ) \
+    hb_work_object_t * hb_work_##a##_init( hb_job_t *, hb_audio_t * );
+
+DECLARE_WORK_NORMAL( sync );
+DECLARE_WORK_NORMAL( decmpeg2 );
+DECLARE_WORK_NORMAL( decsub );
+DECLARE_WORK_NORMAL( render );
+DECLARE_WORK_NORMAL( encavcodec );
+DECLARE_WORK_NORMAL( encxvid );
+DECLARE_WORK_NORMAL( encx264 );
+DECLARE_WORK_AUDIO( deca52 );
+DECLARE_WORK_AUDIO( decavcodec );
+DECLARE_WORK_AUDIO( declpcm );
+DECLARE_WORK_AUDIO( encfaac );
+DECLARE_WORK_AUDIO( enclame );
+DECLARE_WORK_AUDIO( encvorbis );
+
+/***********************************************************************
+ * Muxers
+ **********************************************************************/
+typedef struct hb_mux_object_s hb_mux_object_t;
+typedef struct hb_mux_data_s   hb_mux_data_t;
+
+#define HB_MUX_COMMON \
+    int (*init)      ( hb_mux_object_t * ); \
+    int (*mux)       ( hb_mux_object_t *, hb_mux_data_t *, \
+                       hb_buffer_t * ); \
+    int (*end)       ( hb_mux_object_t * );
+
+#define DECLARE_MUX( a ) \
+    hb_mux_object_t  * hb_mux_##a##_init( hb_job_t * );
+
+DECLARE_MUX( mp4 );
+DECLARE_MUX( avi );
+DECLARE_MUX( ogm );
+
similarity index 86%
rename from core/Languages.h
rename to libhb/lang.h
index 7949688..f88f539 100644 (file)
@@ -1,20 +1,21 @@
-/* $Id: Languages.h,v 1.1 2003/11/03 12:08:01 titer Exp $
+/* $Id: lang.h,v 1.1 2004/08/02 07:19:05 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_LANGUAGES_H
-#define HB_LANGUAGES_H
+#ifndef HB_LANG_H
+#define HB_LANG_H
 
 typedef struct iso639_lang_t
 {
-    char * engName;        /* Description in English */
-    char * nativeName;     /* Description in native language */
+    char * eng_name;        /* Description in English */
+    char * native_name;     /* Description in native language */
     char * iso639_1;       /* ISO-639-1 (2 characters) code */
+
 } iso639_lang_t;
 
-static iso639_lang_t languages[] =
+static const iso639_lang_t languages[] =
 { { "Afar", "", "aa" },
   { "Abkhazian", "", "ab" },
   { "Afrikaans", "", "af" },
@@ -181,4 +182,28 @@ static iso639_lang_t languages[] =
   { "Zulu", "", "zu" },
   { NULL, NULL, NULL } };
 
+static char * lang_for_code( int code )
+{
+    char code_string[2];
+    iso639_lang_t * lang;
+
+    code_string[0] = ( code >> 8 ) & 0xFF;
+    code_string[1] = code & 0xFF;
+
+    for( lang = (iso639_lang_t*) languages; lang->eng_name; lang++ )
+    {
+        if( !strncmp( lang->iso639_1, code_string, 2 ) )
+        {
+            if( *lang->native_name )
+            {
+                return lang->native_name;
+            }
+
+            return lang->eng_name;
+        }
+    }
+
+    return "Unknown";
+}
+
 #endif
diff --git a/libhb/muxavi.c b/libhb/muxavi.c
new file mode 100644 (file)
index 0000000..8746a3c
--- /dev/null
@@ -0,0 +1,551 @@
+/* $Id: muxavi.c,v 1.10 2005/03/30 18:17:29 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 "hb.h"
+
+#define AVIF_HASINDEX  0x10
+#define AVIIF_KEYFRAME 0x10
+#define FOURCC(a)      ((a[3]<<24)|(a[2]<<16)|(a[1]<<8)|a[0])
+
+/* Structures definitions */
+typedef struct __attribute__((__packed__))
+{
+    uint32_t FourCC;
+    uint32_t BytesCount;
+    uint32_t MicroSecPerFrame;
+    uint32_t MaxBytesPerSec;
+    uint32_t PaddingGranularity;
+    uint32_t Flags;
+    uint32_t TotalFrames;
+    uint32_t InitialFrames;
+    uint32_t Streams;
+    uint32_t SuggestedBufferSize;
+    uint32_t Width;
+    uint32_t Height;
+    uint32_t Reserved[4];
+
+} hb_avi_main_header_t;
+
+typedef struct __attribute__((__packed__))
+{
+    uint32_t FourCC;
+    uint32_t BytesCount;
+    uint32_t Type;
+    uint32_t Handler;
+    uint32_t Flags;
+    uint16_t Priority;
+    uint16_t Language;
+    uint32_t InitialFrames;
+    uint32_t Scale;
+    uint32_t Rate;
+    uint32_t Start;
+    uint32_t Length;
+    uint32_t SuggestedBufferSize;
+    uint32_t Quality;
+    uint32_t SampleSize;
+    int16_t  Left;
+    int16_t  Top;
+    int16_t  Right;
+    int16_t  Bottom;
+
+} hb_avi_stream_header_t;
+
+typedef struct __attribute__((__packed__))
+{
+    uint32_t FourCC;
+    uint32_t BytesCount;
+    uint32_t Size;
+    uint32_t Width;
+    uint32_t Height;
+    uint16_t Planes;
+    uint16_t BitCount;
+    uint32_t Compression;
+    uint32_t SizeImage;
+    uint32_t XPelsPerMeter;
+    uint32_t YPelsPerMeter;
+    uint32_t ClrUsed;
+    uint32_t ClrImportant;
+
+} hb_bitmap_info_t;
+
+typedef struct __attribute__((__packed__))
+{
+    uint32_t FourCC;
+    uint32_t BytesCount;
+    uint16_t FormatTag;
+    uint16_t Channels;
+    uint32_t SamplesPerSec;
+    uint32_t AvgBytesPerSec;
+    uint16_t BlockAlign;
+    uint16_t BitsPerSample;
+    uint16_t Size;
+
+} hb_wave_formatex_t;
+
+typedef struct __attribute__((__packed__))
+{
+    uint16_t Id;
+    uint32_t Flags;
+    uint16_t BlockSize;
+    uint16_t FramesPerBlock;
+    uint16_t CodecDelay;
+
+} hb_wave_mp3_t;
+
+static void WriteBuffer( FILE * file, hb_buffer_t * buf )
+{
+    fwrite( buf->data, buf->size, 1, file );
+}
+
+/* Little-endian write routines */
+
+static void WriteInt8( FILE * file, uint8_t val )
+{
+    fputc( val, file );
+}   
+
+static void WriteInt16( FILE * file, uint16_t val )
+{
+    fputc( val & 0xFF, file );
+    fputc( val >> 8, file );
+}
+
+static void WriteInt32( FILE * file, uint32_t val )
+{
+    fputc( val & 0xFF, file );
+    fputc( ( val >> 8 ) & 0xFF, file );
+    fputc( ( val >> 16 ) & 0xFF, file );
+    fputc( val >> 24, file );
+}
+
+static void WriteBitmapInfo( FILE * file, hb_bitmap_info_t * info )
+{
+    WriteInt32( file, info->FourCC );
+    WriteInt32( file, info->BytesCount );
+    WriteInt32( file, info->Size );
+    WriteInt32( file, info->Width );
+    WriteInt32( file, info->Height );
+    WriteInt16( file, info->Planes );
+    WriteInt16( file, info->BitCount );
+    WriteInt32( file, info->Compression );
+    WriteInt32( file, info->SizeImage );
+    WriteInt32( file, info->XPelsPerMeter );
+    WriteInt32( file, info->YPelsPerMeter );
+    WriteInt32( file, info->ClrUsed );
+    WriteInt32( file, info->ClrImportant );
+}
+
+static void WriteWaveFormatEx( FILE * file, hb_wave_formatex_t * format )
+{
+    WriteInt32( file, format->FourCC );
+    WriteInt32( file, format->BytesCount );
+    WriteInt16( file, format->FormatTag );
+    WriteInt16( file, format->Channels );
+    WriteInt32( file, format->SamplesPerSec );
+    WriteInt32( file, format->AvgBytesPerSec );
+    WriteInt16( file, format->BlockAlign );
+    WriteInt16( file, format->BitsPerSample );
+    WriteInt16( file, format->Size );
+}
+
+static void WriteWaveMp3( FILE * file, hb_wave_mp3_t * mp3 )
+{
+    WriteInt16( file, mp3->Id );
+    WriteInt32( file, mp3->Flags );
+    WriteInt16( file, mp3->BlockSize );
+    WriteInt16( file, mp3->FramesPerBlock );
+    WriteInt16( file, mp3->CodecDelay );
+}
+
+static void WriteMainHeader( FILE * file, hb_avi_main_header_t * header )
+{
+    WriteInt32( file, header->FourCC );
+    WriteInt32( file, header->BytesCount );
+    WriteInt32( file, header->MicroSecPerFrame );
+    WriteInt32( file, header->MaxBytesPerSec );
+    WriteInt32( file, header->PaddingGranularity );
+    WriteInt32( file, header->Flags );
+    WriteInt32( file, header->TotalFrames );
+    WriteInt32( file, header->InitialFrames );
+    WriteInt32( file, header->Streams );
+    WriteInt32( file, header->SuggestedBufferSize );
+    WriteInt32( file, header->Width );
+    WriteInt32( file, header->Height );
+    WriteInt32( file, header->Reserved[0] );
+    WriteInt32( file, header->Reserved[1] );
+    WriteInt32( file, header->Reserved[2] );
+    WriteInt32( file, header->Reserved[3] );
+}
+
+static void WriteStreamHeader( FILE * file, hb_avi_stream_header_t * header )
+{
+    WriteInt32( file, header->FourCC );
+    WriteInt32( file, header->BytesCount );
+    WriteInt32( file, header->Type );
+    WriteInt32( file, header->Handler );
+    WriteInt32( file, header->Flags );
+    WriteInt16( file, header->Priority );
+    WriteInt16( file, header->Language );
+    WriteInt32( file, header->InitialFrames );
+    WriteInt32( file, header->Scale );
+    WriteInt32( file, header->Rate );
+    WriteInt32( file, header->Start );
+    WriteInt32( file, header->Length );
+    WriteInt32( file, header->SuggestedBufferSize );
+    WriteInt32( file, header->Quality );
+    WriteInt32( file, header->SampleSize );
+    WriteInt16( file, header->Left );
+    WriteInt16( file, header->Top );
+    WriteInt16( file, header->Right );
+    WriteInt16( file, header->Bottom );
+}
+
+static void IndexAddInt32( hb_buffer_t * b, uint32_t val )
+{
+    if( b->size + 16 > b->alloc )
+    {
+        hb_log( "muxavi: reallocing index (%d MB)",
+                1 + b->alloc / 1024 / 1024 );
+        hb_buffer_realloc( b, b->alloc + 1024 * 1024 );
+    }
+
+    b->data[b->size++] = val & 0xFF;
+    b->data[b->size++] = ( val >> 8 ) & 0xFF;
+    b->data[b->size++] = ( val >> 16 ) & 0xFF;
+    b->data[b->size++] = val >> 24;
+}
+
+struct hb_mux_object_s
+{
+    HB_MUX_COMMON;
+
+    hb_job_t * job;
+
+    /* Data size in bytes, not including headers */
+    unsigned               size;
+    FILE                 * file;
+    hb_buffer_t          * index;
+    hb_avi_main_header_t   main_header;
+};
+
+struct hb_mux_data_s
+{
+    uint32_t               fourcc;
+    hb_avi_stream_header_t header;
+    union
+    {
+        hb_bitmap_info_t   v;
+        struct
+        {
+            hb_wave_formatex_t f;
+            hb_wave_mp3_t      m;
+        } a;
+    } format;
+};
+
+static void AddIndex( hb_mux_object_t * m )
+{
+    fseek( m->file, 0, SEEK_END );
+
+    /* Write the index at the end of the file */
+    WriteInt32( m->file, FOURCC( "idx1" ) );
+    WriteInt32( m->file, m->index->size );
+    WriteBuffer( m->file, m->index );
+
+    /* Update file size */
+    m->size += 8 + m->index->size;
+    fseek( m->file, 4, SEEK_SET );
+    WriteInt32( m->file, 2040 + m->size );
+
+    /* Update HASINDEX flag */
+    m->main_header.Flags |= AVIF_HASINDEX;
+    fseek( m->file, 24, SEEK_SET );
+    WriteMainHeader( m->file, &m->main_header );
+}
+
+
+/**********************************************************************
+ * AVIInit
+ **********************************************************************
+ * Allocates things, create file, initialize and write headers
+ *********************************************************************/
+static int AVIInit( hb_mux_object_t * m )
+{
+    hb_job_t   * job   = m->job;
+    hb_title_t * title = job->title;
+
+    hb_audio_t    * audio;
+    hb_mux_data_t * mux_data;
+
+    int audio_count = hb_list_count( title->list_audio );
+    int is_ac3      = ( job->acodec & HB_ACODEC_AC3 );
+    int hdrl_bytes;
+    int i;
+
+    /* Allocate index */
+    m->index       = hb_buffer_init( 1024 * 1024 );
+    m->index->size = 0;
+
+    /* Open destination file */
+    hb_log( "muxavi: opening %s", job->file );
+    m->file = fopen( job->file, "wb" );
+
+#define m m->main_header
+    /* AVI main header */
+    m.FourCC           = FOURCC( "avih" );
+    m.BytesCount       = sizeof( hb_avi_main_header_t ) - 8;
+    m.MicroSecPerFrame = (uint64_t) 1000000 * job->vrate_base / job->vrate;
+    m.Streams          = 1 + audio_count;
+    m.Width            = job->width;
+    m.Height           = job->height;
+#undef m
+
+    /* Video track */
+    mux_data = calloc( sizeof( hb_mux_data_t ), 1 );
+    job->mux_data = mux_data;
+    
+#define h mux_data->header
+    /* Video stream header */
+    h.FourCC     = FOURCC( "strh" );
+    h.BytesCount = sizeof( hb_avi_stream_header_t ) - 8;
+    h.Type       = FOURCC( "vids" );
+
+    if( job->vcodec == HB_VCODEC_FFMPEG )
+        h.Handler = FOURCC( "divx" );
+    else if( job->vcodec == HB_VCODEC_XVID )
+        h.Handler = FOURCC( "xvid" );
+    else if( job->vcodec == HB_VCODEC_X264 )
+        h.Handler = FOURCC( "h264" );
+
+    h.Scale      = job->vrate_base;
+    h.Rate       = job->vrate;
+#undef h
+
+#define f mux_data->format.v
+    /* Video stream format */
+    f.FourCC      = FOURCC( "strf" );
+    f.BytesCount  = sizeof( hb_bitmap_info_t ) - 8;
+    f.Size        = f.BytesCount;
+    f.Width       = job->width;
+    f.Height      = job->height;
+    f.Planes      = 1;
+    f.BitCount    = 24;
+    if( job->vcodec == HB_VCODEC_FFMPEG )
+        f.Compression = FOURCC( "DX50" );
+    else if( job->vcodec == HB_VCODEC_XVID )
+        f.Compression = FOURCC( "XVID" );
+    else if( job->vcodec == HB_VCODEC_X264 )
+        f.Compression = FOURCC( "H264" );
+#undef f
+
+    /* Audio tracks */
+    for( i = 0; i < hb_list_count( title->list_audio ); i++ )
+    {
+        audio = hb_list_item( title->list_audio, i );
+
+        mux_data = calloc( sizeof( hb_mux_data_t ), 1 );
+        audio->mux_data = mux_data;
+
+#define h mux_data->header
+#define f mux_data->format.a.f
+#define m mux_data->format.a.m
+        /* Audio stream header */
+        h.FourCC        = FOURCC( "strh" );
+        h.BytesCount    = sizeof( hb_avi_stream_header_t ) - 8;
+        h.Type          = FOURCC( "auds" );
+        h.InitialFrames = 1;
+        h.Scale         = 1;
+        h.Rate          = is_ac3 ? ( audio->bitrate / 8 ) :
+                                   ( job->abitrate * 1000 / 8 );
+        h.Quality       = 0xFFFFFFFF;
+        h.SampleSize    = 1;
+
+        /* Audio stream format */
+        f.FourCC         = FOURCC( "strf" );
+        if( is_ac3 )
+        {
+            f.BytesCount     = sizeof( hb_wave_formatex_t ) - 8;
+            f.FormatTag      = 0x2000;
+            f.Channels       = audio->channels;
+            f.SamplesPerSec  = audio->rate;
+        }
+        else
+        {
+            f.BytesCount     = sizeof( hb_wave_formatex_t ) +
+                               sizeof( hb_wave_mp3_t ) - 8;
+            f.FormatTag      = 0x55;
+            f.Channels       = 2;
+            f.SamplesPerSec  = job->arate;
+        }
+        f.AvgBytesPerSec = h.Rate;
+        f.BlockAlign     = 1;
+        if( is_ac3 )
+        {
+            f.Size       = 0;
+        }
+        else
+        {
+            f.Size           = sizeof( hb_wave_mp3_t );
+            m.Id             = 1;
+            m.Flags          = 2;
+            m.BlockSize      = 1152 * f.AvgBytesPerSec / job->arate;
+            m.FramesPerBlock = 1;
+            m.CodecDelay     = 1393;
+        }
+#undef h
+#undef f
+#undef m
+    }
+
+    hdrl_bytes =
+        /* Main header */
+        4 + sizeof( hb_avi_main_header_t ) +
+        /* strh for video + audios */
+        ( 1 + audio_count ) * ( 12 + sizeof( hb_avi_stream_header_t ) ) +
+        /* video strf */
+        sizeof( hb_bitmap_info_t ) +
+        /* audios strf */
+        audio_count * ( sizeof( hb_wave_formatex_t ) +
+                        ( is_ac3 ? 0 : sizeof( hb_wave_mp3_t ) ) );
+
+    /* Here we really start to write into the file */
+
+    /* Main headers */
+    WriteInt32( m->file, FOURCC( "RIFF" ) );
+    WriteInt32( m->file, 2040 );
+    WriteInt32( m->file, FOURCC( "AVI " ) );
+    WriteInt32( m->file, FOURCC( "LIST" ) );
+    WriteInt32( m->file, hdrl_bytes );
+    WriteInt32( m->file, FOURCC( "hdrl" ) );
+    WriteMainHeader( m->file, &m->main_header );
+
+    /* Video track */
+    mux_data          = job->mux_data;
+    mux_data->fourcc = FOURCC( "00dc" );
+
+    WriteInt32( m->file, FOURCC( "LIST" ) );
+    WriteInt32( m->file, 4 + sizeof( hb_avi_stream_header_t ) +
+                sizeof( hb_bitmap_info_t ) );
+    WriteInt32( m->file, FOURCC( "strl" ) );
+    WriteStreamHeader( m->file, &mux_data->header );
+    WriteBitmapInfo( m->file, &mux_data->format.v );
+
+    /* Audio tracks */
+    for( i = 0; i < audio_count; i++ )
+    {
+        char fourcc[4] = "00wb";
+        
+        audio    = hb_list_item( title->list_audio, i );
+        mux_data = audio->mux_data;
+
+        fourcc[1] = '1' + i; /* This is fine as we don't allow more
+                                than 8 tracks */
+        mux_data->fourcc = FOURCC( fourcc );
+
+        WriteInt32( m->file, FOURCC( "LIST" ) );
+        WriteInt32( m->file, 4 + sizeof( hb_avi_stream_header_t ) +
+                             sizeof( hb_wave_formatex_t ) +
+                             ( is_ac3 ? 0 : sizeof( hb_wave_mp3_t ) ) );
+        WriteInt32( m->file, FOURCC( "strl" ) );
+        WriteStreamHeader( m->file, &mux_data->header );
+        WriteWaveFormatEx( m->file, &mux_data->format.a.f );
+        if( !is_ac3 )
+        {
+            WriteWaveMp3( m->file, &mux_data->format.a.m );
+        }
+    }
+
+    WriteInt32( m->file, FOURCC( "JUNK" ) );
+    WriteInt32( m->file, 2020 - hdrl_bytes );
+    for( i = 0; i < 2020 - hdrl_bytes; i++ )
+    {
+        WriteInt8( m->file, 0 );
+    }
+    WriteInt32( m->file, FOURCC( "LIST" ) );
+    WriteInt32( m->file, 4 );
+    WriteInt32( m->file, FOURCC( "movi" ) );
+
+    return 0;
+}
+
+static int AVIMux( hb_mux_object_t * m, hb_mux_data_t * mux_data,
+                   hb_buffer_t * buf )
+{
+    hb_job_t   * job   = m->job;
+    hb_title_t * title = job->title;
+
+    hb_audio_t * audio;
+    int i;
+
+    /* Update index */
+    IndexAddInt32( m->index, mux_data->fourcc );
+    IndexAddInt32( m->index, buf->key ? AVIIF_KEYFRAME : 0 );
+    IndexAddInt32( m->index, 4 + m->size );
+    IndexAddInt32( m->index, buf->size );
+
+    /* Write the chunk to the file */
+    fseek( m->file, 0, SEEK_END );
+    WriteInt32( m->file, mux_data->fourcc );
+    WriteInt32( m->file, buf->size );
+    WriteBuffer( m->file, buf );
+
+    /* Chunks must be 2-bytes aligned */
+    if( buf->size & 1 )
+    {
+        WriteInt8( m->file, 0 );
+    }
+
+    /* Update headers */ 
+    m->size += 8 + EVEN( buf->size );
+    mux_data->header.Length++;
+
+    /* RIFF size */ 
+    fseek( m->file, 4, SEEK_SET );
+    WriteInt32( m->file, 2052 + m->size );
+
+    /* Mmmmh that's not nice */
+    fseek( m->file, 140, SEEK_SET );
+    WriteInt32( m->file, job->mux_data->header.Length );
+    for( i = 0; i < hb_list_count( title->list_audio ); i++ )
+    {
+        audio = hb_list_item( title->list_audio, i );
+        fseek( m->file, 264 + i *
+               ( 102 + ( ( job->acodec & HB_ACODEC_AC3 ) ? 0 :
+                 sizeof( hb_wave_mp3_t ) ) ), SEEK_SET );
+        WriteInt32( m->file, audio->mux_data->header.Length );
+    }
+
+    /* movi size */
+    fseek( m->file, 2052, SEEK_SET );
+    WriteInt32( m->file, 4 + m->size );
+    return 0;
+}
+
+static int AVIEnd( hb_mux_object_t * m )
+{
+    hb_job_t * job = m->job;
+
+    hb_log( "muxavi: writing index" );
+    AddIndex( m );
+
+    hb_log( "muxavi: closing %s", job->file );
+    fclose( m->file );
+
+    hb_buffer_close( &m->index );
+
+    return 0;
+}
+
+hb_mux_object_t * hb_mux_avi_init( hb_job_t * job )
+{
+    hb_mux_object_t * m = calloc( sizeof( hb_mux_object_t ), 1 );
+    m->init      = AVIInit;
+    m->mux       = AVIMux;
+    m->end       = AVIEnd;
+    m->job       = job;
+    return m;
+}
+
diff --git a/libhb/muxcommon.c b/libhb/muxcommon.c
new file mode 100644 (file)
index 0000000..090f332
--- /dev/null
@@ -0,0 +1,215 @@
+/* $Id: muxcommon.c,v 1.23 2005/03/30 17:27:19 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 "hb.h"
+
+struct hb_mux_object_s
+{
+    HB_MUX_COMMON;
+};
+
+typedef struct
+{
+    hb_job_t * job;
+    uint64_t   pts;
+
+} hb_mux_t;
+
+typedef struct
+{
+    hb_fifo_t     * fifo;
+    hb_mux_data_t * mux_data;
+    uint64_t        frames;
+    uint64_t        bytes;
+
+} hb_track_t;
+
+static hb_track_t * GetTrack( hb_list_t * list )
+{
+    hb_buffer_t * buf;
+    hb_track_t  * track = NULL, * track2;
+    int64_t       pts = 0;
+    int           i;
+
+    for( i = 0; i < hb_list_count( list ); i++ )
+    {
+        track2 = hb_list_item( list, i );
+        buf    = hb_fifo_see( track2->fifo );
+        if( !buf )
+        {
+            return NULL;
+        }
+        if( !track || buf->start < pts )
+        {
+            track = track2;
+            pts   = buf->start;
+        }
+    }
+    return track;
+}
+
+static void MuxerFunc( void * _mux )
+{
+    hb_mux_t    * mux = _mux;
+    hb_job_t    * job = mux->job;
+    hb_title_t  * title = job->title;
+    hb_audio_t  * audio;
+    hb_list_t   * list;
+    hb_buffer_t * buf;
+    hb_track_t  * track;
+    int           i;
+
+    hb_mux_object_t * m = NULL;
+
+    /* Get a real muxer */
+    if( job->pass != 1 )
+    {
+        switch( job->mux )
+        {
+            case HB_MUX_MP4:
+                m = hb_mux_mp4_init( job );
+                break;
+            case HB_MUX_AVI:
+                m = hb_mux_avi_init( job );
+                break;
+            case HB_MUX_OGM:
+                m = hb_mux_ogm_init( job );
+                break;
+        }
+    }
+
+    /* Wait for one buffer for each track */
+    while( !*job->die && !job->done )
+    {
+        int ready;
+
+        ready = 1;
+        if( !hb_fifo_size( job->fifo_mpeg4 ) )
+        {
+            ready = 0;
+        }
+        for( i = 0; i < hb_list_count( title->list_audio ); i++ )
+        {
+            audio = hb_list_item( title->list_audio, i );
+            if( !hb_fifo_size( audio->fifo_out ) )
+            {
+                ready = 0;
+                break;
+            }
+        }
+
+        if( ready )
+        {
+            break;
+        }
+
+        hb_snooze( 50 );
+    }
+
+    /* Create file, write headers */
+    if( job->pass != 1 )
+    {
+        m->init( m );
+    }
+
+    /* Build list of fifos we're interested in */
+    list = hb_list_init();
+
+    track           = calloc( sizeof( hb_track_t ), 1 );
+    track->fifo     = job->fifo_mpeg4;
+    track->mux_data = job->mux_data;
+    hb_list_add( list, track );
+
+    for( i = 0; i < hb_list_count( title->list_audio ); i++ )
+    {
+        audio           = hb_list_item( title->list_audio, i );
+        track           = calloc( sizeof( hb_track_t ), 1 );
+        track->fifo     = audio->fifo_out;
+        track->mux_data = audio->mux_data;
+        hb_list_add( list, track );
+    }
+
+    while( !*job->die && !job->done )
+    {
+        if( !( track = GetTrack( list ) ) )
+        {
+            hb_snooze( 50 );
+            continue;
+        }
+
+        buf = hb_fifo_get( track->fifo );
+        if( job->pass != 1 )
+        {
+            m->mux( m, track->mux_data, buf );
+            track->frames += 1;
+            track->bytes  += buf->size;
+            mux->pts = buf->stop;
+        }
+        hb_buffer_close( &buf );
+    }
+
+    if( job->pass != 1 )
+    {
+        struct stat sb;
+        uint64_t bytes_total, frames_total;
+
+        m->end( m );
+
+        if( !stat( job->file, &sb ) )
+        {
+            hb_log( "mux: file size, %lld bytes", (uint64_t) sb.st_size );
+
+            bytes_total  = 0;
+            frames_total = 0;
+            for( i = 0; i < hb_list_count( list ); i++ )
+            {
+                track = hb_list_item( list, i );
+                hb_log( "mux: track %d, %lld bytes, %.2f kbps",
+                        i, track->bytes,
+                        90000.0 * track->bytes / mux->pts / 125 );
+                if( !i && ( job->vquality < 0.0 || job->vquality > 1.0 ) )
+                {
+                    /* Video */
+                    hb_log( "mux: video bitrate error, %+lld bytes",
+                            track->bytes - mux->pts * job->vbitrate *
+                            125 / 90000 );
+                }
+                bytes_total  += track->bytes;
+                frames_total += track->frames;
+            }
+
+            if( bytes_total && frames_total )
+            {
+                hb_log( "mux: overhead, %.2f bytes per frame",
+                        (float) ( sb.st_size - bytes_total ) /
+                        frames_total );
+            }
+        }
+    }
+
+    free( m );
+
+    for( i = 0; i < hb_list_count( list ); i++ )
+    {
+        track = hb_list_item( list, i );
+        if( track->mux_data )
+        {
+            free( track->mux_data );
+        }
+        free( track );
+    }
+    hb_list_close( &list );
+
+    free( mux );
+}
+
+hb_thread_t * hb_muxer_init( hb_job_t * job )
+{
+    hb_mux_t * mux = calloc( sizeof( hb_mux_t ), 1 );
+    mux->job = job;
+    return hb_thread_init( "muxer", MuxerFunc, mux,
+                           HB_NORMAL_PRIORITY );
+}
diff --git a/libhb/muxmp4.c b/libhb/muxmp4.c
new file mode 100644 (file)
index 0000000..a02a052
--- /dev/null
@@ -0,0 +1,160 @@
+/* $Id: muxmp4.c,v 1.24 2005/11/04 13:09:41 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. */
+
+/* libmp4v2 header */
+#include "mp4.h"
+
+#include "hb.h"
+
+struct hb_mux_object_s
+{
+    HB_MUX_COMMON;
+
+    hb_job_t * job;
+
+    /* libmp4v2 handle */
+    MP4FileHandle file;
+
+    /* Cumulated durations so far, in timescale units (see MP4Mux) */
+    uint64_t sum_dur;
+};
+
+struct hb_mux_data_s
+{
+    MP4TrackId track;
+};
+
+/**********************************************************************
+ * MP4Init
+ **********************************************************************
+ * Allocates hb_mux_data_t structures, create file and write headers
+ *********************************************************************/
+static int MP4Init( hb_mux_object_t * m )
+{
+    hb_job_t   * job   = m->job;
+    hb_title_t * title = job->title;
+    
+    hb_audio_t    * audio;
+    hb_mux_data_t * mux_data;
+    int i;
+
+    /* Create an empty mp4 file */
+    m->file = MP4Create( job->file, MP4_DETAILS_ERROR, 0 );
+
+    /* Video track */
+    mux_data      = malloc( sizeof( hb_mux_data_t ) );
+    job->mux_data = mux_data;
+
+    /* When using the standard 90000 timescale, QuickTime tends to have
+       synchronization issues (audio not playing at the correct speed).
+       To workaround this, we use the audio samplerate as the
+       timescale */
+    MP4SetTimeScale( m->file, job->arate );
+
+    if( job->vcodec == HB_VCODEC_X264 )
+    {
+#define c job->config.h264
+        /* Stolen from mp4creator */
+        MP4SetVideoProfileLevel( m->file, 0x7F );
+
+        mux_data->track = MP4AddH264VideoTrack( m->file, job->arate,
+                MP4_INVALID_DURATION, job->width, job->height,
+                c.sps[1], /* AVCProfileIndication */
+                c.sps[2], /* profile_compat */
+                c.sps[3], /* AVCLevelIndication */
+                3 );      /* 4 bytes length before each NAL unit */
+
+        MP4AddH264SequenceParameterSet( m->file, mux_data->track,
+                c.sps, c.sps_length );
+        MP4AddH264PictureParameterSet( m->file, mux_data->track,
+                c.pps, c.pps_length );
+#undef c
+    }
+    else /* FFmpeg or XviD */
+    {
+#define c job->config.mpeg4
+        MP4SetVideoProfileLevel( m->file, MPEG4_SP_L3 );
+        mux_data->track = MP4AddVideoTrack( m->file, job->arate,
+                MP4_INVALID_DURATION, job->width, job->height,
+                MP4_MPEG4_VIDEO_TYPE );
+
+        /* VOL from FFmpeg or XviD */
+        MP4SetTrackESConfiguration( m->file, mux_data->track,
+                c.config, c.config_length );
+#undef c
+    }
+
+    for( i = 0; i < hb_list_count( title->list_audio ); i++ )
+    {
+        audio = hb_list_item( title->list_audio, i );
+        mux_data = malloc( sizeof( hb_mux_data_t ) );
+        audio->mux_data = mux_data;
+
+        mux_data->track = MP4AddAudioTrack( m->file,
+                job->arate, 1024, MP4_MPEG4_AUDIO_TYPE );
+        MP4SetAudioProfileLevel( m->file, 0x0F );
+        MP4SetTrackESConfiguration( m->file, mux_data->track,
+                audio->config.faac.decinfo, audio->config.faac.size );
+    }
+
+    return 0;
+}
+
+static int MP4Mux( hb_mux_object_t * m, hb_mux_data_t * mux_data,
+                   hb_buffer_t * buf )
+{
+    hb_job_t * job = m->job;
+
+    uint64_t duration;
+
+    if( mux_data == job->mux_data )
+    {
+        /* Video */
+        /* Because we use the audio samplerate as the timescale,
+           we have to use potentially variable durations so the video
+           doesn't go out of sync */
+        duration    = ( buf->stop * job->arate / 90000 ) - m->sum_dur;
+        m->sum_dur += duration;
+    }
+    else
+    {
+        /* Audio */
+        duration = MP4_INVALID_DURATION;
+    }
+
+    MP4WriteSample( m->file, mux_data->track, buf->data, buf->size,
+                    duration, 0, buf->key );
+    return 0;
+}
+
+static int MP4End( hb_mux_object_t * m )
+{
+    hb_job_t * job = m->job;
+    char filename[1024]; memset( filename, 0, 1024 );
+
+    MP4Close( m->file );
+
+#if 0
+    hb_log( "muxmp4: optimizing file" );
+    snprintf( filename, 1024, "%s.tmp", job->file );
+    MP4Optimize( job->file, filename, MP4_DETAILS_ERROR );
+    remove( job->file );
+    rename( filename, job->file );
+#endif
+
+    return 0;
+}
+
+hb_mux_object_t * hb_mux_mp4_init( hb_job_t * job )
+{
+    hb_mux_object_t * m = calloc( sizeof( hb_mux_object_t ), 1 );
+    m->init      = MP4Init;
+    m->mux       = MP4Mux;
+    m->end       = MP4End;
+    m->job       = job;
+    return m;
+}
+
diff --git a/libhb/muxogm.c b/libhb/muxogm.c
new file mode 100644 (file)
index 0000000..d326c98
--- /dev/null
@@ -0,0 +1,364 @@
+/* $Id: muxogm.c,v 1.4 2005/02/20 00:41:56 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 "hb.h"
+
+#include <ogg/ogg.h>
+
+struct hb_mux_object_s
+{
+    HB_MUX_COMMON;
+
+    hb_job_t * job;
+
+    FILE * file;
+};
+
+struct hb_mux_data_s
+{
+    int              codec;
+    ogg_stream_state os;
+    int              i_packet_no;                                               
+};
+
+typedef struct __attribute__((__packed__))
+{
+    uint8_t i_packet_type;
+
+    char stream_type[8];
+    char sub_type[4];
+
+    int32_t i_size;
+
+    int64_t i_time_unit;
+    int64_t i_samples_per_unit;
+    int32_t i_default_len;
+
+    int32_t i_buffer_size;
+    int16_t i_bits_per_sample;
+    int16_t i_padding_0;            // hum hum
+    union
+    {
+        struct
+        {
+            int32_t i_width;
+            int32_t i_height;
+
+        } video;
+        struct
+        {
+            int16_t i_channels;
+            int16_t i_block_align;
+            int32_t i_avgbytespersec;
+        } audio;
+    } header;
+
+} ogg_stream_header_t;
+
+#define SetWLE( p, v ) _SetWLE( (uint8_t*)p, v)
+static void _SetWLE( uint8_t *p, uint16_t i_dw )
+{
+    p[1] = ( i_dw >>  8 )&0xff;
+    p[0] = ( i_dw       )&0xff;
+}
+
+#define SetDWLE( p, v ) _SetDWLE( (uint8_t*)p, v)
+static void _SetDWLE( uint8_t *p, uint32_t i_dw )
+{
+    p[3] = ( i_dw >> 24 )&0xff;
+    p[2] = ( i_dw >> 16 )&0xff;
+    p[1] = ( i_dw >>  8 )&0xff;
+    p[0] = ( i_dw       )&0xff;
+}
+#define SetQWLE( p, v ) _SetQWLE( (uint8_t*)p, v)
+static void _SetQWLE( uint8_t *p, uint64_t i_qw )
+{
+    SetDWLE( p,   i_qw&0xffffffff );
+    SetDWLE( p+4, ( i_qw >> 32)&0xffffffff );
+}
+
+static int OGMFlush( hb_mux_object_t * m, hb_mux_data_t * mux_data )
+{
+    for( ;; )
+    {
+        ogg_page og;
+        if( ogg_stream_flush( &mux_data->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 )
+        {
+            return -1;
+        }
+    }
+    return 0;
+}                                                                               
+
+/**********************************************************************
+ * OGMInit
+ **********************************************************************
+ * Allocates hb_mux_data_t structures, create file and write headers
+ *********************************************************************/
+static int OGMInit( hb_mux_object_t * m )
+{
+    hb_job_t   * job   = m->job;
+    hb_title_t * title = job->title;
+    
+    hb_audio_t    * audio;
+    hb_mux_data_t * mux_data;
+    int i;
+
+    ogg_packet          op;
+    ogg_stream_header_t h;
+
+    /* Open output file */
+    if( ( m->file = fopen( job->file, "wb" ) ) == NULL )
+    {
+        hb_log( "muxogm: failed to open `%s'", job->file );
+        return -1;
+    }
+    hb_log( "muxogm: `%s' opened", job->file );
+
+    /* Video track */
+    mux_data              = malloc( sizeof( hb_mux_data_t ) );
+    mux_data->codec       = job->vcodec;
+    mux_data->i_packet_no = 0;
+    job->mux_data         = mux_data;
+    ogg_stream_init( &mux_data->os, 0 );
+
+    /* Audio */
+    for( i = 0; i < hb_list_count( title->list_audio ); i++ )
+    {
+        audio                 = hb_list_item( title->list_audio, i );
+        mux_data              = malloc( sizeof( hb_mux_data_t ) );
+        mux_data->codec       = job->acodec;
+        mux_data->i_packet_no = 0;
+        audio->mux_data       = mux_data;
+        ogg_stream_init( &mux_data->os, i + 1 );
+    }
+
+
+    /* First pass: all b_o_s packets */
+
+    /* Video */
+    mux_data = job->mux_data;
+    memset( &h, 0, sizeof( ogg_stream_header_t ) );
+    h.i_packet_type = 0x01;
+    memcpy( h.stream_type, "video    ", 8 );
+    if( mux_data->codec == HB_VCODEC_X264 )
+    {
+        memcpy( h.sub_type, "H264", 4 );
+    }
+    else if( mux_data->codec == HB_VCODEC_XVID )
+    {
+        memcpy( h.sub_type, "XVID", 4 );
+    }
+    else
+    {
+        memcpy( h.sub_type, "DX50", 4 );
+    }
+    SetDWLE( &h.i_size, sizeof( ogg_stream_header_t ) - 1);
+    SetQWLE( &h.i_time_unit, (int64_t) 10 * 1000 * 1000 *
+             (int64_t) job->vrate_base / (int64_t) job->vrate );
+    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,  job->width );
+    SetDWLE( &h.header.video.i_height, job->height );
+    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 = mux_data->i_packet_no++;
+    ogg_stream_packetin( &mux_data->os, &op );
+    OGMFlush( m, mux_data );
+
+    /* Audio */
+    for( i = 0; i < hb_list_count( title->list_audio ); i++ )
+    {
+        audio   = hb_list_item( title->list_audio, i );
+        mux_data = audio->mux_data;
+        memset( &h, 0, sizeof( ogg_stream_header_t ) );
+        switch( job->acodec )
+        {
+            case HB_ACODEC_LAME:
+            {
+                h.i_packet_type = 0x01;
+                memcpy( h.stream_type, "audio    ", 8 );
+                memcpy( h.sub_type, "55  ", 4 );
+
+                SetDWLE( &h.i_size, sizeof( ogg_stream_header_t ) - 1);
+                SetQWLE( &h.i_time_unit, 0 );
+                SetQWLE( &h.i_samples_per_unit, job->arate );
+                SetDWLE( &h.i_default_len, 1 );
+                SetDWLE( &h.i_buffer_size, 30 * 1024 );
+                SetWLE ( &h.i_bits_per_sample, 0 );
+
+                SetDWLE( &h.header.audio.i_channels, 2 ); 
+                SetDWLE( &h.header.audio.i_block_align, 0 );
+                SetDWLE( &h.header.audio.i_avgbytespersec,
+                         job->abitrate / 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 = mux_data->i_packet_no++;
+                ogg_stream_packetin( &mux_data->os, &op );
+                break;
+            }
+            case HB_ACODEC_VORBIS:
+            {
+                memcpy( &op, audio->config.vorbis.headers[0],
+                        sizeof( ogg_packet ) );
+                op.packet = audio->config.vorbis.headers[0] +
+                                sizeof( ogg_packet );
+                ogg_stream_packetin( &mux_data->os, &op );
+                break;
+            }
+            default:
+                hb_log( "muxogm: unhandled codec" );
+                break;
+        }
+        OGMFlush( m, mux_data );
+    }
+
+    /* second pass: all non b_o_s packets */
+    for( i = 0; i < hb_list_count( title->list_audio ); i++ )
+    {
+        audio = hb_list_item( title->list_audio, i );
+        if( job->acodec == HB_ACODEC_VORBIS )
+        {
+            int       j;
+            mux_data = audio->mux_data;
+
+            for( j = 1; j < 3; j++ )
+            {
+                memcpy( &op, audio->config.vorbis.headers[j],
+                        sizeof( ogg_packet ) );
+                op.packet = audio->config.vorbis.headers[j] +
+                                sizeof( ogg_packet );
+                ogg_stream_packetin( &mux_data->os, &op );
+
+                OGMFlush( m, mux_data );
+            }
+        }
+    }
+    hb_log( "muxogm: headers written" );
+
+    return 0;
+}
+
+static int OGMMux( hb_mux_object_t * m, hb_mux_data_t * mux_data,
+                   hb_buffer_t * buf )
+{
+    ogg_packet   op;
+
+    switch( mux_data->codec )
+    {
+        case HB_VCODEC_FFMPEG:
+        case HB_VCODEC_XVID:
+        case HB_VCODEC_X264:
+            op.bytes  = buf->size + 1;
+            op.packet = malloc( op.bytes );
+            op.packet[0] = buf->key ? 0x08 : 0x00;
+            memcpy( &op.packet[1], buf->data, buf->size );
+            op.b_o_s       = 0;
+            op.e_o_s       = 0;
+            op.granulepos  = mux_data->i_packet_no;
+            op.packetno    = mux_data->i_packet_no++;
+            break;
+        case HB_ACODEC_LAME:
+            op.bytes  = buf->size + 1;
+            op.packet = malloc( op.bytes );
+            op.packet[0] = 0x08;
+            memcpy( &op.packet[1], buf->data, buf->size );
+            op.b_o_s       = 0;
+            op.e_o_s       = 0;
+            op.granulepos  = mux_data->i_packet_no * 1152;
+            op.packetno    = mux_data->i_packet_no++;
+            break;
+        case HB_ACODEC_VORBIS:
+            memcpy( &op, buf->data, sizeof( ogg_packet ) );
+            op.packet = malloc( op.bytes );
+            memcpy( op.packet, buf->data + sizeof( ogg_packet ), op.bytes );
+            break;
+
+        default:
+            hb_log( "muxogm: unhandled codec" );
+            op.bytes = 0;
+            op.packet = NULL;
+            break;
+    }
+
+    if( op.packet )
+    {
+        ogg_stream_packetin( &mux_data->os, &op );
+
+        for( ;; )
+        {
+            ogg_page og;
+            if( ogg_stream_pageout( &mux_data->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 )
+            {
+                hb_log( "muxogm: write failed" );
+                break;
+            }
+        }
+        free( op.packet );
+    }
+    return 0; 
+}
+
+static int OGMEnd( hb_mux_object_t * m )
+{
+    hb_job_t * job = m->job;
+
+    hb_title_t * title = job->title;
+    hb_audio_t    * audio;
+    hb_mux_data_t * mux_data;
+    int          i;
+
+    mux_data = job->mux_data;
+    if( OGMFlush( m, mux_data ) < 0 )
+    {
+        return -1;
+    }
+    for( i = 0; i < hb_list_count( title->list_audio ); i++ )
+    {
+        audio = hb_list_item( title->list_audio, i );
+        mux_data = audio->mux_data;
+        if( OGMFlush( m, mux_data ) < 0 )
+        {
+            return -1;
+        }
+    }
+
+    fclose( m->file );
+    hb_log( "muxogm: `%s' closed", job->file );
+    
+    return 0;
+}
+
+hb_mux_object_t * hb_mux_ogm_init( hb_job_t * job )
+{
+    hb_mux_object_t * m = calloc( sizeof( hb_mux_object_t ), 1 );
+    m->init      = OGMInit;
+    m->mux       = OGMMux;
+    m->end       = OGMEnd;
+    m->job       = job;
+    return m;
+}
+
diff --git a/libhb/ports.c b/libhb/ports.c
new file mode 100644 (file)
index 0000000..20c2cae
--- /dev/null
@@ -0,0 +1,593 @@
+/* $Id: ports.c,v 1.15 2005/10/15 18:05:03 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 <time.h> 
+#include <sys/time.h>
+
+#if defined( SYS_BEOS )
+#include <OS.h>
+#include <signal.h>
+#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD )
+#include <pthread.h>
+#elif defined( SYS_CYGWIN )
+#include <windows.h>
+#endif
+
+#ifdef SYS_CYGWIN
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#else
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#endif
+
+#include "hb.h"
+
+/************************************************************************
+ * hb_get_date()
+ ************************************************************************
+ * Returns the current date in milliseconds.
+ * On Win32, we implement a gettimeofday emulation here because
+ * libdvdread and libmp4v2 use it without checking.
+ ************************************************************************/
+#ifdef SYS_CYGWIN
+struct timezone
+{
+};
+
+int gettimeofday( struct timeval * tv, struct timezone * tz )
+{
+    int tick;
+    tick        = GetTickCount();
+    tv->tv_sec  = tick / 1000;
+    tv->tv_usec = ( tick % 1000 ) * 1000;
+    return 0;
+}
+#endif
+
+uint64_t hb_get_date()
+{
+    struct timeval tv;
+    gettimeofday( &tv, NULL );
+    return( (uint64_t) tv.tv_sec * 1000 + (uint64_t) tv.tv_usec / 1000 );
+}
+
+/************************************************************************
+ * hb_snooze()
+ ************************************************************************
+ * Waits <delay> milliseconds.
+ ************************************************************************/
+void hb_snooze( int delay )
+{
+    if( delay < 1 )
+    {
+        return;
+    }
+#if defined( SYS_BEOS )
+    snooze( 1000 * delay );
+#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD )
+    usleep( 1000 * delay );
+#elif defined( SYS_CYGWIN )
+    Sleep( delay );
+#endif
+}
+
+/************************************************************************
+ * hb_get_cpu_count()
+ ************************************************************************
+ * Whenever possible, returns the number of CPUs on the current
+ * computer. Returns 1 otherwise.
+ * The detection is actually only performed on the first call.
+ ************************************************************************/
+int hb_get_cpu_count()
+{
+    static int cpu_count = 0;
+
+    if( cpu_count )
+    {
+        return cpu_count;
+    }
+    cpu_count = 1;
+
+#if defined( SYS_BEOS )
+    {
+        system_info info;
+        get_system_info( &info );
+        cpu_count = info.cpu_count;
+    }
+
+#elif defined( SYS_DARWIN ) || defined( SYS_FREEBSD )
+    FILE * info;
+    char   buffer[16];
+
+    if( ( info = popen( "/usr/sbin/sysctl hw.ncpu", "r" ) ) )
+    {
+        memset( buffer, 0, 16 );
+        if( fgets( buffer, 15, info ) )
+        {
+            if( sscanf( buffer, "hw.ncpu: %d", &cpu_count ) != 1 )
+            {
+                cpu_count = 1;
+            }
+        }
+        fclose( info );
+    }
+
+#elif defined( SYS_LINUX )
+    {
+        FILE * info;
+        char   buffer[8];
+
+        if( ( info = popen( "grep -c '^processor' /proc/cpuinfo",
+                            "r" ) ) )
+        {
+            memset( buffer, 0, 8 );
+            if( fgets( buffer, 7, info ) )
+            {
+                if( sscanf( buffer, "%d", &cpu_count ) != 1 )
+                {
+                    cpu_count = 1;
+                }
+            }
+            fclose( info );
+        }
+    }
+
+#elif defined( SYS_CYGWIN )
+    SYSTEM_INFO cpuinfo;
+    GetSystemInfo( &cpuinfo );
+    cpu_count = cpuinfo.dwNumberOfProcessors;
+#endif
+
+    cpu_count = MAX( 1, cpu_count );
+    cpu_count = MIN( cpu_count, 8 );
+
+    return cpu_count;
+}
+
+/************************************************************************
+ * Get a tempory directory for HB
+ ***********************************************************************/
+void hb_get_tempory_directory( hb_handle_t * h, char path[512] )
+{
+    char base[512];
+
+    /* Create the base */
+#ifdef SYS_CYGWIN
+    char *p;
+    int i_size = GetTempPath( 512, base );
+    if( i_size <= 0 || i_size >= 512 )
+    {
+        if( getcwd( base, 512 ) == NULL )
+            strcpy( base, "c:" ); /* Bad fallback but ... */
+    }
+
+    /* c:/path/ works like a charm under cygwin(win32?) so use it */
+    while( ( p = strchr( base, '\\' ) ) )
+        *p = '/';
+#else
+    strcpy( base, "/tmp" );
+#endif
+    /* I prefer to remove evntual last '/' (for cygwin) */
+    if( base[strlen(base)-1] == '/' )
+        base[strlen(base)-1] = '\0';
+
+    snprintf( path, 512, "%s/hb.%d", base, hb_get_pid( h ) );
+}
+
+/************************************************************************
+ * Get a tempory filename for HB
+ ***********************************************************************/
+void hb_get_tempory_filename( hb_handle_t * h, char name[1024],
+                              char *fmt, ... )
+{
+    va_list args;
+
+    hb_get_tempory_directory( h, name );
+    strcat( name, "/" );
+    
+    va_start( args, fmt );
+    vsnprintf( &name[strlen(name)], 1024 - strlen(name), fmt, args );
+    va_end( args );
+}
+
+/************************************************************************
+ * hb_mkdir
+ ************************************************************************
+ * Wrapper to the real mkdir, needed only because it doesn't take a
+ * second argument on Win32. Grrr.
+ ***********************************************************************/
+void hb_mkdir( char * name )
+{
+#ifdef SYS_CYGWIN
+    mkdir( name );
+#else
+    mkdir( name, 0755 );
+#endif
+}
+
+/************************************************************************
+ * Portable thread implementation
+ ***********************************************************************/
+struct hb_thread_s
+{
+    char       * name;
+    int          priority;
+    void      (* function) ( void * );
+    void       * arg;
+
+    hb_lock_t  * lock;
+    int          exited;
+
+#if defined( SYS_BEOS )
+    thread_id    thread;
+#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD )
+    pthread_t    thread;
+#elif defined( SYS_CYGWIN )
+    HANDLE       thread;
+#endif
+};
+
+/************************************************************************
+ * hb_thread_func()
+ ************************************************************************
+ * We use it as the root routine for any thread, for two reasons:
+ *  + To set the thread priority on OS X (pthread_setschedparam() could
+ *    be called from hb_thread_init(), but it's nicer to do it as we
+ *    are sure it is done before the real routine starts)
+ *  + Get informed when the thread exits, so we know whether
+ *    hb_thread_close() will block or not.
+ ***********************************************************************/
+static void hb_thread_func( void * _t )
+{
+    hb_thread_t * t = (hb_thread_t *) _t;
+
+#if defined( SYS_DARWIN )
+    /* Set the thread priority */
+    struct sched_param param;
+    memset( &param, 0, sizeof( struct sched_param ) );
+    param.sched_priority = t->priority;
+    pthread_setschedparam( pthread_self(), SCHED_OTHER, &param );
+#endif
+
+#if defined( SYS_BEOS )
+    signal( SIGINT, SIG_IGN );
+#endif
+
+    /* Start the actual routine */
+    t->function( t->arg );
+
+    /* Inform that the thread can be joined now */
+    hb_log( "thread %d exited (\"%s\")", t->thread, t->name );
+    hb_lock( t->lock );
+    t->exited = 1;
+    hb_unlock( t->lock );
+}
+
+/************************************************************************
+ * hb_thread_init()
+ ************************************************************************
+ * name:     user-friendly name
+ * function: the thread routine
+ * arg:      argument of the routine
+ * priority: HB_LOW_PRIORITY or HB_NORMAL_PRIORITY
+ ***********************************************************************/
+hb_thread_t * hb_thread_init( char * name, void (* function)(void *),
+                              void * arg, int priority )
+{
+    hb_thread_t * t = calloc( sizeof( hb_thread_t ), 1 );
+
+    t->name     = strdup( name );
+    t->function = function;
+    t->arg      = arg;
+    t->priority = priority;
+
+    t->lock     = hb_lock_init();
+
+    /* Create and start the thread */
+#if defined( SYS_BEOS )
+    t->thread = spawn_thread( (thread_func) hb_thread_func,
+                              name, priority, t );
+    resume_thread( t->thread );
+
+#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD )
+    pthread_create( &t->thread, NULL,
+                    (void * (*)( void * )) hb_thread_func, t );
+
+#elif defined( SYS_CYGWIN )
+    t->thread = CreateThread( NULL, 0,
+        (LPTHREAD_START_ROUTINE) hb_thread_func, t, 0, NULL );
+
+    /* Maybe use THREAD_PRIORITY_LOWEST instead */
+    if( priority == HB_LOW_PRIORITY )
+        SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL );
+#endif
+
+    hb_log( "thread %d started (\"%s\")", t->thread, t->name );
+    return t;
+}
+
+/************************************************************************
+ * hb_thread_close()
+ ************************************************************************
+ * Joins the thread and frees memory.
+ ***********************************************************************/
+void hb_thread_close( hb_thread_t ** _t )
+{
+    hb_thread_t * t = *_t;
+
+    /* Join the thread */
+#if defined( SYS_BEOS )
+    long exit_value;
+    wait_for_thread( t->thread, &exit_value );
+    
+#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD )
+    pthread_join( t->thread, NULL );
+
+#elif defined( SYS_CYGWIN )
+    WaitForSingleObject( t->thread, INFINITE );
+#endif
+    
+    hb_log( "thread %d joined (\"%s\")",
+            t->thread, t->name );
+
+    hb_lock_close( &t->lock );
+    free( t->name );
+    free( t );
+    *_t = NULL; 
+}
+
+/************************************************************************
+ * hb_thread_has_exited()
+ ************************************************************************
+ * Returns 1 if the thread can be joined right away, 0 otherwise.
+ ***********************************************************************/
+int hb_thread_has_exited( hb_thread_t * t )
+{
+    int exited;
+
+    hb_lock( t->lock );
+    exited = t->exited;
+    hb_unlock( t->lock );
+
+    return exited;
+}
+
+/************************************************************************
+ * Portable mutex implementation
+ ***********************************************************************/
+struct hb_lock_s
+{
+#if defined( SYS_BEOS )
+    sem_id          sem;
+#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD )
+    pthread_mutex_t mutex;
+#elif defined( SYS_CYGWIN )
+    HANDLE          mutex;
+#endif
+};
+
+/************************************************************************
+ * hb_lock_init()
+ * hb_lock_close()
+ * hb_lock()
+ * hb_unlock()
+ ************************************************************************
+ * Basic wrappers to OS-specific semaphore or mutex functions.
+ ***********************************************************************/
+hb_lock_t * hb_lock_init()
+{
+    hb_lock_t * l = calloc( sizeof( hb_lock_t ), 1 );
+
+#if defined( SYS_BEOS )
+    l->sem = create_sem( 1, "sem" );
+#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD )
+    pthread_mutex_init( &l->mutex, NULL );
+#elif defined( SYS_CYGWIN )
+    l->mutex = CreateMutex( 0, FALSE, 0 );
+#endif
+
+    return l;
+}
+
+void hb_lock_close( hb_lock_t ** _l )
+{
+    hb_lock_t * l = *_l;
+
+#if defined( SYS_BEOS )
+    delete_sem( l->sem );
+#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD )
+    pthread_mutex_destroy( &l->mutex );
+#elif defined( SYS_CYGWIN )
+    CloseHandle( l->mutex );
+#endif
+    free( l );
+
+    *_l = NULL;
+}
+
+void hb_lock( hb_lock_t * l )
+{
+#if defined( SYS_BEOS )
+    acquire_sem( l->sem );
+#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD )
+    pthread_mutex_lock( &l->mutex );
+#elif defined( SYS_CYGWIN )
+    WaitForSingleObject( l->mutex, INFINITE );
+#endif
+}
+
+void hb_unlock( hb_lock_t * l )
+{
+#if defined( SYS_BEOS )
+    release_sem( l->sem );
+#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD )
+    pthread_mutex_unlock( &l->mutex );
+#elif defined( SYS_CYGWIN )
+    ReleaseMutex( l->mutex );
+#endif
+}
+
+/************************************************************************
+ * Portable condition variable implementation
+ ***********************************************************************/
+struct hb_cond_s
+{
+#if defined( SYS_BEOS )
+    int                 thread;
+#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD )
+    pthread_cond_t      cond;
+#elif defined( SYS_CYGWIN )
+    HANDLE              event;
+#endif
+};
+
+/************************************************************************
+ * hb_cond_init()
+ * hb_cond_close()
+ * hb_cond_wait()
+ * hb_cond_signal()
+ ************************************************************************
+ * Win9x is not supported by this implementation (SignalObjectAndWait()
+ * only available on Windows 2000/XP).
+ ***********************************************************************/
+hb_cond_t * hb_cond_init()
+{
+    hb_cond_t * c = calloc( sizeof( hb_cond_t ), 1 );
+
+#if defined( SYS_BEOS )
+    c->thread = -1;
+#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD )
+    pthread_cond_init( &c->cond, NULL );
+#elif defined( SYS_CYGWIN )
+    c->event = CreateEvent( NULL, FALSE, FALSE, NULL );
+#endif
+
+    return c;
+}
+
+void hb_cond_close( hb_cond_t ** _c )
+{
+    hb_cond_t * c = *_c;
+
+#if defined( SYS_BEOS )
+#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD )
+    pthread_cond_destroy( &c->cond );
+#elif defined( SYS_CYGWIN )
+    CloseHandle( c->event );
+#endif
+    free( c );
+
+    *_c = NULL;
+}
+
+void hb_cond_wait( hb_cond_t * c, hb_lock_t * lock )
+{
+#if defined( SYS_BEOS )
+    c->thread = find_thread( NULL );
+    release_sem( lock->sem );
+    suspend_thread( c->thread );
+    acquire_sem( lock->sem );
+    c->thread = -1;
+#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD )
+    pthread_cond_wait( &c->cond, &lock->mutex );
+#elif defined( SYS_CYGWIN )
+    SignalObjectAndWait( lock->mutex, c->event, INFINITE, FALSE );
+    WaitForSingleObject( lock->mutex, INFINITE );
+#endif
+}
+
+void hb_cond_signal( hb_cond_t * c )
+{
+#if defined( SYS_BEOS )
+    while( c->thread != -1 )
+    {
+        thread_info info;
+        get_thread_info( c->thread, &info );
+        if( info.state == B_THREAD_SUSPENDED )
+        {
+            resume_thread( c->thread );
+            break;
+        }
+        /* Looks like we have been called between hb_cond_wait's
+           release_sem() and suspend_thread() lines. Wait until the
+           thread is actually suspended before we resume it */
+        snooze( 5000 );
+    }
+#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD )
+    pthread_cond_signal( &c->cond );
+#elif defined( SYS_CYGWIN )
+    PulseEvent( c->event );
+#endif
+}
+
+/************************************************************************
+ * Network
+ ***********************************************************************/
+
+struct hb_net_s
+{
+    int socket;
+};
+
+hb_net_t * hb_net_open( char * address, int port )
+{
+    hb_net_t * n = calloc( sizeof( hb_net_t ), 1 );
+
+    struct sockaddr_in   sock;
+    struct hostent     * host;
+
+    /* TODO: find out why this doesn't work on Win32 */
+    if( !( host = gethostbyname( address ) ) )
+    {
+        hb_log( "gethostbyname failed (%s)", address );
+        free( n );
+        return NULL;
+    }
+
+    memset( &sock, 0, sizeof( struct sockaddr_in ) );
+    sock.sin_family = host->h_addrtype;
+    sock.sin_port   = htons( port );
+    memcpy( &sock.sin_addr, host->h_addr, host->h_length );
+
+    if( ( n->socket = socket( host->h_addrtype, SOCK_STREAM, 0 ) ) < 0 )
+    {
+        hb_log( "socket failed" );
+        free( n );
+        return NULL;
+    }
+
+    if( connect( n->socket, (struct sockaddr *) &sock,
+                 sizeof( struct sockaddr_in ) ) < 0 )
+    {
+        hb_log( "connect failed" );
+        free( n );
+        return NULL;
+    }
+    
+    return n;
+}
+
+int hb_net_send( hb_net_t * n, char * buffer )
+{
+    return send( n->socket, buffer, strlen( buffer ), 0 );
+}
+
+int hb_net_recv( hb_net_t * n, char * buffer, int size )
+{
+    return recv( n->socket, buffer, size - 1, 0 );
+}
+
+void hb_net_close( hb_net_t ** _n )
+{
+    hb_net_t * n = (hb_net_t *) *_n;
+    close( n->socket );
+    free( n );
+    *_n = NULL;
+}
+
diff --git a/libhb/ports.h b/libhb/ports.h
new file mode 100644 (file)
index 0000000..4639c6b
--- /dev/null
@@ -0,0 +1,86 @@
+/* $Id: ports.h,v 1.7 2005/10/15 18:05:03 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_PORTS_H
+#define HB_PORTS_H
+
+/************************************************************************
+ * Utils
+ ***********************************************************************/
+uint64_t hb_get_date();
+void     hb_snooze( int delay );
+int      hb_get_cpu_count();
+
+#ifdef __LIBHB__
+
+/* Everything from now is only used internally and hidden to the UI */
+
+/************************************************************************
+ * Files utils
+ ***********************************************************************/
+void hb_get_tempory_directory( hb_handle_t * h, char path[512] );
+void hb_get_tempory_filename( hb_handle_t *, char name[1024],
+                              char * fmt, ... );
+void hb_mkdir( char * name );
+
+/************************************************************************
+ * Threads
+ ***********************************************************************/
+typedef struct hb_thread_s hb_thread_t;
+
+#if defined( SYS_BEOS )
+#  define HB_LOW_PRIORITY    5
+#  define HB_NORMAL_PRIORITY 10
+#elif defined( SYS_DARWIN )
+#  define HB_LOW_PRIORITY    0
+#  define HB_NORMAL_PRIORITY 31
+#elif defined( SYS_LINUX ) || defined( SYS_FREEBSD )
+#  define HB_LOW_PRIORITY    0
+#  define HB_NORMAL_PRIORITY 0
+#elif defined( SYS_CYGWIN )
+#  define HB_LOW_PRIORITY    0
+#  define HB_NORMAL_PRIORITY 1
+#endif
+
+hb_thread_t * hb_thread_init( char * name, void (* function)(void *),
+                              void * arg, int priority );
+void          hb_thread_close( hb_thread_t ** );
+int           hb_thread_has_exited( hb_thread_t * );
+
+/************************************************************************
+ * Mutexes
+ ***********************************************************************/
+typedef struct hb_lock_s hb_lock_t;
+
+hb_lock_t * hb_lock_init();
+void        hb_lock_close( hb_lock_t ** );
+void        hb_lock( hb_lock_t * );
+void        hb_unlock( hb_lock_t * );
+
+/************************************************************************
+ * Condition variables
+ ***********************************************************************/
+typedef struct hb_cond_s hb_cond_t;
+
+hb_cond_t * hb_cond_init();
+void        hb_cond_wait( hb_cond_t *, hb_lock_t * );
+void        hb_cond_signal( hb_cond_t * );
+void        hb_cond_close( hb_cond_t ** );
+
+/************************************************************************
+ * Network
+ ***********************************************************************/
+typedef struct hb_net_s hb_net_t;
+
+hb_net_t * hb_net_open( char * address, int port );
+int        hb_net_send( hb_net_t *, char * );
+int        hb_net_recv( hb_net_t *, char *, int );
+void       hb_net_close( hb_net_t ** );
+
+#endif /* __LIBHB__ */
+
+#endif
+
diff --git a/libhb/reader.c b/libhb/reader.c
new file mode 100644 (file)
index 0000000..e57467d
--- /dev/null
@@ -0,0 +1,155 @@
+/* $Id: reader.c,v 1.20 2005/04/29 19:55:54 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 "hb.h"
+
+typedef struct
+{
+    hb_job_t     * job;
+    hb_title_t   * title;
+    volatile int * die;
+
+    hb_dvd_t     * dvd;
+    hb_buffer_t  * ps;
+
+} hb_reader_t;
+
+/***********************************************************************
+ * Local prototypes
+ **********************************************************************/
+static void        ReaderFunc( void * );
+static hb_fifo_t * GetFifoForId( hb_job_t * job, int id );
+
+/***********************************************************************
+ * hb_reader_init
+ ***********************************************************************
+ *
+ **********************************************************************/
+hb_thread_t * hb_reader_init( hb_job_t * job )
+{
+    hb_reader_t * r;
+
+    r = calloc( sizeof( hb_reader_t ), 1 );
+
+    r->job   = job;
+    r->title = job->title;
+    r->die   = job->die;
+    
+    return hb_thread_init( "reader", ReaderFunc, r,
+                           HB_NORMAL_PRIORITY );
+}
+
+/***********************************************************************
+ * ReaderFunc
+ ***********************************************************************
+ *
+ **********************************************************************/
+static void ReaderFunc( void * _r )
+{
+    hb_reader_t  * r = _r;
+    hb_fifo_t    * fifo;
+    hb_buffer_t  * buf;
+    hb_list_t    * list;
+    int            chapter;
+
+    if( !( r->dvd = hb_dvd_init( r->title->dvd ) ) )
+    {
+        return;
+    }
+
+    if( !hb_dvd_start( r->dvd, r->title->index, r->job->chapter_start ) )
+    {
+        hb_dvd_close( &r->dvd );
+        return;
+    }
+
+    list  = hb_list_init();
+    r->ps = hb_buffer_init( 2048 );
+
+    while( !*r->die && !r->job->done )
+    {
+        chapter = hb_dvd_chapter( r->dvd );
+        if( chapter < 0 )
+        {
+            hb_log( "reader: end of the title reached" );
+            break;
+        }
+        if( chapter > r->job->chapter_end )
+        {
+            hb_log( "reader: end of chapter %d reached (%d)",
+                    r->job->chapter_end, chapter );
+            break;
+        }
+
+        if( !hb_dvd_read( r->dvd, r->ps ) )
+        {
+            break;
+        }
+
+        hb_demux_ps( r->ps, list );
+
+        while( ( buf = hb_list_item( list, 0 ) ) )
+        {
+            hb_list_rem( list, buf );
+            fifo = GetFifoForId( r->job, buf->id );
+            if( fifo )
+            {
+                while( !*r->die && !r->job->done &&
+                       hb_fifo_is_full( fifo ) )
+                {
+                    hb_snooze( 50 );
+                }
+                hb_fifo_push( fifo, buf );
+            }
+            else
+            {
+                hb_buffer_close( &buf );
+            }
+        }
+    }
+
+    hb_list_empty( &list );
+    hb_buffer_close( &r->ps );
+    hb_dvd_close( &r->dvd );
+
+    hb_log( "reader: done" );
+}
+
+/***********************************************************************
+ * GetFifoForId
+ ***********************************************************************
+ *
+ **********************************************************************/
+static hb_fifo_t * GetFifoForId( hb_job_t * job, int id )
+{
+    hb_title_t    * title = job->title;
+    hb_audio_t    * audio;
+    hb_subtitle_t * subtitle;
+    int             i;
+
+    if( id == 0xE0 )
+    {
+        return job->fifo_mpeg2;
+    }
+
+    if( ( subtitle = hb_list_item( title->list_subtitle, 0 ) ) &&
+        id == subtitle->id )
+    {
+        return subtitle->fifo_in;
+    }
+
+    for( i = 0; i < hb_list_count( title->list_audio ); i++ )
+    {
+        audio = hb_list_item( title->list_audio, i );
+        if( id == audio->id )
+        {
+            return audio->fifo_in;
+        }
+    }
+
+    return NULL;
+}
+
diff --git a/libhb/render.c b/libhb/render.c
new file mode 100644 (file)
index 0000000..914fa39
--- /dev/null
@@ -0,0 +1,167 @@
+/* $Id: render.c,v 1.17 2005/04/14 17:37:54 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 "hb.h"
+
+#include "ffmpeg/avcodec.h"
+
+struct hb_work_object_s
+{
+    HB_WORK_COMMON;
+
+    hb_job_t * job;
+
+    ImgReSampleContext * context;
+    AVPicture            pic_raw;
+    AVPicture            pic_deint;
+    AVPicture            pic_render;
+    hb_buffer_t        * buf_deint;
+};
+
+static void ApplySub( hb_job_t * job, hb_buffer_t * buf,
+                      hb_buffer_t ** _sub )
+{
+    hb_buffer_t * sub = *_sub;
+    hb_title_t * title = job->title;
+    int i, j, offset_top, offset_left;
+    uint8_t * lum, * alpha, * out;
+
+    if( !sub )
+    {
+        return;
+    }
+
+    if( sub->width > title->width - job->crop[0] - job->crop[1] - 40 ||
+        sub->height > title->height - job->crop[2] - job->crop[3] - 40 )
+    {
+        /* The subtitle won't fit */
+        hb_buffer_close( _sub );
+        return;
+    }
+
+    /* If necessary, move the subtitle so it is 20 pixels far from each
+       border of the cropped picture */
+    offset_top = sub->y;
+    offset_top = MAX( offset_top, job->crop[0] + 20 );
+    offset_top = MIN( offset_top,
+            title->height - job->crop[1] - 20 - sub->height );
+    offset_left = sub->x;
+    offset_left = MAX( offset_left, job->crop[2] + 20 );
+    offset_left = MIN( offset_left,
+            title->width - job->crop[3] - 20 - sub->width );
+
+    lum   = sub->data;
+    alpha = lum + sub->width * sub->height;
+    out   = buf->data + offset_top * title->width + offset_left;
+
+    for( i = 0; i < sub->height; i++ )
+    {
+        for( j = 0; j < sub->width; j++ )
+        {
+            out[j] = ( (uint16_t) out[j] * ( 16 - (uint16_t) alpha[j] ) +
+                       (uint16_t) lum[j] * (uint16_t) alpha[j] ) >> 4;
+        }
+        lum   += sub->width;
+        alpha += sub->width;
+        out   += title->width;
+    }
+
+    hb_buffer_close( _sub );
+}
+
+static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+                 hb_buffer_t ** buf_out )
+{
+    hb_job_t   * job   = w->job;
+    hb_title_t * title = job->title;
+    hb_buffer_t * in = *buf_in, * buf;
+
+    avpicture_fill( &w->pic_raw, in->data, PIX_FMT_YUV420P,
+                    title->width, title->height );
+
+    buf        = hb_buffer_init( 3 * job->width * job->height / 2 );
+    buf->start = in->start;
+    buf->stop  = in->stop;
+
+    if( job->deinterlace && w->context )
+    {
+        avpicture_fill( &w->pic_render, buf->data, PIX_FMT_YUV420P,
+                        job->width, job->height );
+        avpicture_deinterlace( &w->pic_deint, &w->pic_raw,
+                               PIX_FMT_YUV420P, title->width,
+                               title->height );
+        ApplySub( job, w->buf_deint, &in->sub );
+        img_resample( w->context, &w->pic_render, &w->pic_deint );
+    }
+    else if( job->deinterlace )
+    {
+        avpicture_fill( &w->pic_deint, buf->data, PIX_FMT_YUV420P,
+                        job->width, job->height );
+        avpicture_deinterlace( &w->pic_deint, &w->pic_raw,
+                               PIX_FMT_YUV420P, title->width,
+                               title->height );
+        ApplySub( job, buf, &in->sub );
+    }
+    else if( w->context )
+    {
+        ApplySub( job, in, &in->sub );
+        avpicture_fill( &w->pic_render, buf->data, PIX_FMT_YUV420P,
+                        job->width, job->height );
+        img_resample( w->context, &w->pic_render, &w->pic_raw );
+    }
+    else
+    {
+        hb_buffer_close( &buf );
+        ApplySub( job, in, &in->sub );
+        buf      = in;
+        *buf_in  = NULL;
+    }
+
+    (*buf_out) = buf;
+
+    return HB_WORK_OK;
+}
+
+static void Close( hb_work_object_t ** _w )
+{
+    hb_work_object_t * w = *_w;
+    free( w->name );
+    free( w );
+    *_w = NULL;
+}
+
+hb_work_object_t * hb_work_render_init( hb_job_t * job )
+{
+    hb_title_t * title;
+    
+    hb_work_object_t * w = calloc( sizeof( hb_work_object_t ), 1 );
+    w->name  = strdup( "Renderer" );
+    w->work  = Work;
+    w->close = Close;
+
+    title = job->title;
+
+    w->job = job;
+
+    if( job->crop[0] || job->crop[1] || job->crop[2] || job->crop[3] ||
+        job->width != title->width || job->height != title->height )
+    {
+        w->context = img_resample_full_init(
+            job->width, job->height, title->width, title->height,
+            job->crop[0], job->crop[1], job->crop[2], job->crop[3],
+            0, 0, 0, 0 );
+    }
+
+    if( job->deinterlace )
+    {
+        /* Allocate a constant buffer used for deinterlacing */
+        w->buf_deint = hb_buffer_init( 3 * title->width *
+                                       title->height / 2 );
+        avpicture_fill( &w->pic_deint, w->buf_deint->data,
+                        PIX_FMT_YUV420P, title->width, title->height );
+    }
+    return w;
+}
diff --git a/libhb/scan.c b/libhb/scan.c
new file mode 100644 (file)
index 0000000..812e840
--- /dev/null
@@ -0,0 +1,491 @@
+/* $Id: scan.c,v 1.51 2005/04/27 21:05:24 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 "hb.h"
+#include "a52dec/a52.h"
+
+typedef struct
+{
+    hb_handle_t * h;
+    
+    char        * path;
+    int           title_index;
+    hb_list_t   * list_title;
+    
+    hb_dvd_t    * dvd;
+
+} hb_scan_t;
+
+static void ScanFunc( void * );
+static int  DecodePreviews( hb_scan_t *, hb_title_t * title );
+static void LookForAC3( hb_title_t * title, hb_buffer_t * b );
+static int  AllAC3OK( hb_title_t * title );
+
+hb_thread_t * hb_scan_init( hb_handle_t * handle, const char * path,
+                            int title_index, hb_list_t * list_title )
+{
+    hb_scan_t * data = calloc( sizeof( hb_scan_t ), 1 );
+
+    data->h            = handle;
+    data->path         = strdup( path );
+    data->title_index  = title_index;
+    data->list_title   = list_title;
+
+    return hb_thread_init( "scan", ScanFunc, data, HB_NORMAL_PRIORITY );
+}
+
+static void ScanFunc( void * _data )
+{
+    hb_scan_t  * data = (hb_scan_t *) _data;
+    hb_title_t * title;
+    int          i;
+
+    /* Try to open the path as a DVD. If it fails, try as a file */
+    hb_log( "scan: trying to open with libdvdread" );
+    if( ( data->dvd = hb_dvd_init( data->path ) ) )
+    {
+        hb_log( "scan: DVD has %d title(s)",
+                hb_dvd_title_count( data->dvd ) );
+        if( data->title_index )
+        {
+            /* Scan this title only */
+            hb_list_add( data->list_title, hb_dvd_title_scan( data->dvd,
+                            data->title_index ) );
+        }
+        else
+        {
+            /* Scan all titles */
+            for( i = 0; i < hb_dvd_title_count( data->dvd ); i++ )
+            {
+                hb_list_add( data->list_title,
+                             hb_dvd_title_scan( data->dvd, i + 1 ) );
+            }
+        }
+    }
+    else
+    {
+       /* Open as a VOB file */
+        FILE * file;
+        hb_log( "scan: trying to open as VOB file" );
+        file = fopen( data->path, "rb" );
+        if( file )
+        {
+            /* XXX */
+            fclose( file );
+        }
+        else
+        {
+            hb_log( "scan: fopen failed" );
+            return;
+        }
+    }
+
+    for( i = 0; i < hb_list_count( data->list_title ); )
+    {
+        int j;
+        hb_state_t state;
+        hb_audio_t * audio;
+        hb_title_t * title_tmp = NULL;
+
+        title = hb_list_item( data->list_title, i );
+
+        /* I've seen a DVD with strictly identical titles. Check this
+           here and ignore it if redundant */
+        for( j = 0; j < i; j++ )
+        {
+            title_tmp = hb_list_item( data->list_title, j );
+            if( title->vts         == title_tmp->vts &&
+                title->block_start == title_tmp->block_start &&
+                title->block_end   == title_tmp->block_end &&
+                title->block_count == title_tmp->block_count )
+            {
+                break;
+            }
+            else
+            {
+                title_tmp = NULL;
+            }
+        }
+        if( title_tmp )
+        {
+            hb_log( "scan: title %d is duplicate with title %d",
+                    title->index, title_tmp->index );
+            hb_list_rem( data->list_title, title );
+            free( title );
+            continue;
+        }
+
+#define p state.param.scanning
+        /* Update the UI */
+        state.state   = HB_STATE_SCANNING;
+        p.title_cur   = title->index;
+        p.title_count = hb_dvd_title_count( data->dvd );
+        hb_set_state( data->h, &state );
+#undef p
+
+        /* Decode previews */
+        if( !DecodePreviews( data, title ) )
+        {
+            /* TODO: free things */
+            hb_list_rem( data->list_title, title );
+            continue;
+        }
+
+        /* Make sure we found AC3 rates and bitrates */
+        for( j = 0; j < hb_list_count( title->list_audio ); )
+        {
+            audio = hb_list_item( title->list_audio, j );
+            if( audio->codec == HB_ACODEC_AC3 &&
+                !audio->bitrate )
+            {
+                hb_list_rem( title->list_audio, audio );
+                free( audio );
+                continue;
+            }
+            j++;
+        }
+
+        /* Do we still have audio */
+        if( !hb_list_count( title->list_audio ) )
+        {
+            hb_list_rem( data->list_title, title );
+            free( title );
+            continue;
+        }
+        
+        i++;
+    }
+
+    /* Init jobs templates */
+    for( i = 0; i < hb_list_count( data->list_title ); i++ )
+    {
+        hb_job_t * job;
+
+        title      = hb_list_item( data->list_title, i );
+        job        = calloc( sizeof( hb_job_t ), 1 );
+        title->job = job;
+
+        job->title = title;
+
+        /* Set defaults settings */
+        job->chapter_start = 1;
+        job->chapter_end   = hb_list_count( title->list_chapter );
+
+        /* Autocrop by default. Gnark gnark */
+        memcpy( job->crop, title->crop, 4 * sizeof( int ) );
+
+        job->width = title->width - job->crop[2] - job->crop[3];
+        hb_fix_aspect( job, HB_KEEP_WIDTH );
+        if( job->height > title->height - job->crop[0] - job->crop[1] )
+        {
+            job->height = title->height - job->crop[0] - job->crop[1];
+            hb_fix_aspect( job, HB_KEEP_HEIGHT );
+        }
+        job->keep_ratio = 1;
+
+        job->vcodec     = HB_VCODEC_FFMPEG;
+        job->vquality   = -1.0;
+        job->vbitrate   = 1000;
+        job->pass       = 0;
+        job->vrate      = title->rate;
+        job->vrate_base = title->rate_base;
+
+        job->audios[0] = 0;
+        job->audios[1] = -1;
+
+        job->acodec   = HB_ACODEC_FAAC;
+        job->abitrate = 128;
+        job->arate    = 44100;
+
+        job->subtitle = -1;
+
+        job->mux = HB_MUX_MP4;
+    }
+
+    if( data->dvd )
+    {
+        hb_dvd_close( &data->dvd );
+    }
+}
+
+/***********************************************************************
+ * DecodePreviews
+ ***********************************************************************
+ * Decode 10 pictures for the given title.
+ * It assumes that data->reader and data->vts have successfully been
+ * DVDOpen()ed and ifoOpen()ed.
+ **********************************************************************/
+static int DecodePreviews( hb_scan_t * data, hb_title_t * title )
+{
+    int             i, ret;
+    hb_buffer_t   * buf_ps, * buf_es, * buf_raw;
+    hb_list_t     * list_es, * list_raw;
+    hb_libmpeg2_t * mpeg2;
+
+    buf_ps   = hb_buffer_init( 2048 );
+    list_es  = hb_list_init();
+    list_raw = hb_list_init();
+
+    hb_log( "scan: decoding previews for title %d", title->index );
+
+    hb_dvd_start( data->dvd, title->index, 1 );
+
+    for( i = 0; i < 10; i++ )
+    {
+        int j, k;
+        FILE * file_preview;
+        char   filename[1024];
+
+        hb_dvd_seek( data->dvd, (float) ( i + 1 ) / 11.0 );
+
+        hb_log( "scan: preview %d", i + 1 );
+
+        mpeg2 = hb_libmpeg2_init();
+
+        for( j = 0; j < 10240; j++ )
+        {
+            if( !hb_dvd_read( data->dvd, buf_ps ) )
+            {
+                goto error;
+            }
+            hb_demux_ps( buf_ps, list_es );
+
+            while( ( buf_es = hb_list_item( list_es, 0 ) ) )
+            {
+                hb_list_rem( list_es, buf_es );
+                if( buf_es->id == 0xE0 && !hb_list_count( list_raw ) )
+                {
+                    hb_libmpeg2_decode( mpeg2, buf_es, list_raw );
+                }
+                else if( !i )
+                {
+                    LookForAC3( title, buf_es );
+                }
+                hb_buffer_close( &buf_es );
+
+                if( hb_list_count( list_raw ) &&
+                    ( i || AllAC3OK( title ) ) )
+                {
+                    /* We got a picture */
+                    break;
+                }
+            }
+
+            if( hb_list_count( list_raw ) &&
+                ( i || AllAC3OK( title ) ) )
+            {
+                break;
+            }
+        }
+
+        if( !hb_list_count( list_raw ) )
+        {
+            hb_log( "scan: could not get a decoded picture" );
+            goto error;
+        }
+
+        if( !i )
+        {
+            /* Get size and rate infos */
+            title->rate = 27000000;
+            hb_libmpeg2_info( mpeg2, &title->width, &title->height,
+                              &title->rate_base );
+            title->crop[0] = title->crop[1] = title->height / 2;
+            title->crop[2] = title->crop[3] = title->width / 2;
+        }
+
+        hb_libmpeg2_close( &mpeg2 );
+
+        while( ( buf_es = hb_list_item( list_es, 0 ) ) )
+        {
+            hb_list_rem( list_es, buf_es );
+            hb_buffer_close( &buf_es );
+        }
+
+        buf_raw = hb_list_item( list_raw, 0 );
+
+        hb_get_tempory_filename( data->h, filename, "%x%d",
+                                 (int) title, i );
+
+        file_preview = fopen( filename, "w" );
+        if( file_preview )
+        {
+            fwrite( buf_raw->data, title->width * title->height * 3 / 2,
+                    1, file_preview );
+            fclose( file_preview );
+        }
+        else
+        {
+            hb_log( "scan: fopen failed (%s)", filename );
+        }
+
+#define Y    buf_raw->data
+#define DARK 64
+        
+        /* Detect black borders */
+        
+        for( j = 0; j < title->width; j++ )
+        {
+            for( k = 0; k < title->crop[0]; k++ )
+                if( Y[ k * title->width + j ] > DARK )
+                {
+                    title->crop[0] = k;
+                    break;
+                }
+            for( k = 0; k < title->crop[1]; k++ )
+                if( Y[ ( title->height - k - 1 ) *
+                       title->width + j ] > DARK )
+                {
+                    title->crop[1] = k;
+                    break;
+                }
+        }
+        for( j = 0; j < title->height; j++ )
+        {
+            for( k = 0; k < title->crop[2]; k++ ) 
+                if( Y[ j * title->width + k ] > DARK )
+                {
+                    title->crop[2] = k;
+                    break;
+                }
+            for( k = 0; k < title->crop[3]; k++ )
+                if( Y[ j * title->width +
+                        title->width - k - 1 ] > DARK )
+                {
+                    title->crop[3] = k;
+                    break;
+                }
+        }
+
+        while( ( buf_raw = hb_list_item( list_raw, 0 ) ) )
+        {
+            hb_list_rem( list_raw, buf_raw );
+            hb_buffer_close( &buf_raw );
+        }
+    }
+
+    title->crop[0] = EVEN( title->crop[0] );
+    title->crop[1] = EVEN( title->crop[1] );
+    title->crop[2] = EVEN( title->crop[2] );
+    title->crop[3] = EVEN( title->crop[3] );
+
+    hb_log( "scan: %dx%d, %.3f fps, autocrop = %d/%d/%d/%d",
+            title->width, title->height, (float) title->rate /
+            (float) title->rate_base, title->crop[0], title->crop[1],
+            title->crop[2], title->crop[3] );
+
+    ret = 1;
+    goto cleanup;
+
+error:
+    ret = 0;
+
+cleanup:
+    hb_buffer_close( &buf_ps );
+    while( ( buf_es = hb_list_item( list_es, 0 ) ) )
+    {
+        hb_list_rem( list_es, buf_es );
+        hb_buffer_close( &buf_es );
+    }
+    hb_list_close( &list_es );
+    while( ( buf_raw = hb_list_item( list_raw, 0 ) ) )
+    {
+        hb_list_rem( list_raw, buf_raw );
+        hb_buffer_close( &buf_raw );
+    }
+    hb_list_close( &list_raw );
+    return ret;
+}
+
+static void LookForAC3( hb_title_t * title, hb_buffer_t * b ) 
+{
+    int i;
+    int flags;
+    int rate;
+    int bitrate;
+
+    /* Figure out if this is a AC3 buffer for a known track */
+    hb_audio_t * audio = NULL;
+    for( i = 0; i < hb_list_count( title->list_audio ); i++ )
+    {
+        audio = hb_list_item( title->list_audio, i );
+        if( audio->codec == HB_ACODEC_AC3 &&
+            audio->id    == b->id )
+        {
+            break;
+        }
+        else
+        {
+            audio = NULL;
+        }
+    }
+    if( !audio )
+    {
+        return;
+    }
+
+    if( audio->bitrate )
+    {
+        /* Already done for this track */
+        return;
+    }
+
+    for( i = 0; i < b->size - 7; i++ )
+    {
+        if( a52_syncinfo( &b->data[i], &flags, &rate, &bitrate ) )
+        {
+            hb_log( "scan: rate=%dHz, bitrate=%d", rate, bitrate );
+            audio->rate    = rate;
+            audio->bitrate = bitrate;
+            switch( flags & A52_CHANNEL_MASK )
+            {
+                case A52_MONO:
+                case A52_CHANNEL1:
+                case A52_CHANNEL2:
+                    audio->channels = 1;
+                    break;
+                case A52_STEREO:
+                case A52_DOLBY:
+                case A52_CHANNEL:
+                    audio->channels = 2;
+                    break;
+                case A52_3F:
+                case A52_2F1R:
+                    audio->channels = 3;
+                    break;
+                case A52_3F1R:
+                case A52_2F2R:
+                    audio->channels = 4;
+                    break;
+                case A52_3F2R:
+                    audio->channels = 5;
+                    break;
+            }
+            /* XXX */
+            sprintf( audio->lang + strlen( audio->lang ),
+                     " (%d ch)", audio->channels );
+            break;
+        }
+    }
+}
+
+static int  AllAC3OK( hb_title_t * title )
+{
+    int i;
+    hb_audio_t * audio;
+
+    for( i = 0; i < hb_list_count( title->list_audio ); i++ )
+    {
+        audio = hb_list_item( title->list_audio, i );
+        if( audio->codec == HB_ACODEC_AC3 &&
+            !audio->bitrate )
+        {
+            return 0;
+        }
+    }
+
+    return 1;
+}
diff --git a/libhb/sync.c b/libhb/sync.c
new file mode 100644 (file)
index 0000000..e0530a0
--- /dev/null
@@ -0,0 +1,664 @@
+/* $Id: sync.c,v 1.38 2005/04/14 21:57:58 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 "hb.h"
+
+#include "samplerate.h"
+#include "ffmpeg/avcodec.h"
+
+#ifdef INT64_MIN
+#undef INT64_MIN /* Because it isn't defined correctly in Zeta */
+#endif
+#define INT64_MIN (-9223372036854775807LL-1)
+
+#define AC3_SAMPLES_PER_FRAME 1536
+
+typedef struct
+{
+    hb_audio_t * audio;
+    int64_t      count_frames;
+    
+    /* Raw */
+    SRC_STATE  * state;
+    SRC_DATA     data;
+
+    /* AC-3 */
+    int          ac3_size;
+    uint8_t    * ac3_buf;
+
+} hb_sync_audio_t;
+
+struct hb_work_object_s
+{
+    HB_WORK_COMMON;
+
+    hb_job_t * job;
+    int        done;
+
+    /* Video */
+    hb_subtitle_t * subtitle;
+    int64_t pts_offset;
+    int64_t pts_offset_old;
+    int64_t count_frames;
+    int64_t count_frames_max;
+    hb_buffer_t * cur; /* The next picture to process */
+
+    /* Audio */
+    hb_sync_audio_t sync_audio[8];
+
+    /* Statistics */
+    uint64_t st_counts[4];
+    uint64_t st_dates[4];
+    uint64_t st_first;
+};
+
+/***********************************************************************
+ * Local prototypes
+ **********************************************************************/
+static void InitAudio( hb_work_object_t * w, int i );
+static void Close( hb_work_object_t ** _w );
+static int  Work( hb_work_object_t * w, hb_buffer_t ** unused1,
+                  hb_buffer_t ** unused2 );
+static int  SyncVideo( hb_work_object_t * w );
+static void SyncAudio( hb_work_object_t * w, int i );
+static int  NeedSilence( hb_work_object_t * w, hb_audio_t * );
+static void InsertSilence( hb_work_object_t * w, int i );
+static void UpdateState( hb_work_object_t * w );
+
+/***********************************************************************
+ * hb_work_sync_init
+ ***********************************************************************
+ * Initialize the work object
+ **********************************************************************/
+hb_work_object_t * hb_work_sync_init( hb_job_t * job )
+{
+    hb_work_object_t * w;
+    hb_title_t       * title = job->title;
+    hb_chapter_t     * chapter;
+    int                i;
+    uint64_t           duration;
+
+    w        = calloc( sizeof( hb_work_object_t ), 1 );
+    w->name  = strdup( "Synchronization" );
+    w->work  = Work;
+    w->close = Close;
+
+    w->job            = job;
+    w->pts_offset     = INT64_MIN;
+    w->pts_offset_old = INT64_MIN;
+    w->count_frames   = 0;
+
+    /* Calculate how many video frames we are expecting */
+    duration = 0;
+    for( i = job->chapter_start; i <= job->chapter_end; i++ )
+    {
+        chapter   = hb_list_item( title->list_chapter, i - 1 );
+        duration += chapter->duration;
+    }                                                                           
+    duration += 90000;
+        /* 1 second safety so we're sure we won't miss anything */
+    w->count_frames_max = duration * job->vrate / job->vrate_base / 90000;
+
+    hb_log( "sync: expecting %lld video frames", w->count_frames_max );
+
+    /* Initialize libsamplerate for every audio track we have */
+    for( i = 0; i < hb_list_count( title->list_audio ); i++ )
+    {
+        InitAudio( w, i );
+    }
+
+    /* Get subtitle info, if any */
+    w->subtitle = hb_list_item( title->list_subtitle, 0 );
+
+    return w;
+}
+
+static void InitAudio( hb_work_object_t * w, int i )
+{
+    hb_job_t        * job   = w->job;
+    hb_title_t      * title = job->title;
+    hb_sync_audio_t * sync;
+
+    sync        = &w->sync_audio[i];
+    sync->audio = hb_list_item( title->list_audio, i );
+
+    if( job->acodec & HB_ACODEC_AC3 )
+    {
+        /* Have a silent AC-3 frame ready in case we have to fill a
+           gap */
+        AVCodec        * codec;
+        AVCodecContext * c;
+        short          * zeros;
+
+        codec = avcodec_find_encoder( CODEC_ID_AC3 );
+        c     = avcodec_alloc_context();
+
+        c->bit_rate    = sync->audio->bitrate;
+        c->sample_rate = sync->audio->rate;
+        c->channels    = sync->audio->channels;
+
+        if( avcodec_open( c, codec ) < 0 )
+        {
+            hb_log( "sync: avcodec_open failed" );
+            return;
+        }
+
+        zeros          = calloc( AC3_SAMPLES_PER_FRAME *
+                                 sizeof( short ) * c->channels, 1 );
+        sync->ac3_size = sync->audio->bitrate * AC3_SAMPLES_PER_FRAME /
+                             sync->audio->rate / 8;
+        sync->ac3_buf  = malloc( sync->ac3_size );
+
+        if( avcodec_encode_audio( c, sync->ac3_buf, sync->ac3_size,
+                                  zeros ) != sync->ac3_size )
+        {
+            hb_log( "sync: avcodec_encode_audio failed" );
+        }
+        
+        free( zeros );
+        avcodec_close( c );
+        av_free( c );
+    }
+    else
+    {
+        /* Initialize libsamplerate */
+        int error;
+        sync->state             = src_new( SRC_LINEAR, 2, &error );
+        sync->data.end_of_input = 0;
+    }
+}
+
+/***********************************************************************
+ * Close
+ ***********************************************************************
+ *
+ **********************************************************************/
+static void Close( hb_work_object_t ** _w )
+{
+    hb_work_object_t * w     = *_w;
+    hb_job_t         * job   = w->job;
+    hb_title_t       * title = job->title;
+    
+    int i;
+
+    if( w->cur ) hb_buffer_close( &w->cur );
+
+    for( i = 0; i < hb_list_count( title->list_audio ); i++ )
+    {
+        if( job->acodec & HB_ACODEC_AC3 )
+        {
+            free( w->sync_audio[i].ac3_buf );
+        }
+        else
+        {
+            src_delete( w->sync_audio[i].state );
+        }
+    }
+
+    free( w->name );    
+    free( w );
+    *_w = NULL;
+}
+
+/***********************************************************************
+ * Work
+ ***********************************************************************
+ * The root routine of this work abject
+ **********************************************************************/
+static int Work( hb_work_object_t * w, hb_buffer_t ** unused1,
+                 hb_buffer_t ** unused2 )
+{
+    int i;
+
+    /* If we ever got a video frame, handle audio now */
+    if( w->pts_offset != INT64_MIN )
+    {
+        for( i = 0; i < hb_list_count( w->job->title->list_audio ); i++ )
+        {
+            SyncAudio( w, i );
+        }
+    }
+
+    /* Handle video */
+    return SyncVideo( w );
+}
+
+/***********************************************************************
+ * SyncVideo
+ ***********************************************************************
+ * 
+ **********************************************************************/
+static int SyncVideo( hb_work_object_t * w )
+{
+    hb_buffer_t * cur, * next, * sub = NULL;
+    hb_job_t * job = w->job;
+    int64_t pts_expected;
+
+    if( w->done )
+    {
+        return HB_WORK_DONE;
+    }
+
+    if( hb_thread_has_exited( job->reader ) &&
+        !hb_fifo_size( job->fifo_mpeg2 ) &&
+        !hb_fifo_size( job->fifo_raw ) )
+    {
+        /* All video data has been processed already, we won't get
+           more */
+        hb_log( "sync: got %lld frames, %lld expected",
+                w->count_frames, w->count_frames_max );
+        w->done = 1;
+        return HB_WORK_DONE;
+    }
+
+    if( !w->cur && !( w->cur = hb_fifo_get( job->fifo_raw ) ) )
+    {
+        /* We haven't even got a frame yet */
+        return HB_WORK_OK;
+    }
+    cur = w->cur;
+
+    /* At this point we have a frame to process. Let's check
+        1) if we will be able to push into the fifo ahead
+        2) if the next frame is there already, since we need it to
+           know whether we'll have to repeat the current frame or not */
+    while( !hb_fifo_is_full( job->fifo_sync ) &&
+           ( next = hb_fifo_see( job->fifo_raw ) ) )
+    {
+        hb_buffer_t * buf_tmp;
+
+        if( w->pts_offset == INT64_MIN )
+        {
+            /* This is our first frame */
+            hb_log( "sync: first pts is %lld", cur->start );
+            w->pts_offset = cur->start;
+        }
+
+        /* Check for PTS jumps over 0.5 second */
+        if( next->start < cur->start - 45000 ||
+            next->start > cur->start + 45000 )
+        {
+            hb_log( "PTS discontinuity (%lld, %lld)",
+                    cur->start, next->start );
+            
+            /* Trash all subtitles */
+            if( w->subtitle )
+            {
+                while( ( sub = hb_fifo_get( w->subtitle->fifo_raw ) ) )
+                {
+                    hb_buffer_close( &sub );
+                }
+            }
+
+            /* Trash current picture */
+            hb_buffer_close( &cur );
+            w->cur = cur = hb_fifo_get( job->fifo_raw );
+
+            /* Calculate new offset */
+            w->pts_offset_old = w->pts_offset;
+            w->pts_offset     = cur->start -
+                w->count_frames * w->job->vrate_base / 300;
+            continue;
+        }
+
+        /* Look for a subtitle for this frame */
+        if( w->subtitle )
+        {
+            /* Trash subtitles older than this picture */
+            while( ( sub = hb_fifo_see( w->subtitle->fifo_raw ) ) &&
+                    sub->stop < cur->start )
+            {
+                sub = hb_fifo_get( w->subtitle->fifo_raw );
+                hb_buffer_close( &sub );
+            }
+
+            /* If we have subtitles left in the fifo, check if we should
+               apply the first one to the current frame or if we should
+               keep it for later */
+            if( sub && sub->start > cur->start )
+            {
+                sub = NULL;
+            }
+        }
+
+        /* The PTS of the frame we are expecting now */
+        pts_expected = w->pts_offset +
+            w->count_frames * w->job->vrate_base / 300;
+
+        if( cur->start < pts_expected - w->job->vrate_base / 300 / 2 &&
+            next->start < pts_expected + w->job->vrate_base / 300 / 2 )
+        {
+            /* The current frame is too old but the next one matches,
+               let's trash */
+            hb_buffer_close( &cur );
+            w->cur = cur = hb_fifo_get( job->fifo_raw );
+            continue;
+        }
+
+        if( next->start > pts_expected + 3 * w->job->vrate_base / 300 / 2 )
+        {
+            /* We'll need the current frame more than one time. Make a
+               copy of it and keep it */
+            buf_tmp = hb_buffer_init( cur->size );
+            memcpy( buf_tmp->data, cur->data, cur->size );
+        }
+        else
+        {
+            /* The frame has the expected date and won't have to be
+               duplicated, just put it through */
+            buf_tmp = cur;
+            w->cur = cur = hb_fifo_get( job->fifo_raw );
+        }
+
+        /* Replace those MPEG-2 dates with our dates */
+        buf_tmp->start = (uint64_t) w->count_frames *
+            w->job->vrate_base / 300;
+        buf_tmp->stop  = (uint64_t) ( w->count_frames + 1 ) *
+            w->job->vrate_base / 300;
+
+        /* If we have a subtitle for this picture, copy it */
+        /* FIXME: we should avoid this memcpy */
+        if( sub )
+        {
+            buf_tmp->sub         = hb_buffer_init( sub->size );
+            buf_tmp->sub->x      = sub->x;
+            buf_tmp->sub->y      = sub->y;
+            buf_tmp->sub->width  = sub->width;
+            buf_tmp->sub->height = sub->height;
+            memcpy( buf_tmp->sub->data, sub->data, sub->size );
+        }
+
+        /* Push the frame to the renderer */
+        hb_fifo_push( job->fifo_sync, buf_tmp );
+
+        /* Update UI */
+        UpdateState( w );
+
+        /* Make sure we won't get more frames then expected */
+        if( w->count_frames >= w->count_frames_max )
+        {
+            hb_log( "sync: got %lld frames", w->count_frames );
+            w->done = 1;
+            break;
+        }
+    }
+
+    return HB_WORK_OK;
+}
+
+/***********************************************************************
+ * SyncAudio
+ ***********************************************************************
+ * 
+ **********************************************************************/
+static void SyncAudio( hb_work_object_t * w, int i )
+{
+    hb_job_t        * job;
+    hb_audio_t      * audio;
+    hb_buffer_t     * buf;
+    hb_sync_audio_t * sync;
+
+    hb_fifo_t       * fifo;
+    int               rate;
+
+    int64_t           pts_expected;
+    int64_t           start;
+
+    job    = w->job;
+    sync   = &w->sync_audio[i];
+    audio  = sync->audio;
+
+    if( job->acodec & HB_ACODEC_AC3 )
+    {
+        fifo = audio->fifo_out;
+        rate = audio->rate;
+    }
+    else
+    {
+        fifo = audio->fifo_sync;
+        rate = job->arate;
+    }
+
+    while( !hb_fifo_is_full( fifo ) &&
+           ( buf = hb_fifo_see( audio->fifo_raw ) ) )
+    {
+        /* The PTS of the samples we are expecting now */
+        pts_expected = w->pts_offset + sync->count_frames * 90000 / rate;
+
+        if( ( buf->start > pts_expected + 45000 ||
+              buf->start < pts_expected - 45000 ) &&
+            w->pts_offset_old > INT64_MIN )
+        {
+            /* There has been a PTS discontinuity, and this frame might
+               be from before the discontinuity */
+            pts_expected = w->pts_offset_old + sync->count_frames *
+                90000 / rate;
+
+            if( buf->start > pts_expected + 45000 ||
+                buf->start < pts_expected - 45000 )
+            {
+                /* There is really nothing we can do with it */
+                buf = hb_fifo_get( audio->fifo_raw );
+                hb_buffer_close( &buf );
+                continue;
+            }
+
+            /* Use the older offset */
+            start = pts_expected - w->pts_offset_old;
+        }
+        else
+        {
+            start = pts_expected - w->pts_offset;
+        }
+
+        if( ( buf->start + buf->stop ) / 2 < pts_expected )
+        {
+            /* Late audio, trash it */
+            buf = hb_fifo_get( audio->fifo_raw );
+            hb_buffer_close( &buf );
+            continue;
+        }
+
+        if( buf->start > pts_expected + ( buf->stop - buf->start ) / 2 )
+        {
+            /* Audio push, send a frame of silence */
+            InsertSilence( w, i );
+            continue;
+        }
+
+        if( job->acodec & HB_ACODEC_AC3 )
+        {
+            buf        = hb_fifo_get( audio->fifo_raw );
+            buf->start = start;
+            buf->stop  = start + 90000 * AC3_SAMPLES_PER_FRAME / rate;
+
+            sync->count_frames += AC3_SAMPLES_PER_FRAME;
+        }
+        else
+        {
+            hb_buffer_t * buf_raw = hb_fifo_get( audio->fifo_raw );
+
+            int count_in, count_out;
+
+            count_in  = buf_raw->size / 2 / sizeof( float );
+            count_out = ( buf->stop - pts_expected ) * job->arate / 90000;
+
+            sync->data.data_in      = (float *) buf_raw->data;
+            sync->data.input_frames = count_in;
+
+            if( buf->start < pts_expected - ( buf->stop - buf->start ) / 5 )
+            {
+                /* Avoid too heavy downsampling, trash the beginning of
+                   the buffer instead */
+                int drop;
+                drop = count_in * ( pts_expected - buf->start ) /
+                           ( buf->stop - buf->start );
+                sync->data.data_in      += 2 * drop;
+                sync->data.input_frames -= drop;
+                hb_log( "dropping %d of %d samples", drop, count_in );
+            }
+
+            sync->data.output_frames = count_out;
+            sync->data.src_ratio = (double) sync->data.output_frames /
+                                   (double) sync->data.input_frames;
+
+            buf = hb_buffer_init( sync->data.output_frames * 2 *
+                                  sizeof( float ) );
+            sync->data.data_out = (float *) buf->data;
+            if( src_process( sync->state, &sync->data ) )
+            {
+                /* XXX If this happens, we're screwed */
+                hb_log( "sync: src_process failed" );
+            }
+            hb_buffer_close( &buf_raw );
+
+            buf->size = sync->data.output_frames_gen * 2 * sizeof( float );
+
+            /* Set dates for resampled data */
+            buf->start = start;
+            buf->stop  = start + sync->data.output_frames_gen *
+                            90000 / job->arate;
+
+            sync->count_frames += sync->data.output_frames_gen;
+        }
+
+        buf->key = 1;
+        hb_fifo_push( fifo, buf );
+    }
+
+    if( NeedSilence( w, audio ) )
+    {
+        InsertSilence( w, i );
+    }
+}
+
+static int NeedSilence( hb_work_object_t * w, hb_audio_t * audio )
+{
+    hb_job_t * job = w->job;
+
+    if( hb_fifo_size( audio->fifo_in ) ||
+        hb_fifo_size( audio->fifo_raw ) ||
+        hb_fifo_size( audio->fifo_sync ) ||
+        hb_fifo_size( audio->fifo_out ) )
+    {
+        /* We have some audio, we are fine */
+        return 0;
+    }
+
+    /* No audio left in fifos */
+
+    if( hb_thread_has_exited( job->reader ) )
+    {
+        /* We might miss some audio to complete encoding and muxing
+           the video track */
+        return 1;
+    }
+
+    if( hb_fifo_is_full( job->fifo_mpeg2 ) &&
+        hb_fifo_is_full( job->fifo_raw ) &&
+        hb_fifo_is_full( job->fifo_sync ) &&
+        hb_fifo_is_full( job->fifo_render ) &&
+        hb_fifo_is_full( job->fifo_mpeg4 ) )
+    {
+        /* Too much video and no audio, oh-oh */
+        return 1;
+    }
+
+    return 0;
+}
+
+static void InsertSilence( hb_work_object_t * w, int i )
+{
+    hb_job_t        * job;
+    hb_sync_audio_t * sync;
+    hb_buffer_t     * buf;
+
+    job    = w->job;
+    sync   = &w->sync_audio[i];
+
+    if( job->acodec & HB_ACODEC_AC3 )
+    {
+        buf        = hb_buffer_init( sync->ac3_size );
+        buf->start = sync->count_frames * 90000 / sync->audio->rate;
+        buf->stop  = buf->start + 90000 * AC3_SAMPLES_PER_FRAME /
+                     sync->audio->rate;
+        memcpy( buf->data, sync->ac3_buf, buf->size );
+
+        hb_log( "sync: adding a silent AC-3 frame for track %x",
+                sync->audio->id );
+        hb_fifo_push( sync->audio->fifo_out, buf );
+
+        sync->count_frames += AC3_SAMPLES_PER_FRAME;
+
+    }
+    else
+    {
+        buf        = hb_buffer_init( 2 * job->arate / 20 *
+                                     sizeof( float ) );
+        buf->start = sync->count_frames * 90000 / job->arate;
+        buf->stop  = buf->start + 90000 / 20;
+        memset( buf->data, 0, buf->size );
+
+        hb_log( "sync: adding 50 ms of silence for track %x",
+                sync->audio->id );
+        hb_fifo_push( sync->audio->fifo_sync, buf );
+
+        sync->count_frames += job->arate / 20;
+    }
+}
+
+static void UpdateState( hb_work_object_t * w )
+{
+    hb_state_t state;
+
+    if( !w->count_frames )
+    {
+        w->st_first = hb_get_date();
+    }
+    w->count_frames++;
+
+    if( hb_get_date() > w->st_dates[3] + 1000 )
+    {
+        memmove( &w->st_dates[0], &w->st_dates[1],
+                 3 * sizeof( uint64_t ) );
+        memmove( &w->st_counts[0], &w->st_counts[1],
+                 3 * sizeof( uint64_t ) );
+        w->st_dates[3]  = hb_get_date();
+        w->st_counts[3] = w->count_frames;
+    } 
+
+#define p state.param.working
+    state.state = HB_STATE_WORKING;
+    p.progress  = (float) w->count_frames / (float) w->count_frames_max;
+    if( p.progress > 1.0 )
+    {
+        p.progress = 1.0; 
+    }
+    p.rate_cur   = 1000.0 *
+        (float) ( w->st_counts[3] - w->st_counts[0] ) /
+        (float) ( w->st_dates[3] - w->st_dates[0] );
+    if( hb_get_date() > w->st_first + 4000 )
+    {
+        int eta;
+        p.rate_avg = 1000.0 * (float) w->st_counts[3] /
+            (float) ( w->st_dates[3] - w->st_first );
+        eta = (float) ( w->count_frames_max - w->st_counts[3] ) /
+            p.rate_avg;
+        p.hours   = eta / 3600;
+        p.minutes = ( eta % 3600 ) / 60;
+        p.seconds = eta % 60;
+    }
+    else
+    {
+        p.rate_avg = 0.0;
+        p.hours    = -1;
+        p.minutes  = -1;
+        p.seconds  = -1;
+    }
+#undef p
+
+    hb_set_state( w->job->h, &state );
+}
diff --git a/libhb/update.c b/libhb/update.c
new file mode 100644 (file)
index 0000000..7678070
--- /dev/null
@@ -0,0 +1,157 @@
+/* $Id: update.c,v 1.7 2005/03/26 23:04:14 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 "hb.h"
+
+#define HB_URL   "handbrake.m0k.org"
+#define HB_QUERY "GET /LATEST HTTP/1.0\r\nHost: " HB_URL "\r\n\r\n"
+
+typedef struct
+{
+    int  * build;
+    char * version;
+
+} hb_update_t;
+
+static void UpdateFunc( void * );
+
+hb_thread_t * hb_update_init( int * build, char * version )
+{
+    hb_update_t * data = calloc( sizeof( hb_update_t ), 1 );
+    data->build   = build;
+    data->version = version;
+
+    return hb_thread_init( "update", UpdateFunc, data,
+                           HB_NORMAL_PRIORITY );
+}
+
+static void UpdateFunc( void * _data )
+{
+    hb_update_t * data = (hb_update_t *) _data;
+
+    hb_net_t * net;
+    int        ret;
+    char       buf[1024];
+    char     * cur, * end, * p;
+    int        size;
+    int        stable, unstable;
+    char       stable_str[16], unstable_str[16];
+    int        i;
+
+    if( !( net = hb_net_open( HB_URL, 80 ) ) )
+    {
+        goto error;
+    }
+
+    if( hb_net_send( net, HB_QUERY ) < 0 )
+    {
+        hb_net_close( &net );
+        goto error;
+    }
+
+    size = 0;
+    memset( buf, 0, 1024 );
+    for( ;; )
+    {
+        ret = hb_net_recv( net, &buf[size], sizeof( buf ) - size );
+        if( ret < 1 )
+        {
+            hb_net_close( &net );
+            break;
+        }
+        size += ret;
+    }
+
+    cur = buf;
+    end = &buf[sizeof( buf )];
+
+    /* Make sure we got it */
+    cur += 9;
+    if( size < 15 || strncmp( cur, "200 OK", 6 ) )
+    {
+        /* Something went wrong */
+        goto error;
+    }
+    cur += 6;
+
+    /* Find the end of the headers and the beginning of the content */
+    for( ; &cur[3] < end; cur++ )
+    {
+        if( cur[0] == '\r' && cur[1] == '\n' &&
+            cur[2] == '\r' && cur[3] == '\n' )
+        {
+            cur += 4;
+            break;
+        }
+    }
+
+    if( cur >= end )
+    {
+        goto error;
+    }
+
+    stable = strtol( cur, &p, 10 );
+    if( cur == p )
+    {
+        goto error;
+    }
+    cur = p + 1;
+    memset( stable_str, 0, sizeof( stable_str ) );
+    for( i = 0;
+         i < sizeof( stable_str ) - 1 && cur < end && *cur != '\n';
+         i++, cur++ )
+    {
+        stable_str[i] = *cur;
+    }
+
+    hb_log( "latest stable: %s, build %d", stable_str, stable );
+
+    cur++;
+    if( cur >= end )
+    {
+        goto error;
+    }
+
+    unstable = strtol( cur, &p, 10 );
+    if( cur == p )
+    {
+        goto error;
+    }
+    cur = p + 1;
+    memset( unstable_str, 0, sizeof( unstable_str ) );
+    for( i = 0;
+         i < sizeof( unstable_str ) - 1 && cur < end && *cur != '\n';
+         i++, cur++ )
+    {
+        unstable_str[i] = *cur;
+    }
+
+    hb_log( "latest unstable: %s, build %d", unstable_str, unstable );
+
+    if( HB_BUILD % 100 )
+    {
+        /* We are runnning an unstable build */
+        if( unstable > HB_BUILD )
+        {
+            memcpy( data->version, unstable_str, sizeof( unstable_str ) );
+            *(data->build) = unstable;
+        }
+    }
+    else
+    {
+        /* We are runnning an stable build */
+        if( stable > HB_BUILD )
+        {
+            memcpy( data->version, stable_str, sizeof( stable_str ) );
+            *(data->build) = stable;
+        }
+    }
+
+error:
+    free( data );
+    return;
+}
+
diff --git a/libhb/work.c b/libhb/work.c
new file mode 100644 (file)
index 0000000..6c0be24
--- /dev/null
@@ -0,0 +1,400 @@
+/* $Id: work.c,v 1.43 2005/03/17 16:38:49 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 "hb.h"
+
+struct hb_work_object_s
+{
+    HB_WORK_COMMON;
+};
+
+typedef struct
+{
+    hb_list_t * jobs;
+    int         cpu_count;
+    int       * error;
+    volatile int * die;
+
+} hb_work_t;
+
+static void work_func();
+static void do_job( hb_job_t *, int cpu_count );
+static void job_loop( void * );
+
+hb_thread_t * hb_work_init( hb_list_t * jobs, int cpu_count,
+                            volatile int * die, int * error )
+{
+    hb_work_t * work = calloc( sizeof( hb_work_t ), 1 );
+
+    work->jobs      = jobs;
+    work->cpu_count = cpu_count;
+    work->die       = die;
+    work->error     = error;
+
+    return hb_thread_init( "work", work_func, work, HB_LOW_PRIORITY );
+}
+
+static void work_func( void * _work )
+{
+    hb_work_t  * work = _work;
+    hb_job_t   * job;
+
+    hb_log( "%d job(s) to process", hb_list_count( work->jobs ) );
+
+    while( !*work->die && ( job = hb_list_item( work->jobs, 0 ) ) )
+    {
+        hb_list_rem( work->jobs, job );
+        job->die = work->die;
+        do_job( job, work->cpu_count );
+    }
+
+    *(work->error) = HB_ERROR_NONE;
+
+    free( work );
+}
+
+static void do_job( hb_job_t * job, int cpu_count )
+{
+    hb_title_t    * title;
+    int             i;
+    hb_thread_t   * threads[8];
+    hb_work_object_t * w;
+    uint64_t time_total;
+    hb_audio_t   * audio;
+    hb_subtitle_t * subtitle;
+
+    title = job->title;
+
+    job->list_work = hb_list_init();
+
+    hb_log( "starting job" );
+    hb_log( " + device %s", title->dvd );
+    hb_log( " + title %d, chapter(s) %d to %d", title->index,
+            job->chapter_start, job->chapter_end );
+    hb_log( " + %dx%d -> %dx%d, crop %d/%d/%d/%d",
+            title->width, title->height, job->width, job->height,
+            job->crop[0], job->crop[1], job->crop[2], job->crop[3] );
+    hb_log( " + deinterlace %s", job->deinterlace ? "on" : "off" );
+    hb_log( " + grayscale %s", job->grayscale ? "on" : "off" );
+    if( job->vquality >= 0.0 && job->vquality <= 1.0 )
+    {
+        hb_log( " + %.3f fps, video quality %.2f", (float) job->vrate /
+                (float) job->vrate_base, job->vquality );
+    }
+    else
+    {
+        hb_log( " + %.3f fps, video bitrate %d kbps, pass %d",
+                (float) job->vrate / (float) job->vrate_base,
+                job->vbitrate, job->pass );
+    }
+
+    job->fifo_mpeg2  = hb_fifo_init( 2048 );
+    job->fifo_raw    = hb_fifo_init( 8 );
+    job->fifo_sync   = hb_fifo_init( 8 );
+    job->fifo_render = hb_fifo_init( 8 );
+    job->fifo_mpeg4  = hb_fifo_init( 8 );
+
+    /* Synchronization */
+    w           = hb_work_sync_init( job );
+    w->fifo_in  = NULL;
+    w->fifo_out = NULL;
+    hb_list_add( job->list_work, w );
+
+    /* Video decoder */
+    w           = hb_work_decmpeg2_init( job );
+    w->fifo_in  = job->fifo_mpeg2;
+    w->fifo_out = job->fifo_raw;
+    hb_list_add( job->list_work, w );
+
+    /* Video renderer */
+    w           = hb_work_render_init( job );
+    w->fifo_in  = job->fifo_sync;
+    w->fifo_out = job->fifo_render;
+    hb_list_add( job->list_work, w );
+
+    /* Video encoder */
+    switch( job->vcodec )
+    {
+        case HB_VCODEC_FFMPEG:
+            hb_log( " + encoder FFmpeg" );
+            w = hb_work_encavcodec_init( job );
+            break;
+        case HB_VCODEC_XVID:
+            hb_log( " + encoder XviD" );
+            w = hb_work_encxvid_init( job );
+            break;
+        case HB_VCODEC_X264:
+            hb_log( " + encoder x264" );
+            w = hb_work_encx264_init( job );
+            break;
+    }
+    w->fifo_in  = job->fifo_render;
+    w->fifo_out = job->fifo_mpeg4;
+    hb_list_add( job->list_work, w );
+
+    subtitle = hb_list_item( title->list_subtitle, 0 );
+    if( subtitle )
+    {
+        hb_log( " + subtitle %x, %s", subtitle->id, subtitle->lang );
+
+        subtitle->fifo_in  = hb_fifo_init( 8 );
+        subtitle->fifo_raw = hb_fifo_init( 8 );
+
+        w           = hb_work_decsub_init( job );
+        w->fifo_in  = subtitle->fifo_in;
+        w->fifo_out = subtitle->fifo_raw;
+        hb_list_add( job->list_work, w );
+    }
+
+    if( job->acodec & HB_ACODEC_AC3 )
+    {
+        hb_log( " + audio AC3 passthrough" );
+    }
+    else
+    {
+        hb_log( " + audio %d kbps, %d Hz", job->abitrate, job->arate );
+        hb_log( " + encoder %s", ( job->acodec & HB_ACODEC_FAAC ) ?
+                "faac" : ( ( job->acodec & HB_ACODEC_LAME ) ? "lame" :
+                "vorbis" ) );
+    }
+
+    for( i = 0; i < hb_list_count( title->list_audio ); i++ )
+    {
+        audio = hb_list_item( title->list_audio, i );
+        hb_log( "   + %x, %s", audio->id, audio->lang );
+
+        audio->fifo_in   = hb_fifo_init( 2048 );
+        audio->fifo_raw  = hb_fifo_init( 8 );
+        audio->fifo_sync = hb_fifo_init( 8 );
+        audio->fifo_out  = hb_fifo_init( 8 );
+
+        switch( audio->codec )
+        {
+            case HB_ACODEC_AC3:
+                w = hb_work_deca52_init( job, audio );
+                break;
+            case HB_ACODEC_MPGA:
+                w = hb_work_decavcodec_init( job, audio );
+                break;
+            case HB_ACODEC_LPCM:
+                w = hb_work_declpcm_init( job, audio );
+                break;
+        }
+        w->fifo_in  = audio->fifo_in;
+        w->fifo_out = audio->fifo_raw;
+        hb_list_add( job->list_work, w );
+
+        switch( job->acodec )
+        {
+            case HB_ACODEC_FAAC:
+                w = hb_work_encfaac_init( job, audio );
+                break;
+            case HB_ACODEC_LAME:
+                w = hb_work_enclame_init( job, audio );
+                break;
+            case HB_ACODEC_VORBIS:
+                w = hb_work_encvorbis_init( job, audio );
+                break;
+        }
+        if( job->acodec != HB_ACODEC_AC3 )
+        {
+            w->fifo_in  = audio->fifo_sync;
+            w->fifo_out = audio->fifo_out;
+            hb_list_add( job->list_work, w );
+        }
+    }
+
+    /* Init read & write threads */
+    job->reader = hb_reader_init( job );
+
+    hb_log( " + output: %s", job->file );
+    job->muxer = hb_muxer_init( job );
+
+    for( i = 0; i < hb_list_count( job->list_work ); i++ )
+    {
+        w       = hb_list_item( job->list_work, i );
+        w->lock = hb_lock_init();
+        w->used = 0;
+        w->time = 0;
+    }
+
+    job->done = 0;
+
+    /* Launch processing threads */
+    for( i = 0; i < cpu_count; i++ )
+    {
+        char thread_name[16];
+        if( cpu_count - 1 )
+        {
+            snprintf( thread_name, 16, "cpu killer %d", i + 1 );
+        }
+        else
+        {
+            snprintf( thread_name, 16, "cpu killer" );
+        }
+        threads[i] = hb_thread_init( thread_name, job_loop, job,
+                                     HB_LOW_PRIORITY );
+    }
+
+    while( !*job->die && !job->done )
+    {
+        hb_snooze( 500 );
+    }
+
+    for( i = 0; i < cpu_count; i++ )
+    {
+        hb_thread_close( &threads[i] );
+    }
+
+    /* Stop read & write threads */
+    hb_thread_close( &job->reader );
+    hb_thread_close( &job->muxer );
+
+    /* Stats */
+    time_total = 0;
+    for( i = 0; i < hb_list_count( job->list_work ); i++ )
+    {
+        w = hb_list_item( job->list_work, i );
+        time_total += w->time;
+    }
+    for( i = 0; i < hb_list_count( job->list_work ); i++ )
+    {
+        w = hb_list_item( job->list_work, i );
+        hb_log( "%s: %.2f %%", w->name,
+                100.0 * (float) w->time / (float) time_total );
+    }
+
+    /* Close work objects */
+    while( ( w = hb_list_item( job->list_work, 0 ) ) )
+    {
+        hb_list_rem( job->list_work, w );
+        hb_lock_close( &w->lock );
+        w->close( &w );
+    }
+
+    /* Close fifos */
+    hb_fifo_close( &job->fifo_mpeg2 );
+    hb_fifo_close( &job->fifo_raw );
+    hb_fifo_close( &job->fifo_sync );
+    hb_fifo_close( &job->fifo_render );
+    hb_fifo_close( &job->fifo_mpeg4 );
+    if( subtitle )
+    {
+        hb_fifo_close( &subtitle->fifo_in );
+        hb_fifo_close( &subtitle->fifo_raw );
+    }
+    for( i = 0; i < hb_list_count( title->list_audio ); i++ )
+    {
+        audio = hb_list_item( title->list_audio, i );
+        hb_fifo_close( &audio->fifo_in );
+        hb_fifo_close( &audio->fifo_raw );
+        hb_fifo_close( &audio->fifo_sync );
+        hb_fifo_close( &audio->fifo_out );
+    }
+}
+
+static int lock( hb_work_object_t * w )
+{
+    hb_lock( w->lock );
+    if( w->used )
+    {
+        hb_unlock( w->lock );
+        return 0;
+    }
+    w->used = 1;
+    hb_unlock( w->lock );
+    return 1;
+}
+
+static void unlock( hb_work_object_t * w )
+{
+    hb_lock( w->lock );
+    w->used = 0;
+    hb_unlock( w->lock );
+}
+
+static void job_loop( void * _job )
+{
+    hb_job_t         * job = _job;
+    hb_buffer_t      * buf_in, * buf_out;
+    hb_work_object_t * w;
+    int                work_count;
+    int                act;
+    int                i;
+    uint64_t           date;
+    int                done;
+
+    work_count = hb_list_count( job->list_work );
+    act        = 0;
+    done       = 0;
+
+    while( !*job->die && !job->done )
+    {
+        /* Handle synchronization, resampling, framerate change,
+           etc */
+        w = hb_list_item( job->list_work, 0 );
+        if( lock( w ) )
+        {
+            date = hb_get_date();
+            if( w->work( w, NULL, NULL ) == HB_WORK_DONE )
+            {
+                done = 1;
+            }
+            w->time += hb_get_date() - date;
+            unlock( w );
+        }
+
+        for( i = 1; !*job->die && !job->done && i < work_count; i++ )
+        {
+            w = hb_list_item( job->list_work, i );
+            if( !lock( w ) )
+                continue;
+
+            for( ;; )
+            {
+                hb_lock( job->pause );
+                hb_unlock( job->pause );
+
+                if( hb_fifo_is_full( w->fifo_out ) ||
+                    !( buf_in = hb_fifo_get( w->fifo_in ) ) )
+                {
+                    break;
+                }
+
+                date = hb_get_date();
+                w->work( w, &buf_in, &buf_out );
+                w->time += hb_get_date() - date;
+                if( buf_in )
+                {
+                    hb_buffer_close( &buf_in );
+                }
+                if( buf_out )
+                {
+                    act = 1;
+                    hb_fifo_push( w->fifo_out, buf_out );
+                }
+            }
+
+            unlock( w );
+        }
+
+        if( done &&
+            !hb_fifo_size( job->fifo_sync ) &&
+            !hb_fifo_size( job->fifo_render ) &&
+            hb_fifo_size( job->fifo_mpeg4 ) < 2 )
+        {
+            job->done = 1;
+            break;
+        }
+
+        /* If we did nothing, wait a bit before trying again */
+        if( !act )
+        {
+            hb_snooze( 50 );
+        }
+        act = 0;
+    }
+}
index 400246a..c32dacc 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: Controller.h,v 1.14 2004/02/13 13:45:51 titer Exp $
+/* $Id: Controller.h,v 1.35 2005/08/01 14:29:50 titer Exp $
 
    This file is part of the HandBrake source code.
    Homepage: <http://handbrake.m0k.org/>.
 
 #include <Cocoa/Cocoa.h>
 
-#include "HandBrake.h"
-#include "PictureGLView.h"
-#include "TargetSizeField.h"
+#include "hb.h"
+
+#include "ScanController.h"
+#include "PictureController.h"
+#include "QueueController.h"
 
 @interface HBController : NSObject
 
 {
     IBOutlet NSWindow            * fWindow;
 
-    /* Scan view */
-    IBOutlet NSView              * fScView;
-    IBOutlet NSTextField         * fScWelcomeField;
-    IBOutlet NSTextField         * fScSelectField;
-    IBOutlet NSMatrix            * fScMatrix;
-    IBOutlet NSButtonCell        * fScDetectedCell;
-    IBOutlet NSPopUpButton       * fScDetectedPopUp;
-    IBOutlet NSButtonCell        * fScFolderCell;
-    IBOutlet NSTextField         * fScFolderField;
-    IBOutlet NSButton            * fScBrowseButton;
-    IBOutlet NSTextField         * fScStatusField;
-    IBOutlet NSProgressIndicator * fScProgress;
-    IBOutlet NSButton            * fScOpenButton;
-
-    IBOutlet NSView              * fTempView;
-
-    /* Rip view */
-    IBOutlet NSView              * fRipView;
-
-    /* General box */
-    IBOutlet NSTextField         * fRipGeneralField;
-    IBOutlet NSTextField         * fRipTitleField;
-    IBOutlet NSPopUpButton       * fRipTitlePopUp;
-    IBOutlet NSTextField         * fRipFormatField;
-    IBOutlet NSPopUpButton       * fRipFormatPopUp;
-    IBOutlet NSTextField         * fRipFileField1;
-    IBOutlet NSTextField         * fRipFileField2;
-    IBOutlet NSButton            * fRipBrowseButton;
+    /* Scan panel */
+    IBOutlet ScanController      * fScanController;
+    IBOutlet NSPanel             * fScanPanel;
+
+    /* Picture panel */
+    IBOutlet PictureController   * fPictureController;
+    IBOutlet NSPanel             * fPicturePanel;
+
+    /* Queue panel */
+    IBOutlet QueueController     * fQueueController;
+    IBOutlet NSPanel             * fQueuePanel;
+    IBOutlet NSButton            * fQueueCheck;
+    IBOutlet NSButton            * fQueueAddButton;
+    IBOutlet NSButton            * fQueueShowButton;
+
+    /* Source box */
+    IBOutlet NSTextField         * fSrcDVD1Field;
+    IBOutlet NSTextField         * fSrcDVD2Field;
+    IBOutlet NSTextField         * fSrcTitleField;
+    IBOutlet NSPopUpButton       * fSrcTitlePopUp;
+    IBOutlet NSTextField         * fSrcChapterField;
+    IBOutlet NSPopUpButton       * fSrcChapterStartPopUp;
+    IBOutlet NSTextField         * fSrcChapterToField;
+    IBOutlet NSPopUpButton       * fSrcChapterEndPopUp;
+    IBOutlet NSTextField         * fSrcDuration1Field;
+    IBOutlet NSTextField         * fSrcDuration2Field;
+
+    /* Destination box */
+    IBOutlet NSTextField         * fDstFormatField;
+    IBOutlet NSPopUpButton       * fDstFormatPopUp;
+    IBOutlet NSTextField         * fDstCodecsField;
+    IBOutlet NSPopUpButton       * fDstCodecsPopUp;
+    IBOutlet NSTextField         * fDstFile1Field;
+    IBOutlet NSTextField         * fDstFile2Field;
+    IBOutlet NSButton            * fDstBrowseButton;
 
     /* Video box */
-    IBOutlet NSTextField         * fRipVideoField;
-    IBOutlet NSTextField         * fRipEncoderField;
-    IBOutlet NSPopUpButton       * fRipEncoderPopUp;
-    IBOutlet NSTextField         * fRipBitrateField;
-    IBOutlet NSMatrix            * fRipVideoMatrix;
-    IBOutlet NSButtonCell        * fRipCustomCell;
-    IBOutlet NSTextField         * fRipCustomField;
-    IBOutlet NSButtonCell        * fRipTargetCell;
-    IBOutlet HBTargetSizeField   * fRipTargetField;
-    IBOutlet NSButton            * fRipTwoPassCheck;
-    IBOutlet NSButton            * fRipCropButton;
+    IBOutlet NSTextField         * fVidRateField;
+    IBOutlet NSPopUpButton       * fVidRatePopUp;
+    IBOutlet NSTextField         * fVidEncoderField;
+    IBOutlet NSPopUpButton       * fVidEncoderPopUp;
+    IBOutlet NSTextField         * fVidQualityField;
+    IBOutlet NSMatrix            * fVidQualityMatrix;
+    IBOutlet NSButtonCell        * fVidTargetCell;
+    IBOutlet NSTextField         * fVidTargetSizeField;
+    IBOutlet NSButtonCell        * fVidBitrateCell;
+    IBOutlet NSTextField         * fVidBitrateField;
+    IBOutlet NSButtonCell        * fVidConstantCell;
+    IBOutlet NSSlider            * fVidQualitySlider;
+    IBOutlet NSButton            * fVidGrayscaleCheck;
+    IBOutlet NSButton            * fVidTwoPassCheck;
+
+    /* Subtitles box */
+    IBOutlet NSTextField         * fSubField;
+    IBOutlet NSPopUpButton       * fSubPopUp;
 
     /* Audio box */
-    IBOutlet NSTextField         * fRipAudioField;
-    IBOutlet NSTextField         * fRipLang1Field;
-    IBOutlet NSPopUpButton       * fRipLang1PopUp;
-    IBOutlet NSTextField         * fRipLang2Field;
-    IBOutlet NSPopUpButton       * fRipLang2PopUp;
-    IBOutlet NSTextField         * fRipAudBitField;
-    IBOutlet NSPopUpButton       * fRipAudBitPopUp;
+    IBOutlet NSTextField         * fAudLang1Field;
+    IBOutlet NSPopUpButton       * fAudLang1PopUp;
+    IBOutlet NSTextField         * fAudLang2Field;
+    IBOutlet NSPopUpButton       * fAudLang2PopUp;
+    IBOutlet NSTextField         * fAudRateField;
+    IBOutlet NSPopUpButton       * fAudRatePopUp;
+    IBOutlet NSTextField         * fAudBitrateField;
+    IBOutlet NSPopUpButton       * fAudBitratePopUp;
 
     /* Bottom */
-    IBOutlet NSTextField         * fRipStatusField;
-    IBOutlet NSTextField         * fRipInfoField;
-    IBOutlet NSProgressIndicator * fRipProgress;
-    IBOutlet NSButton            * fRipPauseButton;
-    IBOutlet NSButton            * fRipRipButton;
+    IBOutlet NSButton            * fPictureButton;
+    IBOutlet NSTextField         * fStatusField;
+    IBOutlet NSProgressIndicator * fRipIndicator;
+    IBOutlet NSButton            * fShowQuButton;
+    IBOutlet NSButton            * fAddToQuButton;
+    IBOutlet NSButton            * fPauseButton;
+    IBOutlet NSButton            * fRipButton;
+
+    hb_handle_t                  * fHandle;
+}
 
-    /* "Done" alert panel */
-    IBOutlet NSPanel             * fDonePanel;
+- (void)     TranslateStrings;
 
-    /* Crop & scale panel */
-    IBOutlet NSPanel             * fPicturePanel;
-    IBOutlet HBPictureGLView     * fPictureGLView;
-    IBOutlet NSTextField         * fWidthField1;
-    IBOutlet NSTextField         * fWidthField2;
-    IBOutlet NSStepper           * fWidthStepper;
-    IBOutlet NSButton            * fDeinterlaceCheck;
-    IBOutlet NSTextField         * fTopField1;
-    IBOutlet NSTextField         * fTopField2;
-    IBOutlet NSStepper           * fTopStepper;
-    IBOutlet NSTextField         * fBottomField1;
-    IBOutlet NSTextField         * fBottomField2;
-    IBOutlet NSStepper           * fBottomStepper;
-    IBOutlet NSTextField         * fLeftField1;
-    IBOutlet NSTextField         * fLeftField2;
-    IBOutlet NSStepper           * fLeftStepper;
-    IBOutlet NSTextField         * fRightField1;
-    IBOutlet NSTextField         * fRightField2;
-    IBOutlet NSStepper           * fRightStepper;
-    IBOutlet NSButton            * fPreviousButton;
-    IBOutlet NSButton            * fNextButton;
-    IBOutlet NSButton            * fAutocropButton;
-    IBOutlet NSButton            * fOpenGLCheck;
-    IBOutlet NSTextField         * fInfoField;
-    IBOutlet NSButton            * fCloseButton;
-    int                            fPicture;
-
-    HBHandle                     * fHandle;
-    int                            fTitle;
-    int                            fTitleCount;
-    HBList                       * fTitleList;
-    float                          fPosition;
-    int                            fPass;
-    int                            fPassCount;
-    float                          fCurFrameRate;
-    float                          fAvgFrameRate;
-    int                            fRemainingTime;
-    int                            fResult;
-}
+- (void)     UpdateUI: (NSTimer *) timer;
+- (void)     EnableUI: (bool) enable;
 
-- (IBAction) ScanMatrixChanged: (id) sender;
-- (IBAction) BrowseDVD: (id) sender;
-- (void)     BrowseDVDDone: (NSOpenPanel *) sheet
-    returnCode: (int) returnCode contextInfo: (void *) contextInfo;
-- (IBAction) Scan: (id) sender;
+- (IBAction) ShowScanPanel: (id) sender;
 
 - (IBAction) TitlePopUpChanged: (id) sender;
+- (IBAction) ChapterPopUpChanged: (id) sender;
+
 - (IBAction) FormatPopUpChanged: (id) sender;
-- (IBAction) VideoMatrixChanged: (id) sender;
-- (IBAction) AudioPopUpChanged: (id) sender;
+- (IBAction) CodecsPopUpChanged: (id) sender;
 - (IBAction) BrowseFile: (id) sender;
 - (void)     BrowseFileDone: (NSSavePanel *) sheet
     returnCode: (int) returnCode contextInfo: (void *) contextInfo;
+
+- (IBAction) VideoMatrixChanged: (id) sender;
+- (IBAction) QualitySliderChanged: (id) sender;
+
 - (IBAction) ShowPicturePanel: (id) sender;
-- (IBAction) ClosePanel: (id) sender;
+
+- (IBAction) EnableQueue: (id) sender;
+- (IBAction) AddToQueue: (id) sender;
+- (IBAction) ShowQueuePanel: (id) sender;
+
 - (IBAction) Rip: (id) sender;
 - (void)     OverwriteAlertDone: (NSWindow *) sheet
     returnCode: (int) returnCode contextInfo: (void *) contextInfo;
+- (void)     UpdateAlertDone: (NSWindow *) sheet
+    returnCode: (int) returnCode contextInfo: (void *) contextInfo;
 - (void)     _Rip;
 - (IBAction) Cancel: (id) sender;
 - (void)     _Cancel: (NSWindow *) sheet returnCode: (int) returnCode
     contextInfo: (void *) contextInfo;
 - (IBAction) Pause: (id) sender;
-- (IBAction) Resume: (id) sender;
-
-- (IBAction) PreviousPicture: (id) sender;
-- (IBAction) NextPicture: (id) sender;
-- (IBAction) UpdatePicture: (id) sender;
-- (IBAction) AutoCrop: (id) sender;
 
-- (void)     DetectDrives: (NSNotification *) notification;
+- (IBAction) CalculateBitrate: (id) sender;
+- (void) controlTextDidBeginEditing: (NSNotification *) notification;
+- (void) controlTextDidEndEditing: (NSNotification *) notification;
+- (void) controlTextDidChange: (NSNotification *) notification;
 
-/* libhb callbacks */
-- (void) Scanning: (id) sender;
-- (void) ScanDone: (id) sender;
-- (void) Encoding: (id) sender;
-- (void) RipDone:  (id) sender;
+- (IBAction) OpenHomepage: (id) sender;
+- (IBAction) OpenForums:   (id) sender;
 
 @end
 
index eb53a9d..a4ba98a 100644 (file)
-/* $Id: Controller.mm,v 1.31 2004/04/21 21:21:17 titer Exp $
+/* $Id: Controller.mm,v 1.78 2005/11/04 13:09:41 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 <paths.h>
-#include <IOKit/IOKitLib.h>
-#include <IOKit/IOBSD.h>
-#include <IOKit/storage/IOMedia.h>
-#include <IOKit/storage/IODVDMedia.h>
-
 #include "Controller.h"
 
-#define _(a) NSLocalizedString(a,nil)
-
-static void _Scanning( void * data, int title, int titleCount );
-static void _ScanDone( void * data, HBList * titleList );
-static void _Encoding( void * data, float position, int pass,
-                      int passCount, float curFrameRate,
-                      float avgFrameRate, int remainingTime );
-static void _RipDone( void * data, int result );
+#define _(a) NSLocalizedString(a,NULL)
+
+static int FormatSettings[3][4] =
+  { { HB_MUX_MP4 | HB_VCODEC_FFMPEG | HB_ACODEC_FAAC,
+      HB_MUX_MP4 | HB_VCODEC_X264   | HB_ACODEC_FAAC,
+      0,
+      0 },
+    { HB_MUX_AVI | HB_VCODEC_FFMPEG | HB_ACODEC_LAME,
+      HB_MUX_AVI | HB_VCODEC_FFMPEG | HB_ACODEC_AC3,
+      HB_MUX_AVI | HB_VCODEC_X264   | HB_ACODEC_LAME,
+      HB_MUX_AVI | HB_VCODEC_X264   | HB_ACODEC_AC3 },
+    { HB_MUX_OGM | HB_VCODEC_FFMPEG | HB_ACODEC_VORBIS,
+      HB_MUX_OGM | HB_VCODEC_FFMPEG | HB_ACODEC_LAME,
+      0,
+      0 } };
 
 /*******************************
  * HBController implementation *
  *******************************/
 @implementation HBController
 
-- (void) applicationDidFinishLaunching: (NSNotification *) notification
+- init
 {
-    /* Init libhb */
-    HBCallbacks callbacks;
-    callbacks.data     = self;
-    callbacks.scanning = _Scanning;
-    callbacks.scanDone = _ScanDone;
-    callbacks.encoding = _Encoding;
-    callbacks.ripDone  = _RipDone;
+    self    = [super init];
+    fHandle = NULL;
+    return self;
+}
 
-    fHandle = HBInit( 1, 0 );
-    HBSetCallbacks( fHandle, callbacks );
+- (void) applicationDidFinishLaunching: (NSNotification *) notification
+{
+    int    build;
+    char * version;
 
-    [fPictureGLView SetHandle: fHandle];
+    /* Init libhb */
+    fHandle = hb_init( HB_DEBUG_ALL, [[NSUserDefaults
+        standardUserDefaults] boolForKey:@"CheckForUpdates"] );
+
+    /* Init others controllers */
+    [fScanController    SetHandle: fHandle];
+    [fPictureController SetHandle: fHandle];
+    [fQueueController   SetHandle: fHandle];
+
+    /* Call UpdateUI every 2/10 sec */
+    [[NSRunLoop currentRunLoop] addTimer: [NSTimer
+        scheduledTimerWithTimeInterval: 0.2 target: self
+        selector: @selector( UpdateUI: ) userInfo: NULL repeats: FALSE]
+        forMode: NSModalPanelRunLoopMode];
+
+    if( ( build = hb_check_update( fHandle, &version ) ) > -1 )
+    {
+        /* Update available - tell the user */
+        NSBeginInformationalAlertSheet( _( @"Update is available" ),
+            _( @"Go get it!" ), _( @"Discard" ), NULL, fWindow, self,
+            @selector( UpdateAlertDone:returnCode:contextInfo: ),
+            NULL, NULL, [NSString stringWithFormat:
+            _( @"HandBrake %s (build %d) is now available for download." ),
+            version, build] );
+        return;
+    }
 
-    /* Detect drives mounted after the app is started */
-    [[[NSWorkspace sharedWorkspace] notificationCenter]
-        addObserver: self selector: @selector( DetectDrives: )
-        name: NSWorkspaceDidMountNotification object: nil];
+    /* Show scan panel ASAP */
+    [self performSelectorOnMainThread: @selector(ShowScanPanel:)
+        withObject: NULL waitUntilDone: NO];
 }
 
 - (NSApplicationTerminateReply) applicationShouldTerminate:
     (NSApplication *) app
 {
-    if( [[fRipRipButton title] compare: _( @"Cancel" ) ]
-            == NSOrderedSame )
+    if( [[fRipButton title] isEqualToString: _( @"Cancel" )] )
     {
-        [self Cancel: self];
+        [self Cancel: NULL];
         return NSTerminateCancel;
     }
     
     /* Clean up */
-    HBClose( &fHandle );
-
+    hb_close( &fHandle );
     return NSTerminateNow;
 }
 
 - (void) awakeFromNib
 {
-    /* Strings for the Scan view */
-    [fScWelcomeField  setStringValue: _( @"Welcome to HandBrake" )];
-    [fScSelectField   setStringValue: _( @"Select a DVD:" )];
-    [fScDetectedCell  setTitle: _( @"Detected volume" )];
-    [fScDetectedPopUp removeAllItems];
-    [fScFolderCell    setTitle: _( @"DVD Folder" )];
-    [fScBrowseButton  setTitle: _( @"Browse" )];
-    [fScStatusField   setStringValue: @""];
-    [fScOpenButton    setTitle: _( @"Open" )];
-
-    /* Strings for the Rip view */
-    /* General box */
-    [fRipGeneralField setStringValue: _( @"General" )];
-    [fRipTitleField   setStringValue: _( @"DVD title" )];
-    [fRipTitlePopUp   removeAllItems];
-    [fRipFormatField  setStringValue: _( @"Output format" )];
-    [fRipFormatPopUp  removeAllItems];
-    [fRipFormatPopUp  addItemWithTitle:
-        _( @"MP4 file / MPEG-4 video / AAC audio" )];
-    [fRipFormatPopUp  addItemWithTitle:
-        _( @"AVI file / MPEG-4 video / MP3 audio" )];
-    [fRipFormatPopUp  addItemWithTitle:
-        _( @"AVI file / H264 video / MP3 audio" )];
-    [fRipFormatPopUp  addItemWithTitle:
-        _( @"OGM file / MPEG-4 video / Vorbis audio" )];
-    [fRipFileField1   setStringValue: _( @"File" )];
-    [fRipFileField2   setStringValue: [NSString stringWithFormat:
+    [fWindow center];
+
+    [self TranslateStrings];
+
+    /* Destination box */
+    [fDstFormatPopUp removeAllItems];
+    [fDstFormatPopUp addItemWithTitle: _( @"MP4 file" )];
+    [fDstFormatPopUp addItemWithTitle: _( @"AVI file" )];
+    [fDstFormatPopUp addItemWithTitle: _( @"OGM file" )];
+    [fDstFormatPopUp selectItemAtIndex: 0];
+
+    [self FormatPopUpChanged: NULL];
+
+    [fDstFile2Field setStringValue: [NSString stringWithFormat:
         @"%@/Desktop/Movie.mp4", NSHomeDirectory()]];
-    [fRipBrowseButton setTitle: _( @"Browse" )];
-
-    /* Video box */
-    [fRipVideoField   setStringValue: _( @"Video" )];
-    [fRipEncoderField setStringValue: _( @"MPEG-4 encoder" )];
-    [fRipEncoderPopUp removeAllItems];
-    [fRipEncoderPopUp addItemWithTitle: @"FFmpeg"];
-    [fRipEncoderPopUp addItemWithTitle: @"XviD"];
-    [fRipBitrateField setStringValue: _( @"Bitrate" )];
-    [fRipCustomCell   setTitle: _( @"Custom (kbps)" )];
-    [fRipCustomField  setIntValue: 1024];
-    [fRipTargetCell   setTitle: _( @"Target size (MB)" )];
-    [fRipTargetField  setIntValue: 700];
-    [fRipTwoPassCheck setTitle: _( @"2-pass encoding" )];
-    [fRipCropButton   setTitle: _( @"Crop & Scale..." )];
-
-    /* Audio box */
-    [fRipAudioField  setStringValue: _( @"Audio" )];
-    [fRipLang1Field  setStringValue: _( @"Language 1" )];
-    [fRipLang1PopUp  removeAllItems];
-    [fRipLang2Field  setStringValue: _( @"Language 2 (optional)" )];
-    [fRipLang2PopUp  removeAllItems];
-    [fRipAudBitField setStringValue: _( @"Bitrate (kbps)" )];
-    [fRipAudBitPopUp removeAllItems];
-    [fRipAudBitPopUp addItemWithTitle: @"32"];
-    [fRipAudBitPopUp addItemWithTitle: @"40"];
-    [fRipAudBitPopUp addItemWithTitle: @"48"];
-    [fRipAudBitPopUp addItemWithTitle: @"56"];
-    [fRipAudBitPopUp addItemWithTitle: @"64"];
-    [fRipAudBitPopUp addItemWithTitle: @"80"];
-    [fRipAudBitPopUp addItemWithTitle: @"96"];
-    [fRipAudBitPopUp addItemWithTitle: @"112"];
-    [fRipAudBitPopUp addItemWithTitle: @"128"];
-    [fRipAudBitPopUp addItemWithTitle: @"160"];
-    [fRipAudBitPopUp addItemWithTitle: @"192"];
-    [fRipAudBitPopUp addItemWithTitle: @"224"];
-    [fRipAudBitPopUp addItemWithTitle: @"256"];
-    [fRipAudBitPopUp addItemWithTitle: @"320"];
-    [fRipAudBitPopUp selectItemWithTitle: @"128"];
+
+    /* Video encoder */
+    [fVidEncoderPopUp removeAllItems];
+    [fVidEncoderPopUp addItemWithTitle: @"FFmpeg"];
+    [fVidEncoderPopUp addItemWithTitle: @"XviD"];
+
+    /* Video quality */
+    [fVidTargetSizeField setIntValue: 700];
+    [fVidBitrateField    setIntValue: 1000];
+    [fVidQualityMatrix   selectCell: fVidBitrateCell];
+    [self VideoMatrixChanged: NULL];
+
+    /* Video framerate */
+    [fVidRatePopUp removeAllItems];
+    [fVidRatePopUp addItemWithTitle: _( @"Same as source" )];
+    for( int i = 0; i < hb_video_rates_count; i++ )
+    {
+        [fVidRatePopUp addItemWithTitle:
+            [NSString stringWithCString: hb_video_rates[i].string]];
+    }
+    [fVidRatePopUp selectItemAtIndex: 0];
+
+    /* Audio bitrate */
+    [fAudBitratePopUp removeAllItems];
+    for( int i = 0; i < hb_audio_bitrates_count; i++ )
+    {
+        [fAudBitratePopUp addItemWithTitle:
+            [NSString stringWithCString: hb_audio_bitrates[i].string]];
+    }
+    [fAudBitratePopUp selectItemAtIndex: hb_audio_bitrates_default];
+
+    /* Audio samplerate */
+    [fAudRatePopUp removeAllItems];
+    for( int i = 0; i < hb_audio_rates_count; i++ )
+    {
+        [fAudRatePopUp addItemWithTitle:
+            [NSString stringWithCString: hb_audio_rates[i].string]];
+    }
+    [fAudRatePopUp selectItemAtIndex: hb_audio_rates_default];
 
     /* Bottom */
-    [fRipStatusField setStringValue: @""];
-    [fRipInfoField   setStringValue: @""];
-    [fRipPauseButton setTitle: _( @"Pause" )];
-    [fRipRipButton   setTitle: _( @"Rip" )];
-
-    /* Strings for the crop panel */
-    [fWidthField1      setStringValue: _( @"Picture width" )];
-    [fDeinterlaceCheck setTitle: _( @"Deinterlace picture" )];
-    [fTopField1        setStringValue: _( @"Top cropping" )];
-    [fBottomField1     setStringValue: _( @"Bottom cropping" )];
-    [fLeftField1       setStringValue: _( @"Left cropping" )];
-    [fRightField1      setStringValue: _( @"Right cropping" )];
-    [fPreviousButton   setTitle: _( @"Previous" )];
-    [fNextButton       setTitle: _( @"Next" )];
-    [fAutocropButton   setTitle: _( @"Autocrop" )];
-    [fOpenGLCheck      setTitle: _( @"Useless OpenGL effects" )];
-    [fInfoField        setStringValue: @""];
-    [fCloseButton      setTitle: _( @"Close" )];
-
-    [self VideoMatrixChanged: self];
-
-    /* Show the scan view */
-    [fWindow setContentSize: [fScView frame].size];
-    [fWindow setContentView: fScView];
-    [fWindow center];
+    [fStatusField setStringValue: @""];
 
-    /* Detect DVD drives */
-    [self DetectDrives: nil];
-    [self ScanMatrixChanged: self];
+    [self EnableUI: NO];
+    [fPauseButton setEnabled: NO];
+    [fRipButton setEnabled: NO];
 }
 
-- (BOOL) windowShouldClose: (id) sender
+- (void) TranslateStrings
 {
-    if( [[fRipRipButton title] compare: _( @"Cancel" ) ]
-            == NSOrderedSame )
+    [fSrcDVD1Field      setStringValue: _( @"DVD:" )];
+    [fSrcTitleField     setStringValue: _( @"Title:" )];
+    [fSrcChapterField   setStringValue: _( @"Chapters:" )];
+    [fSrcChapterToField setStringValue: _( @"to" )];
+    [fSrcDuration1Field setStringValue: _( @"Duration:" )];
+
+    [fDstFormatField    setStringValue: _( @"File format:" )];
+    [fDstCodecsField    setStringValue: _( @"Codecs:" )];
+    [fDstFile1Field     setStringValue: _( @"File:" )];
+    [fDstBrowseButton   setTitle:       _( @"Browse" )];
+
+    [fVidRateField      setStringValue: _( @"Framerate (fps):" )];
+    [fVidEncoderField   setStringValue: _( @"Encoder:" )];
+    [fVidQualityField   setStringValue: _( @"Quality:" )];
+}
+
+/***********************************************************************
+ * UpdateDockIcon
+ ***********************************************************************
+ * Shows a progression bar on the dock icon, filled according to
+ * 'progress' (0.0 <= progress <= 1.0).
+ * Called with progress < 0.0 or progress > 1.0, restores the original
+ * icon.
+ **********************************************************************/
+- (void) UpdateDockIcon: (float) progress
+{
+    NSImage * icon;
+    NSData * tiff;
+    NSBitmapImageRep * bmp;
+    uint32_t * pen;
+    int row_start, row_end;
+    int i, j;
+
+    /* Get application original icon */
+    icon = [NSImage imageNamed: @"NSApplicationIcon"];
+
+    if( progress < 0.0 || progress > 1.0 )
     {
-        [self Cancel: self];
-        return NO;
+        [NSApp setApplicationIconImage: icon];
+        return;
     }
 
-    /* Stop the application when the user closes the window */
-    [NSApp terminate: self];
-    return YES;
+    /* Get it in a raw bitmap form */
+    tiff = [icon TIFFRepresentationUsingCompression:
+            NSTIFFCompressionNone factor: 1.0];
+    bmp = [NSBitmapImageRep imageRepWithData: tiff];
+    
+    /* Draw the progression bar */
+    /* It's pretty simple (ugly?) now, but I'm no designer */
+
+    row_start = 3 * (int) [bmp size].height / 4;
+    row_end   = 7 * (int) [bmp size].height / 8;
+
+    for( i = row_start; i < row_start + 2; i++ )
+    {
+        pen = (uint32_t *) ( [bmp bitmapData] + i * [bmp bytesPerRow] );
+        for( j = 0; j < (int) [bmp size].width; j++ )
+        {
+            pen[j] = 0x000000FF; /* Black */
+        }
+    }
+    for( i = row_start + 2; i < row_end - 2; i++ )
+    {
+        pen = (uint32_t *) ( [bmp bitmapData] + i * [bmp bytesPerRow] );
+        pen[0] = 0x000000FF;
+        pen[1] = 0x000000FF;
+        for( j = 2; j < (int) [bmp size].width - 2; j++ )
+        {
+            if( j < 2 + (int) ( ( [bmp size].width - 4.0 ) * progress ) )
+            {
+                pen[j] = 0xFF0000FF; /* Red */
+            }
+            else
+            {
+                pen[j] = 0xFFFFFFFF; /* White */
+            }
+        }
+        pen[j]   = 0x000000FF;
+        pen[j+1] = 0x000000FF;
+    }
+    for( i = row_end - 2; i < row_end; i++ )
+    {
+        pen = (uint32_t *) ( [bmp bitmapData] + i * [bmp bytesPerRow] );
+        for( j = 0; j < (int) [bmp size].width; j++ )
+        {
+            pen[j] = 0x000000FF; /* Black */
+        }
+    }
+
+    /* Now update the dock icon */
+    tiff = [bmp TIFFRepresentationUsingCompression:
+            NSTIFFCompressionNone factor: 1.0];
+    icon = [[NSImage alloc] initWithData: tiff];
+    [NSApp setApplicationIconImage: icon];
+    [icon release];
 }
 
-- (IBAction) BrowseDVD: (id) sender
+- (void) UpdateUI: (NSTimer *) timer
 {
-    /* Open a panel to let the user choose and update the text field */
-    NSOpenPanel * panel = [NSOpenPanel openPanel];
+    hb_state_t s;
+    hb_get_state( fHandle, &s );
+
+    switch( s.state )
+    {
+        case HB_STATE_IDLE:
+            /* If the scan panel is currently showing, recheck for DVD
+               drives. The clean way would be to use
+               NSWorkspaceDidMountNotification, but for some reason the
+               notifications don't work when having the sheet attached */
+            if( [fWindow attachedSheet] == fScanPanel )
+            {
+                [fScanController DetectDrives: NULL];
+            }
+            break;
 
-    [panel setAllowsMultipleSelection: NO];
-    [panel setCanChooseFiles: NO];
-    [panel setCanChooseDirectories: YES ];
+        case HB_STATE_SCANNING:
+            [fScanController UpdateUI: &s];
+            break;
 
-    [panel beginSheetForDirectory: nil file: nil types: nil
-        modalForWindow: fWindow modalDelegate: self
-        didEndSelector: @selector( BrowseDVDDone:returnCode:contextInfo: )
-        contextInfo: nil];
+#define p s.param.scandone
+        case HB_STATE_SCANDONE:
+        {
+            hb_list_t  * list;
+            hb_title_t * title;
+
+            [fScanController UpdateUI: &s];
+
+            list = hb_get_titles( fHandle );
+
+            if( !hb_list_count( list ) )
+            {
+                break;
+            }
+
+            [fSrcTitlePopUp removeAllItems];
+            for( int i = 0; i < hb_list_count( list ); i++ )
+            {
+                title = (hb_title_t *) hb_list_item( list, i );
+                [fSrcDVD2Field setStringValue: [NSString
+                    stringWithUTF8String: title->dvd]];
+                [fSrcTitlePopUp addItemWithTitle: [NSString
+                    stringWithFormat: @"%d - %02dh%02dm%02ds",
+                    title->index, title->hours, title->minutes,
+                    title->seconds]];
+            }
+
+            [self TitlePopUpChanged: NULL];
+            [self EnableUI: YES];
+            [fPauseButton setEnabled: NO];
+            [fRipButton   setEnabled: YES];
+            break;
+        }
+#undef p
+
+#define p s.param.working
+        case HB_STATE_WORKING:
+        {
+            float progress_total;
+            NSMutableString * string;
+
+            /* Update text field */
+            string = [NSMutableString stringWithFormat:
+                _( @"Encoding: task %d of %d, %.2f %%" ),
+                p.job_cur, p.job_count, 100.0 * p.progress];
+            if( p.seconds > -1 )
+            {
+                [string appendFormat:
+                    _( @" (%.2f fps, avg %.2f fps, ETA %02dh%02dm%02ds)" ),
+                    p.rate_cur, p.rate_avg, p.hours, p.minutes, p.seconds];
+            }
+            [fStatusField setStringValue: string];
+
+            /* Update slider */
+            progress_total = ( p.progress + p.job_cur - 1 ) / p.job_count;
+            [fRipIndicator setDoubleValue: 100.0 * progress_total];
+
+            /* Update dock icon */
+            [self UpdateDockIcon: progress_total];
+
+            [fPauseButton setEnabled: YES];
+            [fPauseButton setTitle: _( @"Pause" )];
+            [fRipButton setEnabled: YES];
+            [fRipButton setTitle: _( @"Cancel" )];
+            break;
+        }
+#undef p
+
+        case HB_STATE_PAUSED:
+            [fStatusField setStringValue: _( @"Paused" )];
+            [fPauseButton setEnabled: YES];
+            [fPauseButton setTitle: _( @"Resume" )];
+            [fRipButton setEnabled: YES];
+            [fRipButton setTitle: _( @"Cancel" )];
+            break;
+
+        case HB_STATE_WORKDONE:
+        {
+            [self EnableUI: YES];
+            [fStatusField setStringValue: _( @"Done." )];
+            [fRipIndicator setDoubleValue: 0.0];
+            [fRipButton setTitle: _( @"Rip" )];
+
+            /* Restore dock icon */
+            [self UpdateDockIcon: -1.0];
+
+            [fPauseButton setEnabled: NO];
+            [fPauseButton setTitle: _( @"Pause" )];
+            [fRipButton setEnabled: YES];
+            [fRipButton setTitle: _( @"Rip" )];
+
+            /* FIXME */
+            hb_job_t * job;
+            while( ( job = hb_job( fHandle, 0 ) ) )
+            {
+                hb_rem( fHandle, job );
+            }
+            break;
+        }
+    }
+
+    /* FIXME: we should only do that when necessary */
+    if( [fQueueCheck state] == NSOnState )
+    {
+        int count = hb_count( fHandle );
+        if( count )
+        {
+            [fQueueCheck setTitle: [NSString stringWithFormat:
+                @"Enable queue (%d task%s in queue)",
+                count, ( count > 1 ) ? "s" : ""]];
+        }
+        else
+        {
+            [fQueueCheck setTitle: @"Enable queue (no task in queue)"];
+        }
+    }
+
+    [[NSRunLoop currentRunLoop] addTimer: [NSTimer
+        scheduledTimerWithTimeInterval: 0.2 target: self
+        selector: @selector( UpdateUI: ) userInfo: NULL repeats: FALSE]
+        forMode: NSModalPanelRunLoopMode];
 }
 
-- (void) BrowseDVDDone: (NSOpenPanel *) sheet
-    returnCode: (int) returnCode contextInfo: (void *) contextInfo
+- (void) EnableUI: (bool) b
 {
-    if( returnCode == NSOKButton )
+    NSControl * controls[] =
+      { fSrcDVD1Field, fSrcDVD2Field, fSrcTitleField, fSrcTitlePopUp,
+        fSrcChapterField, fSrcChapterStartPopUp, fSrcChapterToField,
+        fSrcChapterEndPopUp, fSrcDuration1Field, fSrcDuration2Field,
+        fDstFormatField, fDstFormatPopUp, fDstCodecsField,
+        fDstCodecsPopUp, fDstFile1Field, fDstFile2Field,
+        fDstBrowseButton, fVidRateField, fVidRatePopUp,
+        fVidEncoderField, fVidEncoderPopUp, fVidQualityField,
+        fVidQualityMatrix, fVidGrayscaleCheck, fSubField, fSubPopUp,
+        fAudLang1Field, fAudLang1PopUp, fAudLang2Field, fAudLang2PopUp,
+        fAudRateField, fAudRatePopUp, fAudBitrateField,
+        fAudBitratePopUp, fPictureButton };
+
+    for( unsigned i = 0;
+         i < sizeof( controls ) / sizeof( NSControl * ); i++ )
     {
-        [fScFolderField setStringValue:
-            [[sheet filenames] objectAtIndex: 0]];
+        if( [[controls[i] className] isEqualToString: @"NSTextField"] )
+        {
+            NSTextField * tf = (NSTextField *) controls[i];
+            if( ![tf isBezeled] )
+            {
+                [tf setTextColor: b ? [NSColor controlTextColor] :
+                    [NSColor disabledControlTextColor]];
+                continue;
+            }
+        }
+        [controls[i] setEnabled: b];
     }
+
+    [self VideoMatrixChanged: NULL];
+}
+
+- (IBAction) ShowScanPanel: (id) sender
+{
+    [NSApp beginSheet: fScanPanel modalForWindow: fWindow
+        modalDelegate: NULL didEndSelector: NULL contextInfo: NULL];
+    [NSApp runModalForWindow: fScanPanel];
+    [NSApp endSheet: fScanPanel];
+    [fScanPanel orderOut: self];
+}
+
+- (BOOL) windowShouldClose: (id) sender
+{
+    /* Stop the application when the user closes the window */
+    [NSApp terminate: self];
+    return YES;
 }
 
 - (IBAction) VideoMatrixChanged: (id) sender;
 {
-    if( ![fRipVideoMatrix isEnabled] )
-    {
-        [fRipCustomField setEnabled: NO];
-        [fRipTargetField setEnabled: NO];
-        return;
-    }
-    
-    if( ![fRipVideoMatrix selectedRow] )
+    bool target, bitrate, quality;
+
+    target = bitrate = quality = false;
+    if( [fVidQualityMatrix isEnabled] )
     {
-        [fRipCustomField setEnabled: YES];
-        [fRipTargetField setEnabled: NO];
+        switch( [fVidQualityMatrix selectedRow] )
+        {
+            case 0:
+                target = true;
+                break;
+            case 1:
+                bitrate = true;
+                break;
+            case 2:
+                quality = true;
+                break;
+        }
     }
-    else
+    [fVidTargetSizeField  setEnabled: target];
+    [fVidBitrateField     setEnabled: bitrate];
+    [fVidQualitySlider    setEnabled: quality];
+    [fVidTwoPassCheck     setEnabled: !quality &&
+        [fVidQualityMatrix isEnabled]];
+    if( quality )
     {
-        [fRipCustomField setEnabled: NO];
-        [fRipTargetField setEnabled: YES];
-        [fRipTargetField UpdateBitrate];
+        [fVidTwoPassCheck setState: NSOffState];
     }
+
+    [self QualitySliderChanged: sender];
+    [self CalculateBitrate:     sender];
+}
+
+- (IBAction) QualitySliderChanged: (id) sender
+{
+    [fVidConstantCell setTitle: [NSString stringWithFormat:
+        _( @"Constant quality: %.0f %%" ), 100.0 *
+        [fVidQualitySlider floatValue]]];
 }
 
 - (IBAction) BrowseFile: (id) sender
@@ -231,10 +490,10 @@ static void _RipDone( void * data, int result );
     /* Open a panel to let the user choose and update the text field */
     NSSavePanel * panel = [NSSavePanel savePanel];
 
-    [panel beginSheetForDirectory: nil file: nil
+    [panel beginSheetForDirectory: NULL file: NULL
         modalForWindow: fWindow modalDelegate: self
         didEndSelector: @selector( BrowseFileDone:returnCode:contextInfo: )
-        contextInfo: nil];
+        contextInfo: NULL];
 }
 
 - (void) BrowseFileDone: (NSSavePanel *) sheet
@@ -242,146 +501,176 @@ static void _RipDone( void * data, int result );
 {
     if( returnCode == NSOKButton )
     {
-        [fRipFileField2 setStringValue: [sheet filename]];
-        [self FormatPopUpChanged: self];
-    }
-}
-
-- (IBAction) Scan: (id) sender
-{
-    [fScMatrix       setEnabled: NO];
-    [fScDetectedPopUp         setEnabled: NO];
-    [fScFolderField   setEnabled: NO];
-    [fScBrowseButton setEnabled: NO];
-    [fScProgress     setIndeterminate: YES];
-    [fScProgress     startAnimation: self];
-    [fScOpenButton       setEnabled: NO];
-    [fScStatusField setStringValue: _( @"Opening device..." )];
-
-    /* Ask libhb to start scanning the specified volume */
-    if( ![fScMatrix selectedRow] )
-    {
-        /* DVD drive */
-        HBScanDVD( fHandle,
-                   [[fScDetectedPopUp titleOfSelectedItem] cString], 0 );
-    }
-    else
-    {
-        /* DVD folder */
-        HBScanDVD( fHandle,
-                   [[fScFolderField stringValue] cString], 0 );
+        [fDstFile2Field setStringValue: [sheet filename]];
+        [self FormatPopUpChanged: NULL];
     }
 }
 
 - (IBAction) ShowPicturePanel: (id) sender
 {
-    HBTitle * title = (HBTitle*)
-        HBListItemAt( fTitleList, [fRipTitlePopUp indexOfSelectedItem] );
-
-    [fPictureGLView SetTitle: title];
-
-    fPicture = 0;
-    [fPictureGLView ShowPicture: fPicture animate: HB_ANIMATE_NONE];
-
-    [fWidthStepper  setValueWraps: NO];
-    [fWidthStepper  setIncrement: 16];
-    [fWidthStepper  setMinValue: 16];
-    [fWidthStepper  setMaxValue: title->outWidthMax];
-    [fWidthStepper  setIntValue: title->outWidth];
-    [fWidthField2   setIntValue: title->outWidth];
-    [fDeinterlaceCheck setState:
-        title->deinterlace ? NSOnState : NSOffState];
-    [fTopStepper    setValueWraps: NO];
-    [fTopStepper    setIncrement: 2];
-    [fTopStepper    setMinValue: 0];
-    [fTopStepper    setMaxValue: title->inHeight / 4];
-    [fTopStepper    setIntValue: title->topCrop];
-    [fTopField2     setIntValue: title->topCrop];
-    [fBottomStepper setValueWraps: NO];
-    [fBottomStepper setIncrement: 2];
-    [fBottomStepper setMinValue: 0];
-    [fBottomStepper setMaxValue: title->inHeight / 4];
-    [fBottomStepper setIntValue: title->bottomCrop];
-    [fBottomField2  setIntValue: title->bottomCrop];
-    [fLeftStepper   setValueWraps: NO];
-    [fLeftStepper   setIncrement: 2];
-    [fLeftStepper   setMinValue: 0];
-    [fLeftStepper   setMaxValue: title->inWidth / 4];
-    [fLeftStepper   setIntValue: title->leftCrop];
-    [fLeftField2    setIntValue: title->leftCrop];
-    [fRightStepper  setValueWraps: NO];
-    [fRightStepper  setIncrement: 2];
-    [fRightStepper  setMinValue: 0];
-    [fRightStepper  setMaxValue: title->inWidth / 4];
-    [fRightStepper  setIntValue: title->rightCrop];
-    [fRightField2   setIntValue: title->rightCrop];
-
-    [fPreviousButton setEnabled: NO];
-    [fNextButton     setEnabled: YES];
-
-    [fInfoField setStringValue: [NSString stringWithFormat:
-        _( @"Final size: %dx%d" ), title->outWidth, title->outHeight] ];
+    hb_list_t  * list  = hb_get_titles( fHandle );
+    hb_title_t * title = (hb_title_t *) hb_list_item( list,
+            [fSrcTitlePopUp indexOfSelectedItem] );
 
     /* Resize the panel */
     NSSize newSize;
-    newSize.width  = 42 +  MAX( 720, title->outWidthMax );
-    newSize.height = 165 + title->outHeightMax;
+    newSize.width  = 246 + title->width;
+    newSize.height = 80 + title->height;
     [fPicturePanel setContentSize: newSize];
 
+    [fPictureController SetTitle: title];
+
     [NSApp beginSheet: fPicturePanel modalForWindow: fWindow
-        modalDelegate: nil didEndSelector: nil contextInfo: nil];
+        modalDelegate: NULL didEndSelector: NULL contextInfo: NULL];
     [NSApp runModalForWindow: fPicturePanel];
     [NSApp endSheet: fPicturePanel];
     [fPicturePanel orderOut: self];
 }
 
-- (IBAction) ClosePanel: (id) sender
+- (IBAction) ShowQueuePanel: (id) sender
 {
-    [NSApp stopModal];
+    /* Update the OutlineView */
+    [fQueueController Update: sender];
+
+    /* Show the panel */
+    [NSApp beginSheet: fQueuePanel modalForWindow: fWindow
+        modalDelegate: NULL didEndSelector: NULL contextInfo: NULL];
+    [NSApp runModalForWindow: fQueuePanel];
+    [NSApp endSheet: fQueuePanel];
+    [fQueuePanel orderOut: self];
 }
 
-- (IBAction) Rip: (id) sender
+- (void) PrepareJob
 {
-    /* Rip or Cancel ? */
-    if( [[fRipRipButton title] compare: _( @"Cancel" ) ]
-            == NSOrderedSame )
+    hb_list_t  * list  = hb_get_titles( fHandle );
+    hb_title_t * title = (hb_title_t *) hb_list_item( list,
+            [fSrcTitlePopUp indexOfSelectedItem] );
+    hb_job_t * job = title->job;
+
+    /* Chapter selection */
+    job->chapter_start = [fSrcChapterStartPopUp indexOfSelectedItem] + 1;
+    job->chapter_end   = [fSrcChapterEndPopUp   indexOfSelectedItem] + 1;
+
+    /* Format and codecs */
+    int format = [fDstFormatPopUp indexOfSelectedItem];
+    int codecs = [fDstCodecsPopUp indexOfSelectedItem];
+    job->mux    = FormatSettings[format][codecs] & HB_MUX_MASK;
+    job->vcodec = FormatSettings[format][codecs] & HB_VCODEC_MASK;
+    job->acodec = FormatSettings[format][codecs] & HB_ACODEC_MASK;
+
+    if( ( job->vcodec & HB_VCODEC_FFMPEG ) &&
+        [fVidEncoderPopUp indexOfSelectedItem] > 0 )
     {
-        [self Cancel: self];
-        return;
+        job->vcodec = HB_VCODEC_XVID;
+    }
+    if( job->vcodec & HB_VCODEC_X264 )
+    {
+        job->h264_13 = [fVidEncoderPopUp indexOfSelectedItem];
     }
 
-    if( [fRipCustomField intValue] < 64 )
+    /* Video settings */
+    if( [fVidRatePopUp indexOfSelectedItem] > 0 )
     {
-        NSBeginCriticalAlertSheet( _( @"Invalid video bitrate" ),
-            _( @"Ooops" ), nil, nil, fWindow, self, nil, nil, nil,
-            _( @"Video bitrate is too low." ) );
-        return;
+        job->vrate      = 27000000;
+        job->vrate_base = hb_video_rates[[fVidRatePopUp
+            indexOfSelectedItem]-1].rate;
     }
-    if( [fRipCustomField intValue] > 8192 )
+    else
     {
-        NSBeginCriticalAlertSheet( _( @"Invalid video bitrate" ),
-            _( @"Ooops" ), nil, nil, fWindow, self, nil, nil, nil,
-            _( @"Video bitrate is too high." ) );
-        return;
+        job->vrate      = title->rate;
+        job->vrate_base = title->rate_base;
     }
-    if( [fRipLang1PopUp indexOfSelectedItem] ==
-            [fRipLang2PopUp indexOfSelectedItem] )
+
+    switch( [fVidQualityMatrix selectedRow] )
     {
-        NSBeginCriticalAlertSheet( _( @"Invalid secondary language" ),
-            _( @"Ooops" ), nil, nil, fWindow, self, nil, nil, nil,
-            _( @"You can't encode the same audio track twice." ) );
+        case 0:
+            /* Target size.
+               Bitrate should already have been calculated and displayed
+               in fVidBitrateField, so let's just use it */
+        case 1:
+            job->vquality = -1.0;
+            job->vbitrate = [fVidBitrateField intValue];
+            break;
+        case 2:
+            job->vquality = [fVidQualitySlider floatValue];
+            job->vbitrate = 0;
+            break;
+    }
+
+    job->grayscale = ( [fVidGrayscaleCheck state] == NSOnState );
+
+    /* Subtitle settings */
+    job->subtitle = [fSubPopUp indexOfSelectedItem] - 1;
+
+    /* Audio tracks */
+    job->audios[0] = [fAudLang1PopUp indexOfSelectedItem] - 1;
+    job->audios[1] = [fAudLang2PopUp indexOfSelectedItem] - 1;
+    job->audios[2] = -1;
+
+    /* Audio settings */
+    job->arate = hb_audio_rates[[fAudRatePopUp
+                     indexOfSelectedItem]].rate;
+    job->abitrate = hb_audio_bitrates[[fAudBitratePopUp
+                        indexOfSelectedItem]].rate;
+}
+
+- (IBAction) EnableQueue: (id) sender
+{
+    bool e = ( [fQueueCheck state] == NSOnState );
+    [fQueueAddButton  setHidden: !e];
+    [fQueueShowButton setHidden: !e];
+    [fRipButton       setTitle: e ? @"Start" : @"Rip"];
+}
+
+- (IBAction) AddToQueue: (id) sender
+{
+    hb_list_t  * list  = hb_get_titles( fHandle );
+    hb_title_t * title = (hb_title_t *) hb_list_item( list,
+            [fSrcTitlePopUp indexOfSelectedItem] );
+    hb_job_t * job = title->job;
+
+    [self PrepareJob];
+
+    /* Destination file */
+    job->file = strdup( [[fDstFile2Field stringValue] UTF8String] );
+
+    if( [fVidTwoPassCheck state] == NSOnState )
+    {
+        job->pass = 1;
+        hb_add( fHandle, job );
+        job->pass = 2;
+        hb_add( fHandle, job );
+    }
+    else
+    {
+        job->pass = 0;
+        hb_add( fHandle, job );
+    }
+}
+
+- (IBAction) Rip: (id) sender
+{
+    /* Rip or Cancel ? */
+    if( [[fRipButton title] isEqualToString: _( @"Cancel" )] )
+    {
+        [self Cancel: sender];
         return;
     }
 
+    if( [fQueueCheck state] == NSOffState )
+    {
+        [self AddToQueue: sender];
+    }
+
     if( [[NSFileManager defaultManager] fileExistsAtPath:
-            [fRipFileField2 stringValue]] )
+            [fDstFile2Field stringValue]] )
     {
         NSBeginCriticalAlertSheet( _( @"File already exists" ),
-            _( @"No" ), _( @"Yes" ), nil, fWindow, self,
+            _( @"Cancel" ), _( @"Overwrite" ), NULL, fWindow, self,
             @selector( OverwriteAlertDone:returnCode:contextInfo: ),
-            nil, nil, [NSString stringWithFormat:
+            NULL, NULL, [NSString stringWithFormat:
             _( @"Do you want to overwrite %@?" ),
-            [fRipFileField2 stringValue]] );
+            [fDstFile2Field stringValue]] );
         return;
     }
 
@@ -397,70 +686,38 @@ static void _RipDone( void * data, int result );
     }
 }
 
-- (void) _Rip
+- (void) UpdateAlertDone: (NSWindow *) sheet
+    returnCode: (int) returnCode contextInfo: (void *) contextInfo
 {
-    /* Get the specified title & audio track(s) */
-    HBTitle * title = (HBTitle*) HBListItemAt( fTitleList,
-            [fRipTitlePopUp indexOfSelectedItem] );
-    HBAudio * audio1 = (HBAudio*) HBListItemAt( title->audioList,
-            [fRipLang1PopUp indexOfSelectedItem] );
-    HBAudio * audio2 = (HBAudio*) HBListItemAt( title->audioList,
-            [fRipLang2PopUp indexOfSelectedItem] );
-
-    /* Use user settings */
-    title->file    = strdup( [[fRipFileField2 stringValue] cString] );
-    title->bitrate = [fRipCustomField intValue];
-    title->twoPass = ( [fRipTwoPassCheck state] == NSOnState );
-
-    int format = [fRipFormatPopUp indexOfSelectedItem];
-    int codec  = [fRipEncoderPopUp indexOfSelectedItem];
-    title->mux = ( !format ) ? HB_MUX_MP4 : ( ( format == 3 ) ?
-            HB_MUX_OGM : HB_MUX_AVI );
-    title->codec = ( format == 2 ) ? HB_CODEC_X264 : ( ( !codec ) ?
-            HB_CODEC_FFMPEG : HB_CODEC_XVID );
-
-    audio1->outBitrate = [[fRipAudBitPopUp titleOfSelectedItem]
-                              intValue];
-    audio1->outCodec = ( !format ) ? HB_CODEC_AAC : ( ( format == 3 ) ?
-            HB_CODEC_VORBIS : HB_CODEC_MP3 );;
-    HBListAdd( title->ripAudioList, audio1 );
-    if( audio2 )
-    {
-        audio2->outBitrate = [[fRipAudBitPopUp
-            titleOfSelectedItem] intValue];
-        audio2->outCodec = ( !format ) ? HB_CODEC_AAC : ( ( format == 3 ) ?
-                HB_CODEC_VORBIS : HB_CODEC_MP3 );
-        HBListAdd( title->ripAudioList, audio2 );
+    if( returnCode == NSAlertAlternateReturn )
+    {
+        /* Show scan panel */
+        [self performSelectorOnMainThread: @selector(ShowScanPanel:)
+            withObject: NULL waitUntilDone: NO];
+        return;
     }
 
-    /* Disable interface */
-    [fRipTitlePopUp   setEnabled: NO];
-    [fRipFormatPopUp  setEnabled: NO];
-    [fRipVideoMatrix  setEnabled: NO];
-    [fRipCustomField  setEnabled: NO];
-    [fRipTargetField  setEnabled: NO];
-    [fRipTwoPassCheck setEnabled: NO];
-    [fRipCropButton   setEnabled: NO];
-    [fRipLang1PopUp   setEnabled: NO];
-    [fRipLang2PopUp   setEnabled: NO];
-    [fRipAudBitPopUp  setEnabled: NO];
-    [fRipFileField2   setEnabled: NO];
-    [fRipEncoderPopUp setEnabled: NO];
-    [fRipBrowseButton setEnabled: NO];
-    [fRipPauseButton  setEnabled: YES];
-    [fRipRipButton    setTitle: _( @"Cancel" )];
-    [fRipProgress     setIndeterminate: YES];
-    [fRipProgress     startAnimation: self];;
+    /* Go to HandBrake homepage and exit */
+    [self OpenHomepage: NULL];
+    [NSApp terminate: self];
+}
 
+- (void) _Rip
+{
     /* Let libhb do the job */
-    HBStartRip( fHandle, title );
+    hb_start( fHandle );
+
+    /* Disable interface */
+    [self EnableUI: NO];
+    [fPauseButton setEnabled: NO];
+    [fRipButton   setEnabled: NO];
 }
 
 - (IBAction) Cancel: (id) sender
 {
     NSBeginCriticalAlertSheet( _( @"Cancel - Are you sure?" ),
-        _( @"No" ), _( @"Yes" ), nil, fWindow, self,
-        @selector( _Cancel:returnCode:contextInfo: ), nil, nil,
+        _( @"Keep working" ), _( @"Cancel encoding" ), NULL, fWindow, self,
+        @selector( _Cancel:returnCode:contextInfo: ), NULL, NULL,
         _( @"Encoding won't be recoverable." ) );
 }
 
@@ -469,500 +726,241 @@ static void _RipDone( void * data, int result );
 {
     if( returnCode == NSAlertAlternateReturn )
     {
-        if( [[fRipPauseButton title] compare: _( @"Resume" ) ]
-                == NSOrderedSame )
-        {
-            HBResumeRip( fHandle );
-        }
-        HBStopRip( fHandle );
+        hb_stop( fHandle );
+        [fPauseButton setEnabled: NO];
+        [fRipButton   setEnabled: NO];
     }
 }
 
 - (IBAction) Pause: (id) sender
 {
-    if( [[fRipPauseButton title] compare: _( @"Resume" ) ]
-            == NSOrderedSame )
-    {
-        [self Resume: self];
-        return;
-    }
-
-    [fRipPauseButton setTitle: _( @"Resume" )];
-    HBPauseRip( fHandle );
-}
-
-- (IBAction) Resume: (id) sender
-{
-    [fRipPauseButton setTitle: _( @"Pause" )];
-    HBResumeRip( fHandle );
-}
-
-- (IBAction) PreviousPicture: (id) sender
-{
-    fPicture--;
-    if( [fOpenGLCheck state] == NSOnState )
-    {
-        [fPictureGLView ShowPicture: fPicture
-            animate: HB_ANIMATE_LEFT];
-    }
-    else
-    {
-        [fPictureGLView ShowPicture: fPicture
-            animate: HB_ANIMATE_NONE];
-    }
-
-    [fPreviousButton setEnabled: ( fPicture > 0 )];
-    [fNextButton     setEnabled: YES];
-}
+    [fPauseButton setEnabled: NO];
+    [fRipButton   setEnabled: NO];
 
-- (IBAction) NextPicture: (id) sender
-{
-    fPicture++;
-    if( [fOpenGLCheck state] == NSOnState )
+    if( [[fPauseButton title] isEqualToString: _( @"Resume" )] )
     {
-        [fPictureGLView ShowPicture: fPicture
-            animate: HB_ANIMATE_RIGHT];
+        hb_resume( fHandle );
     }
     else
     {
-        [fPictureGLView ShowPicture: fPicture
-            animate: HB_ANIMATE_NONE];
+        hb_pause( fHandle );
     }
-
-    [fPreviousButton setEnabled: YES];
-    [fNextButton     setEnabled: ( fPicture < 9 )];
 }
 
-- (IBAction) UpdatePicture: (id) sender
-{
-    HBTitle * title = (HBTitle*)
-        HBListItemAt( fTitleList, [fRipTitlePopUp indexOfSelectedItem] );
-    title->outWidth    = [fWidthStepper intValue];
-    title->deinterlace = ( [fDeinterlaceCheck state] == NSOnState );
-    title->topCrop     = [fTopStepper intValue];
-    title->bottomCrop  = [fBottomStepper intValue];
-    title->leftCrop    = [fLeftStepper intValue];
-    title->rightCrop   = [fRightStepper intValue];
-
-    [fPictureGLView ShowPicture: fPicture animate: HB_ANIMATE_NONE];
-
-    [fWidthStepper  setIntValue: title->outWidth];
-    [fTopStepper    setIntValue: title->topCrop];
-    [fBottomStepper setIntValue: title->bottomCrop];
-    [fLeftStepper   setIntValue: title->leftCrop];
-    [fRightStepper  setIntValue: title->rightCrop];
-    [fWidthField2   setIntValue: [fWidthStepper intValue]];
-    [fTopField2     setIntValue: [fTopStepper intValue]];
-    [fBottomField2  setIntValue: [fBottomStepper intValue]];
-    [fLeftField2    setIntValue: [fLeftStepper intValue]];
-    [fRightField2   setIntValue: [fRightStepper intValue]];
-
-    [fInfoField setStringValue: [NSString stringWithFormat:
-        _( @"Final size: %dx%d" ), title->outWidth, title->outHeight]];
-}
-
-- (IBAction) AutoCrop: (id) sender
-{
-    HBTitle * title = (HBTitle*)
-        HBListItemAt( fTitleList, [fRipTitlePopUp indexOfSelectedItem] );
-    title->topCrop     = title->autoTopCrop;
-    title->bottomCrop  = title->autoBottomCrop;
-    title->leftCrop    = title->autoLeftCrop;
-    title->rightCrop   = title->autoRightCrop;
-
-    [fPictureGLView ShowPicture: fPicture animate: HB_ANIMATE_NONE];
-
-    [fWidthStepper  setIntValue: title->outWidth];
-    [fTopStepper    setIntValue: title->topCrop];
-    [fBottomStepper setIntValue: title->bottomCrop];
-    [fLeftStepper   setIntValue: title->leftCrop];
-    [fRightStepper  setIntValue: title->rightCrop];
-    [fWidthField2   setIntValue: [fWidthStepper intValue]];
-    [fTopField2     setIntValue: [fTopStepper intValue]];
-    [fBottomField2  setIntValue: [fBottomStepper intValue]];
-    [fLeftField2    setIntValue: [fLeftStepper intValue]];
-    [fRightField2   setIntValue: [fRightStepper intValue]];
-
-    [fInfoField setStringValue: [NSString stringWithFormat:
-        _( @"Final size: %dx%d" ), title->outWidth, title->outHeight]];
-}
-
-- (void) DetectDrives: (NSNotification *) notification
+- (IBAction) TitlePopUpChanged: (id) sender
 {
-    /* Scan DVD drives (stolen from VLC) */
-    io_object_t next_media;
-    mach_port_t master_port;
-    kern_return_t kern_result;
-    io_iterator_t media_iterator;
-    CFMutableDictionaryRef classes_to_match;
-
-    kern_result = IOMasterPort( MACH_PORT_NULL, &master_port );
-    if( kern_result != KERN_SUCCESS )
-    {
-        return;
-    }
+    hb_list_t  * list  = hb_get_titles( fHandle );
+    hb_title_t * title = (hb_title_t*)
+        hb_list_item( list, [fSrcTitlePopUp indexOfSelectedItem] );
 
-    classes_to_match = IOServiceMatching( kIODVDMediaClass );
-    if( classes_to_match == NULL )
+    /* Update chapter popups */
+    [fSrcChapterStartPopUp removeAllItems];
+    [fSrcChapterEndPopUp   removeAllItems];
+    for( int i = 0; i < hb_list_count( title->list_chapter ); i++ )
     {
-        return;
+        [fSrcChapterStartPopUp addItemWithTitle: [NSString
+            stringWithFormat: @"%d", i + 1]];
+        [fSrcChapterEndPopUp addItemWithTitle: [NSString
+            stringWithFormat: @"%d", i + 1]];
     }
+    [fSrcChapterStartPopUp selectItemAtIndex: 0];
+    [fSrcChapterEndPopUp   selectItemAtIndex:
+        hb_list_count( title->list_chapter ) - 1];
+    [self ChapterPopUpChanged: NULL];
 
-    CFDictionarySetValue( classes_to_match, CFSTR( kIOMediaEjectableKey ),
-                          kCFBooleanTrue );
-
-    kern_result =
-        IOServiceGetMatchingServices( master_port, classes_to_match,
-                                      &media_iterator );
-    if( kern_result != KERN_SUCCESS )
+    /* Update subtitle popups */
+    hb_subtitle_t * subtitle;
+    [fSubPopUp removeAllItems];
+    [fSubPopUp addItemWithTitle: @"None"];
+    for( int i = 0; i < hb_list_count( title->list_subtitle ); i++ )
     {
-        return;
-    }
-
-    NSMutableArray * drivesList;
-    drivesList = [NSMutableArray arrayWithCapacity: 1];
-
-    next_media = IOIteratorNext( media_iterator );
-    if( next_media != NULL )
-    {
-        char psz_buf[0x32];
-        size_t dev_path_length;
-        CFTypeRef str_bsd_path;
-        do
-        {
-            str_bsd_path =
-                IORegistryEntryCreateCFProperty( next_media,
-                                                 CFSTR( kIOBSDNameKey ),
-                                                 kCFAllocatorDefault,
-                                                 0 );
-            if( str_bsd_path == NULL )
-            {
-                IOObjectRelease( next_media );
-                continue;
-            }
+        subtitle = (hb_subtitle_t *) hb_list_item( title->list_subtitle, i );
 
-            snprintf( psz_buf, sizeof(psz_buf), "%s%c", _PATH_DEV, 'r' );
-            dev_path_length = strlen( psz_buf );
-
-            if( CFStringGetCString( (CFStringRef) str_bsd_path,
-                                    (char*)&psz_buf + dev_path_length,
-                                    sizeof(psz_buf) - dev_path_length,
-                                    kCFStringEncodingASCII ) )
-            {
-                [drivesList addObject:
-                    [NSString stringWithCString: psz_buf]];
-            }
-
-            CFRelease( str_bsd_path );
-
-            IOObjectRelease( next_media );
-
-        } while( ( next_media = IOIteratorNext( media_iterator ) ) != NULL );
+        /* We cannot use NSPopUpButton's addItemWithTitle because
+           it checks for duplicate entries */
+        [[fSubPopUp menu] addItemWithTitle: [NSString stringWithCString:
+            subtitle->lang] action: NULL keyEquivalent: @""];
     }
+    [fSubPopUp selectItemAtIndex: 0];
 
-    IOObjectRelease( media_iterator );
-
-    [fScDetectedPopUp removeAllItems];
-    for( unsigned i = 0; i < [drivesList count]; i++ )
+    /* Update lang popups */
+    hb_audio_t * audio;
+    [fAudLang1PopUp removeAllItems];
+    [fAudLang2PopUp removeAllItems];
+    [fAudLang1PopUp addItemWithTitle: _( @"None" )];
+    [fAudLang2PopUp addItemWithTitle: _( @"None" )];
+    for( int i = 0; i < hb_list_count( title->list_audio ); i++ )
     {
-        [[fScDetectedPopUp menu] addItemWithTitle:
-            [drivesList objectAtIndex: i] action: nil
-            keyEquivalent: @""];
-    }
-    [self ScanMatrixChanged: self];
-}
+        audio = (hb_audio_t *) hb_list_item( title->list_audio, i );
 
-- (IBAction) ScanMatrixChanged: (id) sender
-{
-    if( ![fScMatrix selectedRow] )
-    {
-        [fScDetectedPopUp setEnabled: YES];
-        [fScFolderField setEnabled: NO];
-        [fScBrowseButton setEnabled: NO];
-        [fScOpenButton setEnabled: ( [fScDetectedPopUp selectedItem] != nil )];
-    }
-    else
-    {
-        [fScDetectedPopUp setEnabled: NO];
-        [fScFolderField setEnabled: YES];
-        [fScBrowseButton setEnabled: YES];
-        [fScOpenButton setEnabled: YES];
+        [[fAudLang1PopUp menu] addItemWithTitle:
+            [NSString stringWithCString: audio->lang]
+            action: NULL keyEquivalent: @""];
+        [[fAudLang2PopUp menu] addItemWithTitle:
+            [NSString stringWithCString: audio->lang]
+            action: NULL keyEquivalent: @""];
     }
+    [fAudLang1PopUp selectItemAtIndex: 1];
+    [fAudLang2PopUp selectItemAtIndex: 0];
 }
 
-- (IBAction) TitlePopUpChanged: (id) sender
+- (IBAction) ChapterPopUpChanged: (id) sender
 {
-    HBTitle * title = (HBTitle*)
-        HBListItemAt( fTitleList, [fRipTitlePopUp indexOfSelectedItem] );
+    hb_list_t  * list  = hb_get_titles( fHandle );
+    hb_title_t * title = (hb_title_t *)
+        hb_list_item( list, [fSrcTitlePopUp indexOfSelectedItem] );
 
-    [fRipLang1PopUp removeAllItems];
-    [fRipLang2PopUp removeAllItems];
-
-    HBAudio * audio;
-    for( int i = 0; i < HBListCount( title->audioList ); i++ )
+    hb_chapter_t * chapter;
+    int64_t        duration = 0;
+    for( int i = [fSrcChapterStartPopUp indexOfSelectedItem];
+         i <= [fSrcChapterEndPopUp indexOfSelectedItem]; i++ )
     {
-        audio = (HBAudio*) HBListItemAt( title->audioList, i );
-
-        /* We cannot use NSPopUpButton's addItemWithTitle because
-           it checks for duplicate entries */
-        [[fRipLang1PopUp menu] addItemWithTitle:
-            [NSString stringWithCString: audio->language]
-            action: nil keyEquivalent: @""];
-        [[fRipLang2PopUp menu] addItemWithTitle:
-            [NSString stringWithCString: audio->language]
-            action: nil keyEquivalent: @""];
+        chapter = (hb_chapter_t *) hb_list_item( title->list_chapter, i );
+        duration += chapter->duration;
     }
-    [fRipLang2PopUp addItemWithTitle: _( @"None" )];
-    [fRipLang2PopUp selectItemWithTitle: _( @"None" )];
-    [fRipLang2PopUp setEnabled:
-        ( HBListCount( title->audioList ) > 1 )];
+    
+    duration /= 90000; /* pts -> seconds */
+    [fSrcDuration2Field setStringValue: [NSString stringWithFormat:
+        @"%02lld:%02lld:%02lld", duration / 3600, ( duration / 60 ) % 60,
+        duration % 60]];
 
-    [fRipTargetField SetHBTitle: title];
-    if( [fRipVideoMatrix selectedRow] )
-    {
-        [fRipTargetField UpdateBitrate];
-    }
+    [self CalculateBitrate: sender];
 }
 
 - (IBAction) FormatPopUpChanged: (id) sender
 {
-    /* Headers size changes depending on the format, so let's
-       recalculate the bitrate if necessary */
-    if( [fRipVideoMatrix selectedRow] )
+    NSString * string = [fDstFile2Field stringValue];
+    int format = [fDstFormatPopUp indexOfSelectedItem];
+    char * ext = NULL;
+
+    /* Update the codecs popup */
+    [fDstCodecsPopUp removeAllItems];
+    switch( format )
     {
-        [fRipTargetField UpdateBitrate];
+        case 0:
+            ext = "mp4";
+            [fDstCodecsPopUp addItemWithTitle:
+                _( @"MPEG-4 Video / AAC Audio" )];
+            [fDstCodecsPopUp addItemWithTitle:
+                _( @"AVC/H.264 Video / AAC Audio" )];
+            break;
+        case 1: 
+            ext = "avi";
+            [fDstCodecsPopUp addItemWithTitle:
+                _( @"MPEG-4 Video / MP3 Audio" )];
+            [fDstCodecsPopUp addItemWithTitle:
+                _( @"MPEG-4 Video / AC-3 Audio" )];
+            [fDstCodecsPopUp addItemWithTitle:
+                _( @"AVC/H.264 Video / MP3 Audio" )];
+            [fDstCodecsPopUp addItemWithTitle:
+                _( @"AVC/H.264 Video / AC-3 Audio" )];
+            break;
+        case 2:
+            ext = "ogm";
+            [fDstCodecsPopUp addItemWithTitle:
+                _( @"MPEG-4 Video / Vorbis Audio" )];
+            [fDstCodecsPopUp addItemWithTitle:
+                _( @"MPEG-4 Video / MP3 Audio" )];
+            break;
     }
+    [self CodecsPopUpChanged: NULL];
 
     /* Add/replace to the correct extension */
-    NSString * string = [fRipFileField2 stringValue];
-    int format = [fRipFormatPopUp indexOfSelectedItem];
     if( [string characterAtIndex: [string length] - 4] == '.' )
     {
-        [fRipFileField2 setStringValue: [NSString stringWithFormat:
+        [fDstFile2Field setStringValue: [NSString stringWithFormat:
             @"%@.%s", [string substringToIndex: [string length] - 4],
-            ( !format ) ? "mp4" : ( ( format == 3 ) ?
-            "ogm" : "avi" )]];
+            ext]];
     }
     else
     {
-        [fRipFileField2 setStringValue: [NSString stringWithFormat:
-            @"%@.%s", string, ( !format ) ? "mp4" :
-            ( ( format == 3 ) ? "ogm" : "avi" )]];
+        [fDstFile2Field setStringValue: [NSString stringWithFormat:
+            @"%@.%s", string, ext]];
     }
+}
 
-    if( format == 2 )
+- (IBAction) CodecsPopUpChanged: (id) sender
+{
+    int format = [fDstFormatPopUp indexOfSelectedItem];
+    int codecs = [fDstCodecsPopUp indexOfSelectedItem];
+
+    /* Update the encoder popup if necessary */
+    if( ( FormatSettings[format][codecs] & HB_VCODEC_X264 ) &&
+        [fVidEncoderPopUp numberOfItems] > 1 )
     {
-        /* Can't set X264 bitrate */
-        [fRipEncoderPopUp setEnabled: NO];
-        [fRipVideoMatrix  setEnabled: NO];
-        [fRipTwoPassCheck setEnabled: NO];
+        /* MPEG-4 -> H.264 */
+        [fVidEncoderPopUp removeAllItems];
+        [fVidEncoderPopUp addItemWithTitle: @"x264 (Main profile)"];
+        [fVidEncoderPopUp addItemWithTitle: @"x264 (Baseline profile)"];
     }
-    else if( format == 3 )
+    else if( ( FormatSettings[format][codecs] & HB_VCODEC_FFMPEG ) &&
+             [fVidEncoderPopUp numberOfItems] < 2 )
+    {
+        /* H.264 -> MPEG-4 */
+        [fVidEncoderPopUp removeAllItems];
+        [fVidEncoderPopUp addItemWithTitle: @"FFmpeg"];
+        [fVidEncoderPopUp addItemWithTitle: @"XviD"];
+        [fVidEncoderPopUp selectItemAtIndex: 0];
+    }
+
+    if( FormatSettings[format][codecs] & HB_ACODEC_AC3 )
     {
-        [fRipEncoderPopUp setEnabled: YES];
-        [fRipVideoMatrix  setEnabled: YES];
-        [fRipTwoPassCheck setEnabled: YES];
+        /* AC-3 pass-through: disable samplerate and bitrate */
+        [fAudRatePopUp    setEnabled: NO];
+        [fAudBitratePopUp setEnabled: NO];
     }
     else
     {
-        [fRipEncoderPopUp setEnabled: YES];
-        [fRipVideoMatrix  setEnabled: YES];
-        [fRipTwoPassCheck setEnabled: YES];
+        [fAudRatePopUp    setEnabled: YES];
+        [fAudBitratePopUp setEnabled: YES];
     }
-    [self VideoMatrixChanged: self];
+
+    [self CalculateBitrate: sender];
 }
 
-- (IBAction) AudioPopUpChanged: (id) sender
+- (IBAction) CalculateBitrate: (id) sender
 {
-    /* Recalculate the bitrate */
-    if( [fRipVideoMatrix selectedRow] )
+    if( !fHandle || [fVidQualityMatrix selectedRow] != 0 )
     {
-        [fRipTargetField UpdateBitrate];
+        return;
     }
+
+    hb_list_t  * list  = hb_get_titles( fHandle );
+    hb_title_t * title = (hb_title_t *) hb_list_item( list,
+            [fSrcTitlePopUp indexOfSelectedItem] );
+    hb_job_t * job = title->job;
+
+    [self PrepareJob];
+
+    [fVidBitrateField setIntValue: hb_calc_bitrate( job,
+            [fVidTargetSizeField intValue] )];
 }
 
-/*******************
- * libhb callbacks *
- *******************/
-static void _Scanning( void * data, int title, int titleCount )
+- (void) controlTextDidBeginEditing: (NSNotification *) notification
 {
-    HBController * controller = (HBController*) data;
-    controller->fTitle        = title;
-    controller->fTitleCount   = titleCount;
-    [controller performSelectorOnMainThread: @selector(Scanning:)
-        withObject: nil waitUntilDone: YES];
+    [self CalculateBitrate: NULL];
 }
-- (void) Scanning: (id) sender
-{
-    [fScProgress stopAnimation: self];
-    [fScProgress setIndeterminate: NO];
-    [fScProgress setDoubleValue: 100.0 * fTitle / fTitleCount];
 
-    [fScStatusField setStringValue: [NSString stringWithFormat:
-        _( @"Scanning title %d of %d..." ), fTitle, fTitleCount]];
+- (void) controlTextDidEndEditing: (NSNotification *) notification
+{
+    [self CalculateBitrate: NULL];
 }
 
-static void _ScanDone( void * data, HBList * titleList )
+- (void) controlTextDidChange: (NSNotification *) notification
 {
-    HBController * controller = (HBController*) data;
-    controller->fTitleList    = titleList;
-    [controller performSelectorOnMainThread: @selector(ScanDone:)
-        withObject: nil waitUntilDone: YES];
+    [self CalculateBitrate: NULL];
 }
-- (void) ScanDone: (id) sender
+
+- (IBAction) OpenHomepage: (id) sender
 {
-    if( !fTitleList )
-    {
-        [fScMatrix setEnabled: YES];
-        [self ScanMatrixChanged: self];
-        [fScProgress stopAnimation: self];
-        [fScProgress setIndeterminate: NO];
-        [fScOpenButton setEnabled: YES];
-        [fScStatusField setStringValue:
-            _( @"Invalid volume, try again" ) ];
-        return;
-    }
+    [[NSWorkspace sharedWorkspace] openURL: [NSURL
+        URLWithString:@"http://handbrake.m0k.org/"]];
+}
 
-    /* Show a temporary empty view while the window
-       resizing animation */
-    [fWindow setContentView: fTempView ];
-
-    /* Actually resize it */
-    NSRect newFrame;
-    newFrame = [NSWindow contentRectForFrameRect: [fWindow frame]
-                 styleMask: [fWindow styleMask]];
-    newFrame.origin.y    += newFrame.size.height -
-                                [fRipView frame].size.height;
-    newFrame.size.height  = [fRipView frame].size.height;
-    newFrame.size.width   = [fRipView frame].size.width;
-    newFrame = [NSWindow frameRectForContentRect: newFrame
-                 styleMask: [fWindow styleMask]];
-    [fWindow setFrame: newFrame display: YES animate: YES];
-
-    /* Show the new GUI */
-    [fWindow setContentView: fRipView ];
-    [fRipPauseButton setEnabled: NO];
-
-    [fRipTitlePopUp removeAllItems];
-    HBTitle * title;
-    for( int i = 0; i < HBListCount( fTitleList ); i++ )
-    {
-        title = (HBTitle*) HBListItemAt( fTitleList, i );
-        [[fRipTitlePopUp menu] addItemWithTitle:
-            [NSString stringWithFormat: @"%d - %02dh%02dm%02ds",
-            title->title, title->hours, title->minutes,
-            title->seconds] action: nil keyEquivalent: @""];
-    }
-    [self TitlePopUpChanged: self];
-}
-
-static void _Encoding( void * data, float position, int pass,
-                      int passCount, float curFrameRate,
-                      float avgFrameRate, int remainingTime )
-{
-    HBController * controller  = (HBController*) data;
-    controller->fPosition      = position;
-    controller->fPass          = pass;
-    controller->fPassCount     = passCount;
-    controller->fCurFrameRate  = curFrameRate;
-    controller->fAvgFrameRate  = avgFrameRate;
-    controller->fRemainingTime = remainingTime;
-    [controller performSelectorOnMainThread: @selector(Encoding:)
-        withObject: nil waitUntilDone: YES];
-}
-- (void) Encoding: (id) sender
-{
-    [fRipStatusField setStringValue: [NSString stringWithFormat:
-        _( @"Encoding: %.2f %% (pass %d of %d)" ),
-        100.0 * fPosition, fPass, fPassCount]];
-    [fRipInfoField setStringValue: [NSString stringWithFormat:
-        _( @"Speed: %.2f fps (avg %.2f fps), %02dh%02dm%02ds remaining" ),
-        fCurFrameRate, fAvgFrameRate, fRemainingTime / 3600,
-        ( fRemainingTime / 60 ) % 60, fRemainingTime % 60]];
-
-    [fRipProgress setIndeterminate: NO];
-    [fRipProgress setDoubleValue: 100.0 * fPosition];
-}
-
-static void _RipDone( void * data, int result )
-{
-    HBController * controller = (HBController*) data;
-    controller->fResult       = result;
-    [controller performSelectorOnMainThread: @selector(RipDone:)
-        withObject: nil waitUntilDone: YES];
-}
-- (void) RipDone: (id) sender
-{
-    [fRipTitlePopUp   setEnabled: YES];
-    [fRipFormatPopUp  setEnabled: YES];
-    [fRipVideoMatrix  setEnabled: YES];
-    [fRipTwoPassCheck setEnabled: YES];
-    [fRipCropButton   setEnabled: YES];
-    [fRipLang1PopUp   setEnabled: YES];
-    [fRipLang2PopUp   setEnabled: YES];
-    [fRipAudBitPopUp  setEnabled: YES];
-    [fRipFileField2   setEnabled: YES];
-    [fRipBrowseButton setEnabled: YES];
-    [fRipEncoderPopUp setEnabled: YES];
-    [fRipPauseButton  setEnabled: NO];
-    [fRipPauseButton  setTitle: _( @"Pause" )];
-    [fRipRipButton    setTitle: _( @"Rip" )];
-    [fRipProgress     setIndeterminate: NO];
-    [fRipProgress     setDoubleValue: 0.0];
-    [self VideoMatrixChanged: self];
-
-    switch( fResult )
-    {
-        case HB_SUCCESS:
-            [fRipStatusField setStringValue: _( @"Rip completed." )];
-            [fRipInfoField   setStringValue: @""];
-            NSBeep();
-            [NSApp requestUserAttention: NSInformationalRequest];
-            [NSApp beginSheet: fDonePanel
-                modalForWindow: fWindow modalDelegate: nil
-                didEndSelector: nil contextInfo: nil];
-            [NSApp runModalForWindow: fDonePanel];
-            [NSApp endSheet: fDonePanel];
-            [fDonePanel orderOut: self];
-            break;
-        case HB_CANCELED:
-            [fRipStatusField setStringValue: _( @"Canceled." )];
-            [fRipInfoField   setStringValue: @""];
-            break;
-        case HB_ERROR_A52_SYNC:
-            [fRipStatusField setStringValue: @"Error."];
-            [fRipInfoField   setStringValue: @"Corrupted AC3 data"];
-            break;
-        case HB_ERROR_AVI_WRITE:
-            [fRipStatusField setStringValue: @"Error."];
-            [fRipInfoField   setStringValue: @"Write error"];
-            break;
-        case HB_ERROR_DVD_OPEN:
-            [fRipStatusField setStringValue: @"Error."];
-            [fRipInfoField   setStringValue: @"Could not open the DVD"];
-            break;
-        case HB_ERROR_DVD_READ:
-            [fRipStatusField setStringValue: @"Error."];
-            [fRipInfoField   setStringValue: @"DVD read error"];
-            break;
-        case HB_ERROR_MP3_INIT:
-            [fRipStatusField setStringValue: @"Error."];
-            [fRipInfoField   setStringValue:
-                @"MP3 encoder initialization failed"];
-            break;
-        case HB_ERROR_MP3_ENCODE:
-            [fRipStatusField setStringValue: @"Error."];
-            [fRipInfoField   setStringValue: @"MP3 encoder failed"];
-            break;
-        case HB_ERROR_MPEG4_INIT:
-            [fRipStatusField setStringValue: @"Error."];
-            [fRipInfoField   setStringValue:
-                @"MPEG4 encoder initialization failed"];
-            break;
-        default:
-            [fRipStatusField setStringValue: @"Error."];
-            [fRipInfoField   setStringValue: @"Unknown error"];
-    }
+- (IBAction) OpenForums: (id) sender
+{
+    [[NSWorkspace sharedWorkspace] openURL: [NSURL
+        URLWithString:@"http://handbrake.m0k.org/forum/"]];
 }
 
 @end
index b77248a..59629f0 100644 (file)
         {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, 
         {
             ACTIONS = {
-                AudioPopUpChanged = id; 
-                AutoCrop = id; 
-                BrowseDVD = id; 
+                AddToQueue = id; 
                 BrowseFile = id; 
+                CalculateBitrate = id; 
                 Cancel = id; 
-                ClosePanel = id; 
-                Encoding = id; 
+                ChapterPopUpChanged = id; 
+                CodecsPopUpChanged = id; 
+                EnableQueue = id; 
                 FormatPopUpChanged = id; 
-                NextPicture = id; 
+                OpenForums = id; 
+                OpenHomepage = id; 
                 Pause = id; 
-                PreviousPicture = id; 
-                Resume = id; 
+                QualitySliderChanged = id; 
                 Rip = id; 
-                RipDone = id; 
-                Scan = id; 
-                ScanDone = id; 
-                ScanMatrixChanged = id; 
-                Scanning = id; 
                 ShowPicturePanel = id; 
+                ShowQueuePanel = id; 
+                ShowScanPanel = id; 
                 TitlePopUpChanged = id; 
-                UpdatePicture = id; 
                 VideoMatrixChanged = id; 
             }; 
             CLASS = HBController; 
             LANGUAGE = ObjC; 
             OUTLETS = {
-                fAutocropButton = NSButton; 
-                fBottomField1 = NSTextField; 
-                fBottomField2 = NSTextField; 
-                fBottomStepper = NSStepper; 
-                fCloseButton = NSButton; 
-                fDeinterlaceCheck = NSButton; 
-                fDonePanel = NSPanel; 
-                fInfoField = NSTextField; 
-                fLeftField1 = NSTextField; 
-                fLeftField2 = NSTextField; 
-                fLeftStepper = NSStepper; 
-                fNextButton = NSButton; 
-                fOpenGLCheck = NSButton; 
-                fPictureGLView = HBPictureGLView; 
+                fAddToQuButton = NSButton; 
+                fAudBitrateField = NSTextField; 
+                fAudBitratePopUp = NSPopUpButton; 
+                fAudLang1Field = NSTextField; 
+                fAudLang1PopUp = NSPopUpButton; 
+                fAudLang2Field = NSTextField; 
+                fAudLang2PopUp = NSPopUpButton; 
+                fAudRateField = NSTextField; 
+                fAudRatePopUp = NSPopUpButton; 
+                fDstBrowseButton = NSButton; 
+                fDstCodecsField = NSTextField; 
+                fDstCodecsPopUp = NSPopUpButton; 
+                fDstFile1Field = NSTextField; 
+                fDstFile2Field = NSTextField; 
+                fDstFormatField = NSTextField; 
+                fDstFormatPopUp = NSPopUpButton; 
+                fPauseButton = NSButton; 
+                fPictureButton = NSButton; 
+                fPictureController = PictureController; 
                 fPicturePanel = NSPanel; 
-                fPreviousButton = NSButton; 
-                fRightField1 = NSTextField; 
-                fRightField2 = NSTextField; 
-                fRightStepper = NSStepper; 
-                fRipAudBitField = NSTextField; 
-                fRipAudBitPopUp = NSPopUpButton; 
-                fRipAudioField = NSTextField; 
-                fRipBitrateField = NSTextField; 
-                fRipBrowseButton = NSButton; 
-                fRipCropButton = NSButton; 
-                fRipCustomCell = NSButtonCell; 
-                fRipCustomField = NSTextField; 
-                fRipEncoderField = NSTextField; 
-                fRipEncoderPopUp = NSPopUpButton; 
-                fRipFileField1 = NSTextField; 
-                fRipFileField2 = NSTextField; 
-                fRipFormatField = NSTextField; 
-                fRipFormatPopUp = NSPopUpButton; 
-                fRipGeneralField = NSTextField; 
-                fRipInfoField = NSTextField; 
-                fRipLang1Field = NSTextField; 
-                fRipLang1PopUp = NSPopUpButton; 
-                fRipLang2Field = NSTextField; 
-                fRipLang2PopUp = NSPopUpButton; 
-                fRipPauseButton = NSButton; 
-                fRipProgress = NSProgressIndicator; 
-                fRipRipButton = NSButton; 
-                fRipStatusField = NSTextField; 
-                fRipTargetCell = NSButtonCell; 
-                fRipTargetField = HBTargetSizeField; 
-                fRipTitleField = NSTextField; 
-                fRipTitlePopUp = NSPopUpButton; 
-                fRipTwoPassCheck = NSButton; 
-                fRipVideoField = NSTextField; 
-                fRipVideoMatrix = NSMatrix; 
-                fRipView = NSView; 
-                fScBrowseButton = NSButton; 
-                fScDetectedCell = NSButtonCell; 
-                fScDetectedPopUp = NSPopUpButton; 
-                fScFolderCell = NSButtonCell; 
-                fScFolderField = NSTextField; 
-                fScMatrix = NSMatrix; 
-                fScOpenButton = NSButton; 
-                fScProgress = NSProgressIndicator; 
-                fScSelectField = NSTextField; 
-                fScStatusField = NSTextField; 
-                fScView = NSView; 
-                fScWelcomeField = NSTextField; 
-                fTempView = NSView; 
-                fTopField1 = NSTextField; 
-                fTopField2 = NSTextField; 
-                fTopStepper = NSStepper; 
-                fWidthField1 = NSTextField; 
-                fWidthField2 = NSTextField; 
-                fWidthStepper = NSStepper; 
+                fQueueAddButton = NSButton; 
+                fQueueCheck = NSButton; 
+                fQueueController = QueueController; 
+                fQueuePanel = NSPanel; 
+                fQueueShowButton = NSButton; 
+                fRipButton = NSButton; 
+                fRipIndicator = NSProgressIndicator; 
+                fScanController = ScanController; 
+                fScanPanel = NSPanel; 
+                fShowQuButton = NSButton; 
+                fSrcChapterEndPopUp = NSPopUpButton; 
+                fSrcChapterField = NSTextField; 
+                fSrcChapterStartPopUp = NSPopUpButton; 
+                fSrcChapterToField = NSTextField; 
+                fSrcDVD1Field = NSTextField; 
+                fSrcDVD2Field = NSTextField; 
+                fSrcDuration1Field = NSTextField; 
+                fSrcDuration2Field = NSTextField; 
+                fSrcTitleField = NSTextField; 
+                fSrcTitlePopUp = NSPopUpButton; 
+                fStatusField = NSTextField; 
+                fSubField = NSTextField; 
+                fSubPopUp = NSPopUpButton; 
+                fVidBitrateCell = NSButtonCell; 
+                fVidBitrateField = NSTextField; 
+                fVidConstantCell = NSButtonCell; 
+                fVidEncoderField = NSTextField; 
+                fVidEncoderPopUp = NSPopUpButton; 
+                fVidGrayscaleCheck = NSButton; 
+                fVidQualityField = NSTextField; 
+                fVidQualityMatrix = NSMatrix; 
+                fVidQualitySlider = NSSlider; 
+                fVidRateField = NSTextField; 
+                fVidRatePopUp = NSPopUpButton; 
+                fVidTargetCell = NSButtonCell; 
+                fVidTargetSizeField = NSTextField; 
+                fVidTwoPassCheck = NSButton; 
                 fWindow = NSWindow; 
             }; 
             SUPERCLASS = NSObject; 
             }; 
             SUPERCLASS = NSTextField; 
         }, 
-        {CLASS = PictureGLView; LANGUAGE = ObjC; SUPERCLASS = NSOpenGLView; }
+        {
+            ACTIONS = {
+                ClosePanel = id; 
+                NextPicture = id; 
+                PreviousPicture = id; 
+                SettingsChanged = id; 
+            }; 
+            CLASS = PictureController; 
+            LANGUAGE = ObjC; 
+            OUTLETS = {
+                fCropBottomField = NSTextField; 
+                fCropBottomStepper = NSStepper; 
+                fCropLeftField = NSTextField; 
+                fCropLeftStepper = NSStepper; 
+                fCropMatrix = NSMatrix; 
+                fCropRightField = NSTextField; 
+                fCropRightStepper = NSStepper; 
+                fCropTopField = NSTextField; 
+                fCropTopStepper = NSStepper; 
+                fDeinterlaceCheck = NSButton; 
+                fEffectsCheck = NSButton; 
+                fHeightField = NSTextField; 
+                fHeightStepper = NSStepper; 
+                fInfoField = NSTextField; 
+                fNextButton = NSButton; 
+                fPictureGLView = HBPictureGLView; 
+                fPrevButton = NSButton; 
+                fRatioCheck = NSButton; 
+                fWidthField = NSTextField; 
+                fWidthStepper = NSStepper; 
+            }; 
+            SUPERCLASS = NSObject; 
+        }, 
+        {CLASS = PictureGLView; LANGUAGE = ObjC; SUPERCLASS = NSOpenGLView; }, 
+        {
+            ACTIONS = {CheckChanged = id; ClosePanel = id; OpenPanel = id; }; 
+            CLASS = PrefsController; 
+            LANGUAGE = ObjC; 
+            OUTLETS = {fPanel = NSPanel; fUpdateCheck = NSButton; }; 
+            SUPERCLASS = NSObject; 
+        }, 
+        {
+            ACTIONS = {ClosePanel = id; Remove = id; Update = id; }; 
+            CLASS = QueueController; 
+            LANGUAGE = ObjC; 
+            OUTLETS = {fScrollView = NSScrollView; fTaskView = NSView; }; 
+            SUPERCLASS = NSObject; 
+        }, 
+        {
+            ACTIONS = {
+                Browse = id; 
+                Browse2 = id; 
+                BrowseDone2 = id; 
+                Cancel = id; 
+                MatrixChanged = id; 
+                Open = id; 
+            }; 
+            CLASS = ScanController; 
+            LANGUAGE = ObjC; 
+            OUTLETS = {
+                fBrowseButton = NSButton; 
+                fCancelButton = NSButton; 
+                fDetectedCell = NSButtonCell; 
+                fDetectedPopUp = NSPopUpButton; 
+                fFolderCell = NSButtonCell; 
+                fFolderField = NSTextField; 
+                fIndicator = NSProgressIndicator; 
+                fMatrix = NSMatrix; 
+                fOpenButton = NSButton; 
+                fPanel = NSPanel; 
+                fSelectString = NSTextField; 
+                fStatusField = NSTextField; 
+                fWindow = NSWindow; 
+            }; 
+            SUPERCLASS = NSObject; 
+        }
     ); 
     IBVersion = 1; 
 }
\ No newline at end of file
index 07d1cfa..0854e6d 100644 (file)
@@ -3,29 +3,24 @@
 <plist version="1.0">
 <dict>
        <key>IBDocumentLocation</key>
-       <string>37 177 381 380 0 0 1440 878 </string>
+       <string>73 30 382 380 0 0 1440 878 </string>
        <key>IBEditorPositions</key>
        <dict>
                <key>29</key>
-               <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>
-               <string>650 499 144 171 0 0 1440 878 </string>
-               <key>689</key>
-               <string>513 258 470 610 0 0 1440 878 </string>
+               <string>157 764 261 44 0 0 1280 832 </string>
        </dict>
        <key>IBFramework Version</key>
-       <string>349.0</string>
+       <string>439.0</string>
        <key>IBOpenObjects</key>
        <array>
-               <integer>29</integer>
                <integer>365</integer>
-               <integer>583</integer>
-               <integer>434</integer>
+               <integer>1438</integer>
                <integer>21</integer>
+               <integer>29</integer>
+               <integer>1162</integer>
+               <integer>1348</integer>
        </array>
        <key>IBSystem Version</key>
-       <string>7F44</string>
+       <string>8F46</string>
 </dict>
 </plist>
diff --git a/macosx/English.lproj/MainMenu.nib/keyedobjects.nib b/macosx/English.lproj/MainMenu.nib/keyedobjects.nib
new file mode 100644 (file)
index 0000000..9d8af01
Binary files /dev/null and b/macosx/English.lproj/MainMenu.nib/keyedobjects.nib differ
diff --git a/macosx/English.lproj/MainMenu.nib/objects.nib b/macosx/English.lproj/MainMenu.nib/objects.nib
deleted file mode 100644 (file)
index 5a2d374..0000000
Binary files a/macosx/English.lproj/MainMenu.nib/objects.nib and /dev/null differ
index f1d08d3..f81352b 100644 (file)
Binary files a/macosx/HandBrake.icns and b/macosx/HandBrake.icns differ
diff --git a/macosx/HandBrake.xcode/project.pbxproj b/macosx/HandBrake.xcode/project.pbxproj
deleted file mode 100644 (file)
index c9ac3a6..0000000
+++ /dev/null
@@ -1,560 +0,0 @@
-// !$*UTF8*$!
-{
-       archiveVersion = 1;
-       classes = {
-       };
-       objectVersion = 39;
-       objects = {
-               080E96DCFE201CFB7F000001 = {
-                       fileRef = 29B97318FDCFA39411CA2CEA;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               080E96DDFE201D6D7F000001 = {
-                       children = (
-                               4DF3C8CB052889CD00A80101,
-                               4DF3C8CC052889CD00A80101,
-                               4D85758E052B78E300C39CA9,
-                               4D85758F052B78E300C39CA9,
-                               4D358C000534A91300D654EB,
-                               4D358C010534A91300D654EB,
-                       );
-                       isa = PBXGroup;
-                       name = Classes;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               089C165CFE840E0CC02AAC07 = {
-                       children = (
-                               089C165DFE840E0CC02AAC07,
-                       );
-                       isa = PBXVariantGroup;
-                       name = InfoPlist.strings;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               089C165DFE840E0CC02AAC07 = {
-                       fileEncoding = 10;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.plist.strings;
-                       name = English;
-                       path = English.lproj/InfoPlist.strings;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               089C165EFE840E0CC02AAC07 = {
-                       fileRef = 089C165CFE840E0CC02AAC07;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-//080
-//081
-//082
-//083
-//084
-//100
-//101
-//102
-//103
-//104
-               1058C7A0FEA54F0111CA2CBB = {
-                       children = (
-                               1058C7A1FEA54F0111CA2CBB,
-                               4DEB2024052B055F00C39CA9,
-                               4DDE9724052B7B2B00C39CA9,
-                       );
-                       isa = PBXGroup;
-                       name = "Linked Frameworks";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               1058C7A1FEA54F0111CA2CBB = {
-                       fallbackIsa = PBXFileReference;
-                       isa = PBXFrameworkReference;
-                       lastKnownFileType = wrapper.framework;
-                       name = Cocoa.framework;
-                       path = /System/Library/Frameworks/Cocoa.framework;
-                       refType = 0;
-                       sourceTree = "<absolute>";
-               };
-               1058C7A2FEA54F0111CA2CBB = {
-                       children = (
-                               29B97325FDCFA39411CA2CEA,
-                               29B97324FDCFA39411CA2CEA,
-                       );
-                       isa = PBXGroup;
-                       name = "Other Frameworks";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               1058C7A3FEA54F0111CA2CBB = {
-                       fileRef = 1058C7A1FEA54F0111CA2CBB;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-//100
-//101
-//102
-//103
-//104
-//170
-//171
-//172
-//173
-//174
-               17587328FF379C6511CA2CBB = {
-                       explicitFileType = wrapper.application;
-                       fallbackIsa = PBXFileReference;
-                       isa = PBXApplicationReference;
-                       path = HandBrake.app;
-                       refType = 3;
-                       sourceTree = BUILT_PRODUCTS_DIR;
-               };
-//170
-//171
-//172
-//173
-//174
-//190
-//191
-//192
-//193
-//194
-               19C28FACFE9D520D11CA2CBB = {
-                       children = (
-                               17587328FF379C6511CA2CBB,
-                       );
-                       isa = PBXGroup;
-                       name = Products;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-//190
-//191
-//192
-//193
-//194
-//290
-//291
-//292
-//293
-//294
-               29B97313FDCFA39411CA2CEA = {
-                       buildSettings = {
-                               MACOSX_DEPLOYMENT_TARGET = 10.2;
-                               SDKROOT = /Developer/SDKs/MacOSX10.2.7.sdk;
-                       };
-                       buildStyles = (
-                               4A9504CCFFE6A4B311CA0CBA,
-                               4A9504CDFFE6A4B311CA0CBA,
-                       );
-                       hasScannedForEncodings = 1;
-                       isa = PBXProject;
-                       mainGroup = 29B97314FDCFA39411CA2CEA;
-                       projectDirPath = "";
-                       targets = (
-                               29B97326FDCFA39411CA2CEA,
-                       );
-               };
-               29B97314FDCFA39411CA2CEA = {
-                       children = (
-                               080E96DDFE201D6D7F000001,
-                               29B97315FDCFA39411CA2CEA,
-                               29B97317FDCFA39411CA2CEA,
-                               29B97323FDCFA39411CA2CEA,
-                               19C28FACFE9D520D11CA2CBB,
-                       );
-                       isa = PBXGroup;
-                       name = HandBrake;
-                       path = "";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               29B97315FDCFA39411CA2CEA = {
-                       children = (
-                               29B97316FDCFA39411CA2CEA,
-                               4DFDC318054AC84C00151618,
-                       );
-                       isa = PBXGroup;
-                       name = "Other Sources";
-                       path = "";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               29B97316FDCFA39411CA2CEA = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.objcpp;
-                       path = main.mm;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               29B97317FDCFA39411CA2CEA = {
-                       children = (
-                               29B97318FDCFA39411CA2CEA,
-                               4D118405053054CD00C39CA9,
-                               089C165CFE840E0CC02AAC07,
-                       );
-                       isa = PBXGroup;
-                       name = Resources;
-                       path = "";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               29B97318FDCFA39411CA2CEA = {
-                       children = (
-                               29B97319FDCFA39411CA2CEA,
-                       );
-                       isa = PBXVariantGroup;
-                       name = MainMenu.nib;
-                       path = "";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               29B97319FDCFA39411CA2CEA = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = wrapper.nib;
-                       name = English;
-                       path = English.lproj/MainMenu.nib;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               29B97323FDCFA39411CA2CEA = {
-                       children = (
-                               1058C7A0FEA54F0111CA2CBB,
-                               1058C7A2FEA54F0111CA2CBB,
-                       );
-                       isa = PBXGroup;
-                       name = Frameworks;
-                       path = "";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               29B97324FDCFA39411CA2CEA = {
-                       fallbackIsa = PBXFileReference;
-                       isa = PBXFrameworkReference;
-                       lastKnownFileType = wrapper.framework;
-                       name = AppKit.framework;
-                       path = /System/Library/Frameworks/AppKit.framework;
-                       refType = 0;
-                       sourceTree = "<absolute>";
-               };
-               29B97325FDCFA39411CA2CEA = {
-                       fallbackIsa = PBXFileReference;
-                       isa = PBXFrameworkReference;
-                       lastKnownFileType = wrapper.framework;
-                       name = Foundation.framework;
-                       path = /System/Library/Frameworks/Foundation.framework;
-                       refType = 0;
-                       sourceTree = "<absolute>";
-               };
-               29B97326FDCFA39411CA2CEA = {
-                       buildPhases = (
-                               29B97327FDCFA39411CA2CEA,
-                               29B97328FDCFA39411CA2CEA,
-                               29B9732BFDCFA39411CA2CEA,
-                               29B9732DFDCFA39411CA2CEA,
-                       );
-                       buildSettings = {
-                               FRAMEWORK_SEARCH_PATHS = "";
-                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
-                               HEADER_SEARCH_PATHS = "";
-                               LIBRARY_SEARCH_PATHS = "";
-                               OPTIMIZATION_CFLAGS = "-O3";
-                               OTHER_CFLAGS = "";
-                               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";
-                               WRAPPER_EXTENSION = app;
-                       };
-                       dependencies = (
-                       );
-                       isa = PBXApplicationTarget;
-                       name = HandBrake;
-                       productName = HandBrake;
-                       productReference = 17587328FF379C6511CA2CBB;
-                       productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
-<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
-<plist version=\"1.0\">
-<dict>
-       <key>CFBundleDevelopmentRegion</key>
-       <string>English</string>
-       <key>CFBundleDisplayName</key>
-       <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>
-       <string>org.m0k.handbrake</string>
-       <key>CFBundleInfoDictionaryVersion</key>
-       <string>6.0</string>
-       <key>CFBundleName</key>
-       <string>HandBrake</string>
-       <key>CFBundlePackageType</key>
-       <string>APPL</string>
-       <key>CFBundleShortVersionString</key>
-       <string>0.6.2</string>
-       <key>CFBundleSignature</key>
-       <string>HB##</string>
-       <key>CFBundleVersion</key>
-       <string>0.6.2</string>
-       <key>NSHumanReadableCopyright</key>
-       <string>By Eric Petit &lt;titer@m0k.org&gt;</string>
-       <key>NSMainNibFile</key>
-       <string>MainMenu</string>
-       <key>NSPrincipalClass</key>
-       <string>NSApplication</string>
-</dict>
-</plist>
-";
-               };
-               29B97327FDCFA39411CA2CEA = {
-                       buildActionMask = 2147483647;
-                       files = (
-                               4D6615EA05288C2300A80101,
-                               4D857591052B78E300C39CA9,
-                               4D358C020534A91300D654EB,
-                               4DFDC319054AC84C00151618,
-                       );
-                       isa = PBXHeadersBuildPhase;
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               29B97328FDCFA39411CA2CEA = {
-                       buildActionMask = 2147483647;
-                       files = (
-                               080E96DCFE201CFB7F000001,
-                               089C165EFE840E0CC02AAC07,
-                               4D118406053054CD00C39CA9,
-                       );
-                       isa = PBXResourcesBuildPhase;
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               29B9732BFDCFA39411CA2CEA = {
-                       buildActionMask = 2147483647;
-                       files = (
-                               29B9732CFDCFA39411CA2CEA,
-                               4DF3C8CE052889CD00A80101,
-                               4D857590052B78E300C39CA9,
-                               4D358C030534A91300D654EB,
-                       );
-                       isa = PBXSourcesBuildPhase;
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               29B9732CFDCFA39411CA2CEA = {
-                       fileRef = 29B97316FDCFA39411CA2CEA;
-                       isa = PBXBuildFile;
-                       settings = {
-                               ATTRIBUTES = (
-                               );
-                       };
-               };
-               29B9732DFDCFA39411CA2CEA = {
-                       buildActionMask = 2147483647;
-                       files = (
-                               1058C7A3FEA54F0111CA2CBB,
-                               4DEB2025052B055F00C39CA9,
-                               4DDE9725052B7B2B00C39CA9,
-                       );
-                       isa = PBXFrameworksBuildPhase;
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-//290
-//291
-//292
-//293
-//294
-//4A0
-//4A1
-//4A2
-//4A3
-//4A4
-               4A9504CCFFE6A4B311CA0CBA = {
-                       buildRules = (
-                       );
-                       buildSettings = {
-                               COPY_PHASE_STRIP = NO;
-                               CURRENT_PROJECT_VERSION = "0.6.2";
-                               GCC_DYNAMIC_NO_PIC = YES;
-                               GCC_ENABLE_FIX_AND_CONTINUE = NO;
-                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
-                               GCC_OPTIMIZATION_LEVEL = 3;
-                               LIBRARY_SEARCH_PATHS = ../core;
-                               OPTIMIZATION_CFLAGS = "-O0";
-                               ZERO_LINK = NO;
-                       };
-                       isa = PBXBuildStyle;
-                       name = Development;
-               };
-               4A9504CDFFE6A4B311CA0CBA = {
-                       buildRules = (
-                       );
-                       buildSettings = {
-                               COPY_PHASE_STRIP = YES;
-                               GCC_ENABLE_FIX_AND_CONTINUE = NO;
-                               ZERO_LINK = NO;
-                       };
-                       isa = PBXBuildStyle;
-                       name = Deployment;
-               };
-//4A0
-//4A1
-//4A2
-//4A3
-//4A4
-//4D0
-//4D1
-//4D2
-//4D3
-//4D4
-               4D118405053054CD00C39CA9 = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = image.icns;
-                       path = HandBrake.icns;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4D118406053054CD00C39CA9 = {
-                       fileRef = 4D118405053054CD00C39CA9;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4D358C000534A91300D654EB = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = TargetSizeField.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4D358C010534A91300D654EB = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.objcpp;
-                       path = TargetSizeField.mm;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4D358C020534A91300D654EB = {
-                       fileRef = 4D358C000534A91300D654EB;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4D358C030534A91300D654EB = {
-                       fileRef = 4D358C010534A91300D654EB;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4D6615EA05288C2300A80101 = {
-                       fileRef = 4DF3C8CB052889CD00A80101;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4D85758E052B78E300C39CA9 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.objcpp;
-                       path = PictureGLView.mm;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4D85758F052B78E300C39CA9 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = PictureGLView.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4D857590052B78E300C39CA9 = {
-                       fileRef = 4D85758E052B78E300C39CA9;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4D857591052B78E300C39CA9 = {
-                       fileRef = 4D85758F052B78E300C39CA9;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4DDE9724052B7B2B00C39CA9 = {
-                       fallbackIsa = PBXFileReference;
-                       isa = PBXFrameworkReference;
-                       lastKnownFileType = wrapper.framework;
-                       name = OpenGL.framework;
-                       path = /System/Library/Frameworks/OpenGL.framework;
-                       refType = 0;
-                       sourceTree = "<absolute>";
-               };
-               4DDE9725052B7B2B00C39CA9 = {
-                       fileRef = 4DDE9724052B7B2B00C39CA9;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4DEB2024052B055F00C39CA9 = {
-                       fallbackIsa = PBXFileReference;
-                       isa = PBXFrameworkReference;
-                       lastKnownFileType = wrapper.framework;
-                       name = IOKit.framework;
-                       path = /System/Library/Frameworks/IOKit.framework;
-                       refType = 0;
-                       sourceTree = "<absolute>";
-               };
-               4DEB2025052B055F00C39CA9 = {
-                       fileRef = 4DEB2024052B055F00C39CA9;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4DF3C8CB052889CD00A80101 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = Controller.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4DF3C8CC052889CD00A80101 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.objcpp;
-                       path = Controller.mm;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4DF3C8CE052889CD00A80101 = {
-                       fileRef = 4DF3C8CC052889CD00A80101;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4DFDC318054AC84C00151618 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       name = HandBrake.h;
-                       path = ../core/HandBrake.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4DFDC319054AC84C00151618 = {
-                       fileRef = 4DFDC318054AC84C00151618;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-       };
-       rootObject = 29B97313FDCFA39411CA2CEA;
-}
diff --git a/macosx/HandBrake.xcodeproj/project.pbxproj b/macosx/HandBrake.xcodeproj/project.pbxproj
new file mode 100644 (file)
index 0000000..e733e19
--- /dev/null
@@ -0,0 +1,502 @@
+// !$*UTF8*$!
+{
+       archiveVersion = 1;
+       classes = {
+       };
+       objectVersion = 42;
+       objects = {
+
+/* Begin PBXBuildFile section */
+               4DD93F8F082036E8008E1322 /* Controller.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DF3C8CB052889CD00A80101 /* Controller.h */; };
+               4DD93F90082036E8008E1322 /* PictureGLView.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D85758F052B78E300C39CA9 /* PictureGLView.h */; };
+               4DD93F91082036E8008E1322 /* ScanController.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D86C74F07281F4E007BA979 /* ScanController.h */; };
+               4DD93F92082036E8008E1322 /* PictureController.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D1FD381073D19CE00E46515 /* PictureController.h */; };
+               4DD93F93082036E8008E1322 /* QueueController.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DD27BA507C0065C0023D231 /* QueueController.h */; };
+               4DD93F94082036E8008E1322 /* PrefsController.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DE93A3507F5A2C900F3C78F /* PrefsController.h */; };
+               4DD93F96082036E8008E1322 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 29B97318FDCFA39411CA2CEA /* MainMenu.nib */; };
+               4DD93F97082036E8008E1322 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
+               4DD93F98082036E8008E1322 /* HandBrake.icns in Resources */ = {isa = PBXBuildFile; fileRef = 4D118405053054CD00C39CA9 /* HandBrake.icns */; };
+               4DD93F9A082036E8008E1322 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.mm */; settings = {ATTRIBUTES = (); }; };
+               4DD93F9B082036E8008E1322 /* Controller.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4DF3C8CC052889CD00A80101 /* Controller.mm */; };
+               4DD93F9C082036E8008E1322 /* PictureGLView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4D85758E052B78E300C39CA9 /* PictureGLView.mm */; };
+               4DD93F9D082036E8008E1322 /* ScanController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4D86C74E07281F4E007BA979 /* ScanController.mm */; };
+               4DD93F9E082036E8008E1322 /* PictureController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4D1FD382073D19CE00E46515 /* PictureController.mm */; };
+               4DD93F9F082036E8008E1322 /* QueueController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4DD27BA607C0065C0023D231 /* QueueController.mm */; };
+               4DD93FA0082036E8008E1322 /* PrefsController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4DE93A3607F5A2C900F3C78F /* PrefsController.m */; };
+               4DD93FA2082036E8008E1322 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+               4DD93FA3082036E8008E1322 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DEB2024052B055F00C39CA9 /* IOKit.framework */; };
+               4DD93FA4082036E8008E1322 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DDE9724052B7B2B00C39CA9 /* OpenGL.framework */; };
+               4DE09E63082038A400FB751F /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 4DE09E62082038A400FB751F /* Info.plist */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXBuildStyle section */
+               4A9504CCFFE6A4B311CA0CBA /* Development */ = {
+                       isa = PBXBuildStyle;
+                       buildSettings = {
+                               COPY_PHASE_STRIP = NO;
+                               CURRENT_PROJECT_VERSION = "0.7.0";
+                               GCC_DYNAMIC_NO_PIC = YES;
+                               GCC_ENABLE_FIX_AND_CONTINUE = NO;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+                               GCC_OPTIMIZATION_LEVEL = 3;
+                               GCC_TREAT_WARNINGS_AS_ERRORS = NO;
+                               LIBRARY_SEARCH_PATHS = "";
+                               ZERO_LINK = NO;
+                       };
+                       name = Development;
+               };
+               4A9504CDFFE6A4B311CA0CBA /* Deployment */ = {
+                       isa = PBXBuildStyle;
+                       buildSettings = {
+                               COPY_PHASE_STRIP = YES;
+                               GCC_ENABLE_FIX_AND_CONTINUE = NO;
+                               GCC_TREAT_WARNINGS_AS_ERRORS = NO;
+                               ZERO_LINK = NO;
+                       };
+                       name = Deployment;
+               };
+/* End PBXBuildStyle section */
+
+/* Begin PBXFileReference section */
+               089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+               1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+               29B97316FDCFA39411CA2CEA /* main.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = "<group>"; };
+               29B97319FDCFA39411CA2CEA /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/MainMenu.nib; sourceTree = "<group>"; };
+               29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
+               29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
+               4D118405053054CD00C39CA9 /* HandBrake.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = HandBrake.icns; sourceTree = "<group>"; };
+               4D1FD381073D19CE00E46515 /* PictureController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PictureController.h; sourceTree = "<group>"; };
+               4D1FD382073D19CE00E46515 /* PictureController.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = PictureController.mm; sourceTree = "<group>"; };
+               4D85758E052B78E300C39CA9 /* PictureGLView.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = PictureGLView.mm; sourceTree = "<group>"; };
+               4D85758F052B78E300C39CA9 /* PictureGLView.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PictureGLView.h; sourceTree = "<group>"; };
+               4D86C74E07281F4E007BA979 /* ScanController.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = ScanController.mm; sourceTree = "<group>"; };
+               4D86C74F07281F4E007BA979 /* ScanController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ScanController.h; sourceTree = "<group>"; };
+               4DD27BA507C0065C0023D231 /* QueueController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = QueueController.h; sourceTree = SOURCE_ROOT; };
+               4DD27BA607C0065C0023D231 /* QueueController.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = QueueController.mm; sourceTree = SOURCE_ROOT; };
+               4DD93FA6082036E8008E1322 /* HandBrake.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HandBrake.app; sourceTree = BUILT_PRODUCTS_DIR; };
+               4DDE9724052B7B2B00C39CA9 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = "<absolute>"; };
+               4DE09E62082038A400FB751F /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; path = Info.plist; sourceTree = "<group>"; };
+               4DE93A3507F5A2C900F3C78F /* PrefsController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PrefsController.h; sourceTree = "<group>"; };
+               4DE93A3607F5A2C900F3C78F /* PrefsController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = PrefsController.m; sourceTree = "<group>"; };
+               4DEB2024052B055F00C39CA9 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = "<absolute>"; };
+               4DF3C8CB052889CD00A80101 /* Controller.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Controller.h; sourceTree = "<group>"; };
+               4DF3C8CC052889CD00A80101 /* Controller.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = Controller.mm; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+               4DD93FA1082036E8008E1322 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               4DD93FA2082036E8008E1322 /* Cocoa.framework in Frameworks */,
+                               4DD93FA3082036E8008E1322 /* IOKit.framework in Frameworks */,
+                               4DD93FA4082036E8008E1322 /* OpenGL.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+               080E96DDFE201D6D7F000001 /* Classes */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4D1FD381073D19CE00E46515 /* PictureController.h */,
+                               4D1FD382073D19CE00E46515 /* PictureController.mm */,
+                               4DF3C8CB052889CD00A80101 /* Controller.h */,
+                               4DF3C8CC052889CD00A80101 /* Controller.mm */,
+                               4D86C74E07281F4E007BA979 /* ScanController.mm */,
+                               4D86C74F07281F4E007BA979 /* ScanController.h */,
+                               4D85758E052B78E300C39CA9 /* PictureGLView.mm */,
+                               4D85758F052B78E300C39CA9 /* PictureGLView.h */,
+                               4DD27BA507C0065C0023D231 /* QueueController.h */,
+                               4DD27BA607C0065C0023D231 /* QueueController.mm */,
+                               4DE93A3507F5A2C900F3C78F /* PrefsController.h */,
+                               4DE93A3607F5A2C900F3C78F /* PrefsController.m */,
+                       );
+                       name = Classes;
+                       sourceTree = "<group>";
+               };
+               1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = {
+                       isa = PBXGroup;
+                       children = (
+                               1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */,
+                               4DEB2024052B055F00C39CA9 /* IOKit.framework */,
+                               4DDE9724052B7B2B00C39CA9 /* OpenGL.framework */,
+                       );
+                       name = "Linked Frameworks";
+                       sourceTree = "<group>";
+               };
+               1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = {
+                       isa = PBXGroup;
+                       children = (
+                               29B97325FDCFA39411CA2CEA /* Foundation.framework */,
+                               29B97324FDCFA39411CA2CEA /* AppKit.framework */,
+                       );
+                       name = "Other Frameworks";
+                       sourceTree = "<group>";
+               };
+               19C28FACFE9D520D11CA2CBB /* Products */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4DD93FA6082036E8008E1322 /* HandBrake.app */,
+                       );
+                       name = Products;
+                       sourceTree = "<group>";
+               };
+               29B97314FDCFA39411CA2CEA /* HandBrake */ = {
+                       isa = PBXGroup;
+                       children = (
+                               080E96DDFE201D6D7F000001 /* Classes */,
+                               29B97315FDCFA39411CA2CEA /* Other Sources */,
+                               29B97317FDCFA39411CA2CEA /* Resources */,
+                               29B97323FDCFA39411CA2CEA /* Frameworks */,
+                               19C28FACFE9D520D11CA2CBB /* Products */,
+                               4DE09E62082038A400FB751F /* Info.plist */,
+                       );
+                       name = HandBrake;
+                       sourceTree = "<group>";
+               };
+               29B97315FDCFA39411CA2CEA /* Other Sources */ = {
+                       isa = PBXGroup;
+                       children = (
+                               29B97316FDCFA39411CA2CEA /* main.mm */,
+                       );
+                       name = "Other Sources";
+                       sourceTree = "<group>";
+               };
+               29B97317FDCFA39411CA2CEA /* Resources */ = {
+                       isa = PBXGroup;
+                       children = (
+                               29B97318FDCFA39411CA2CEA /* MainMenu.nib */,
+                               4D118405053054CD00C39CA9 /* HandBrake.icns */,
+                               089C165CFE840E0CC02AAC07 /* InfoPlist.strings */,
+                       );
+                       name = Resources;
+                       sourceTree = "<group>";
+               };
+               29B97323FDCFA39411CA2CEA /* Frameworks */ = {
+                       isa = PBXGroup;
+                       children = (
+                               1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */,
+                               1058C7A2FEA54F0111CA2CBB /* Other Frameworks */,
+                       );
+                       name = Frameworks;
+                       sourceTree = "<group>";
+               };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+               4DD93F8E082036E8008E1322 /* Headers */ = {
+                       isa = PBXHeadersBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               4DD93F8F082036E8008E1322 /* Controller.h in Headers */,
+                               4DD93F90082036E8008E1322 /* PictureGLView.h in Headers */,
+                               4DD93F91082036E8008E1322 /* ScanController.h in Headers */,
+                               4DD93F92082036E8008E1322 /* PictureController.h in Headers */,
+                               4DD93F93082036E8008E1322 /* QueueController.h in Headers */,
+                               4DD93F94082036E8008E1322 /* PrefsController.h in Headers */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+               4DD93F8D082036E8008E1322 /* HandBrake */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 4D4E7BC0087804870051572B /* Build configuration list for PBXNativeTarget "HandBrake" */;
+                       buildPhases = (
+                               4DD93F8E082036E8008E1322 /* Headers */,
+                               4DD93F95082036E8008E1322 /* Resources */,
+                               4DD93F99082036E8008E1322 /* Sources */,
+                               4DD93FA1082036E8008E1322 /* Frameworks */,
+                       );
+                       buildRules = (
+                       );
+                       buildSettings = {
+                               FRAMEWORK_SEARCH_PATHS = "";
+                               GCC_OPTIMIZATION_LEVEL = 3;
+                               GCC_TREAT_WARNINGS_AS_ERRORS = NO;
+                               HEADER_SEARCH_PATHS = ../libhb;
+                               INFOPLIST_FILE = Info.plist;
+                               LIBRARY_SEARCH_PATHS = "";
+                               OTHER_CFLAGS = "";
+                               OTHER_LDFLAGS = (
+                                       ../libhb/libhb.a,
+                                       ../contrib/lib/liba52.a,
+                                       ../contrib/lib/libavcodec.a,
+                                       ../contrib/lib/libavutil.a,
+                                       ../contrib/lib/libdvdread.a,
+                                       ../contrib/lib/libdvdcss.a,
+                                       ../contrib/lib/libfaac.a,
+                                       ../contrib/lib/libmp3lame.a,
+                                       ../contrib/lib/libmp4v2.a,
+                                       ../contrib/lib/libmpeg2.a,
+                                       ../contrib/lib/libvorbis.a,
+                                       ../contrib/lib/libvorbisenc.a,
+                                       ../contrib/lib/libogg.a,
+                                       ../contrib/lib/libsamplerate.a,
+                                       ../contrib/lib/libx264.a,
+                                       ../contrib/lib/libxvidcore.a,
+                               );
+                               PRODUCT_NAME = HandBrake;
+                               SECTORDER_FLAGS = "";
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                               );
+                               WRAPPER_EXTENSION = app;
+                       };
+                       dependencies = (
+                       );
+                       name = HandBrake;
+                       productName = HandBrake;
+                       productReference = 4DD93FA6082036E8008E1322 /* HandBrake.app */;
+                       productType = "com.apple.product-type.application";
+               };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+               29B97313FDCFA39411CA2CEA /* Project object */ = {
+                       isa = PBXProject;
+                       buildConfigurationList = 4D4E7BC4087804870051572B /* Build configuration list for PBXProject "HandBrake" */;
+                       buildSettings = {
+                               MACOSX_DEPLOYMENT_TARGET = 10.3;
+                               SDKROOT = /Developer/SDKs/MacOSX10.3.9.sdk;
+                       };
+                       buildStyles = (
+                               4A9504CCFFE6A4B311CA0CBA /* Development */,
+                               4A9504CDFFE6A4B311CA0CBA /* Deployment */,
+                       );
+                       hasScannedForEncodings = 1;
+                       mainGroup = 29B97314FDCFA39411CA2CEA /* HandBrake */;
+                       projectDirPath = "";
+                       targets = (
+                               4DD93F8D082036E8008E1322 /* HandBrake */,
+                       );
+               };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+               4DD93F95082036E8008E1322 /* Resources */ = {
+                       isa = PBXResourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               4DD93F96082036E8008E1322 /* MainMenu.nib in Resources */,
+                               4DD93F97082036E8008E1322 /* InfoPlist.strings in Resources */,
+                               4DD93F98082036E8008E1322 /* HandBrake.icns in Resources */,
+                               4DE09E63082038A400FB751F /* Info.plist in Resources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+               4DD93F99082036E8008E1322 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               4DD93F9A082036E8008E1322 /* main.mm in Sources */,
+                               4DD93F9B082036E8008E1322 /* Controller.mm in Sources */,
+                               4DD93F9C082036E8008E1322 /* PictureGLView.mm in Sources */,
+                               4DD93F9D082036E8008E1322 /* ScanController.mm in Sources */,
+                               4DD93F9E082036E8008E1322 /* PictureController.mm in Sources */,
+                               4DD93F9F082036E8008E1322 /* QueueController.mm in Sources */,
+                               4DD93FA0082036E8008E1322 /* PrefsController.m in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+               089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = {
+                       isa = PBXVariantGroup;
+                       children = (
+                               089C165DFE840E0CC02AAC07 /* English */,
+                       );
+                       name = InfoPlist.strings;
+                       sourceTree = "<group>";
+               };
+               29B97318FDCFA39411CA2CEA /* MainMenu.nib */ = {
+                       isa = PBXVariantGroup;
+                       children = (
+                               29B97319FDCFA39411CA2CEA /* English */,
+                       );
+                       name = MainMenu.nib;
+                       sourceTree = "<group>";
+               };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+               4D4E7BC1087804870051572B /* Development */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               COPY_PHASE_STRIP = NO;
+                               CURRENT_PROJECT_VERSION = "0.7.0";
+                               FRAMEWORK_SEARCH_PATHS = "";
+                               GCC_DYNAMIC_NO_PIC = YES;
+                               GCC_ENABLE_FIX_AND_CONTINUE = NO;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+                               GCC_OPTIMIZATION_LEVEL = 3;
+                               GCC_TREAT_WARNINGS_AS_ERRORS = NO;
+                               HEADER_SEARCH_PATHS = ../libhb;
+                               INFOPLIST_FILE = Info.plist;
+                               LIBRARY_SEARCH_PATHS = "";
+                               OTHER_CFLAGS = "";
+                               OTHER_LDFLAGS = (
+                                       ../libhb/libhb.a,
+                                       ../contrib/lib/liba52.a,
+                                       ../contrib/lib/libavcodec.a,
+                                       ../contrib/lib/libavutil.a,
+                                       ../contrib/lib/libdvdread.a,
+                                       ../contrib/lib/libdvdcss.a,
+                                       ../contrib/lib/libfaac.a,
+                                       ../contrib/lib/libmp3lame.a,
+                                       ../contrib/lib/libmp4v2.a,
+                                       ../contrib/lib/libmpeg2.a,
+                                       ../contrib/lib/libvorbis.a,
+                                       ../contrib/lib/libvorbisenc.a,
+                                       ../contrib/lib/libogg.a,
+                                       ../contrib/lib/libsamplerate.a,
+                                       ../contrib/lib/libx264.a,
+                                       ../contrib/lib/libxvidcore.a,
+                               );
+                               PRODUCT_NAME = HandBrake;
+                               SECTORDER_FLAGS = "";
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                               );
+                               WRAPPER_EXTENSION = app;
+                               ZERO_LINK = NO;
+                       };
+                       name = Development;
+               };
+               4D4E7BC2087804870051572B /* Deployment */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               COPY_PHASE_STRIP = YES;
+                               FRAMEWORK_SEARCH_PATHS = "";
+                               GCC_ENABLE_FIX_AND_CONTINUE = NO;
+                               GCC_OPTIMIZATION_LEVEL = 3;
+                               GCC_TREAT_WARNINGS_AS_ERRORS = NO;
+                               HEADER_SEARCH_PATHS = ../libhb;
+                               INFOPLIST_FILE = Info.plist;
+                               LIBRARY_SEARCH_PATHS = "";
+                               OTHER_CFLAGS = "";
+                               OTHER_LDFLAGS = (
+                                       ../libhb/libhb.a,
+                                       ../contrib/lib/liba52.a,
+                                       ../contrib/lib/libavcodec.a,
+                                       ../contrib/lib/libavutil.a,
+                                       ../contrib/lib/libdvdread.a,
+                                       ../contrib/lib/libdvdcss.a,
+                                       ../contrib/lib/libfaac.a,
+                                       ../contrib/lib/libmp3lame.a,
+                                       ../contrib/lib/libmp4v2.a,
+                                       ../contrib/lib/libmpeg2.a,
+                                       ../contrib/lib/libvorbis.a,
+                                       ../contrib/lib/libvorbisenc.a,
+                                       ../contrib/lib/libogg.a,
+                                       ../contrib/lib/libsamplerate.a,
+                                       ../contrib/lib/libx264.a,
+                                       ../contrib/lib/libxvidcore.a,
+                               );
+                               PRODUCT_NAME = HandBrake;
+                               SECTORDER_FLAGS = "";
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                               );
+                               WRAPPER_EXTENSION = app;
+                               ZERO_LINK = NO;
+                       };
+                       name = Deployment;
+               };
+               4D4E7BC3087804870051572B /* Default */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               FRAMEWORK_SEARCH_PATHS = "";
+                               GCC_OPTIMIZATION_LEVEL = 3;
+                               GCC_TREAT_WARNINGS_AS_ERRORS = NO;
+                               HEADER_SEARCH_PATHS = ../libhb;
+                               INFOPLIST_FILE = Info.plist;
+                               LIBRARY_SEARCH_PATHS = "";
+                               OTHER_CFLAGS = "";
+                               OTHER_LDFLAGS = (
+                                       ../libhb/libhb.a,
+                                       ../contrib/lib/liba52.a,
+                                       ../contrib/lib/libavcodec.a,
+                                       ../contrib/lib/libavutil.a,
+                                       ../contrib/lib/libdvdread.a,
+                                       ../contrib/lib/libdvdcss.a,
+                                       ../contrib/lib/libfaac.a,
+                                       ../contrib/lib/libmp3lame.a,
+                                       ../contrib/lib/libmp4v2.a,
+                                       ../contrib/lib/libmpeg2.a,
+                                       ../contrib/lib/libvorbis.a,
+                                       ../contrib/lib/libvorbisenc.a,
+                                       ../contrib/lib/libogg.a,
+                                       ../contrib/lib/libsamplerate.a,
+                                       ../contrib/lib/libx264.a,
+                                       ../contrib/lib/libxvidcore.a,
+                               );
+                               PRODUCT_NAME = HandBrake;
+                               SECTORDER_FLAGS = "";
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                               );
+                               WRAPPER_EXTENSION = app;
+                       };
+                       name = Default;
+               };
+               4D4E7BC5087804870051572B /* Development */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                       };
+                       name = Development;
+               };
+               4D4E7BC6087804870051572B /* Deployment */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                       };
+                       name = Deployment;
+               };
+               4D4E7BC7087804870051572B /* Default */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                       };
+                       name = Default;
+               };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+               4D4E7BC0087804870051572B /* Build configuration list for PBXNativeTarget "HandBrake" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               4D4E7BC1087804870051572B /* Development */,
+                               4D4E7BC2087804870051572B /* Deployment */,
+                               4D4E7BC3087804870051572B /* Default */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Default;
+               };
+               4D4E7BC4087804870051572B /* Build configuration list for PBXProject "HandBrake" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               4D4E7BC5087804870051572B /* Development */,
+                               4D4E7BC6087804870051572B /* Deployment */,
+                               4D4E7BC7087804870051572B /* Default */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Default;
+               };
+/* End XCConfigurationList section */
+       };
+       rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
+}
diff --git a/macosx/Info.plist b/macosx/Info.plist
new file mode 100644 (file)
index 0000000..f7df901
--- /dev/null
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>English</string>
+       <key>CFBundleDisplayName</key>
+       <string>HandBrake</string>
+       <key>CFBundleExecutable</key>
+       <string>HandBrake</string>
+       <key>CFBundleGetInfoString</key>
+       <string>0.7.0</string>
+       <key>CFBundleIconFile</key>
+       <string>HandBrake.icns</string>
+       <key>CFBundleIdentifier</key>
+       <string>org.m0k.handbrake</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundleName</key>
+       <string>HandBrake</string>
+       <key>CFBundlePackageType</key>
+       <string>APPL</string>
+       <key>CFBundleShortVersionString</key>
+       <string>0.7.0</string>
+       <key>CFBundleSignature</key>
+       <string>HB##</string>
+       <key>CFBundleVersion</key>
+       <string>2005110400</string>
+       <key>NSHumanReadableCopyright</key>
+       <string>By Eric Petit &lt;titer@m0k.org&gt;</string>
+       <key>NSMainNibFile</key>
+       <string>MainMenu</string>
+       <key>NSPrincipalClass</key>
+       <string>NSApplication</string>
+</dict>
+</plist>
diff --git a/macosx/PictureController.h b/macosx/PictureController.h
new file mode 100644 (file)
index 0000000..3a279e1
--- /dev/null
@@ -0,0 +1,55 @@
+/* $Id: PictureController.h,v 1.6 2005/04/14 20:40:05 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 <Cocoa/Cocoa.h>
+
+#include "hb.h"
+#include "PictureGLView.h"
+
+@interface PictureController : NSObject
+{
+    hb_handle_t              * fHandle;
+    hb_title_t               * fTitle;
+
+    bool                       fHasQE;
+    uint8_t                  * fBuffer;
+    int                        fBufferSize;
+    uint8_t                  * fTexBuf[2];
+    int                        fTexBufSize;
+    int                        fPicture;
+
+    IBOutlet HBPictureGLView * fPictureGLView;
+    IBOutlet NSTextField     * fWidthField;
+    IBOutlet NSStepper       * fWidthStepper;
+    IBOutlet NSTextField     * fHeightField;
+    IBOutlet NSStepper       * fHeightStepper;
+    IBOutlet NSButton        * fRatioCheck;
+    IBOutlet NSMatrix        * fCropMatrix;
+    IBOutlet NSTextField     * fCropTopField;
+    IBOutlet NSStepper       * fCropTopStepper;
+    IBOutlet NSTextField     * fCropBottomField;
+    IBOutlet NSStepper       * fCropBottomStepper;
+    IBOutlet NSTextField     * fCropLeftField;
+    IBOutlet NSStepper       * fCropLeftStepper;
+    IBOutlet NSTextField     * fCropRightField;
+    IBOutlet NSStepper       * fCropRightStepper;
+    IBOutlet NSButton        * fDeinterlaceCheck;
+    IBOutlet NSButton        * fEffectsCheck;
+    IBOutlet NSButton        * fPrevButton;
+    IBOutlet NSButton        * fNextButton;
+    IBOutlet NSTextField     * fInfoField;
+}
+
+- (void) SetHandle: (hb_handle_t *) handle;
+- (void) SetTitle:  (hb_title_t *)  title;
+- (void) Display: (int) anim;
+
+- (IBAction) SettingsChanged: (id) sender;
+- (IBAction) PreviousPicture: (id) sender;
+- (IBAction) NextPicture: (id) sender;
+- (IBAction) ClosePanel: (id) sender;
+
+@end
diff --git a/macosx/PictureController.mm b/macosx/PictureController.mm
new file mode 100644 (file)
index 0000000..f4e9d51
--- /dev/null
@@ -0,0 +1,228 @@
+/* $Id: PictureController.mm,v 1.11 2005/08/01 15:10:44 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 "PictureController.h"
+
+static int GetAlignedSize( int size )
+{
+    int result = 1;
+    while( result < size )
+    {
+        result *= 2;
+    }
+    return result;
+}
+
+@implementation PictureController
+
+- (void) SetHandle: (hb_handle_t *) handle
+{
+    fHandle = handle;
+
+    fHasQE = CGDisplayUsesOpenGLAcceleration( kCGDirectMainDisplay );
+
+    fBuffer     = NULL;
+    fBufferSize = 0;
+    fTexBuf[0]  = NULL;
+    fTexBuf[1]  = NULL;
+    fTexBufSize = 0;
+
+    [fWidthStepper  setValueWraps: NO];
+    [fWidthStepper  setIncrement: 16];
+    [fWidthStepper  setMinValue: 16];
+    [fHeightStepper setValueWraps: NO];
+    [fHeightStepper setIncrement: 16];
+    [fHeightStepper setMinValue: 16];
+
+    [fCropTopStepper    setIncrement: 2];
+    [fCropTopStepper    setMinValue:  0];
+    [fCropBottomStepper setIncrement: 2];
+    [fCropBottomStepper setMinValue:  0];
+    [fCropLeftStepper   setIncrement: 2];
+    [fCropLeftStepper   setMinValue:  0];
+    [fCropRightStepper  setIncrement: 2];
+    [fCropRightStepper  setMinValue:  0];
+}
+
+- (void) SetTitle: (hb_title_t *) title
+{
+    hb_job_t * job = title->job;
+
+    fTitle = title;
+
+    /* Make sure we have big enough buffers */
+    int newSize;
+    newSize = ( title->width + 2 ) * (title->height + 2 ) * 4;
+    if( fBufferSize < newSize )
+    {
+        fBufferSize = newSize;
+        fBuffer     = (uint8_t *) realloc( fBuffer, fBufferSize );
+    }
+    if( !fHasQE )
+    {
+        newSize = ( GetAlignedSize( title->width + 2 ) *
+            GetAlignedSize( title->height + 2 ) * 4 );
+    }
+    if( fTexBufSize < newSize )
+    {
+        fTexBufSize = newSize;
+        fTexBuf[0]  = (uint8_t *) realloc( fTexBuf[0], fTexBufSize );
+        fTexBuf[1]  = (uint8_t *) realloc( fTexBuf[1], fTexBufSize );
+    }
+
+    [fWidthStepper      setMaxValue: title->width];
+    [fWidthStepper      setIntValue: job->width];
+    [fWidthField        setIntValue: job->width];
+    [fHeightStepper     setMaxValue: title->height];
+    [fHeightStepper     setIntValue: job->height];
+    [fHeightField       setIntValue: job->height];
+    [fRatioCheck        setState:    job->keep_ratio ? NSOnState : NSOffState];
+    [fCropTopStepper    setMaxValue: title->height/2-2];
+    [fCropBottomStepper setMaxValue: title->height/2-2];
+    [fCropLeftStepper   setMaxValue: title->width/2-2];
+    [fCropRightStepper  setMaxValue: title->width/2-2];
+    [fDeinterlaceCheck  setState:    job->deinterlace ? NSOnState : NSOffState];
+
+    fPicture = 0;
+    [self SettingsChanged: nil];
+}
+
+- (void) Display: (int) anim
+{
+    hb_get_preview( fHandle, fTitle, fPicture, fBuffer );
+
+    /* Backup previous picture (for effects) */
+    memcpy( fTexBuf[1], fTexBuf[0], fTexBufSize );
+
+    if( fHasQE )
+    {
+        /* Simply copy */
+        memcpy( fTexBuf[0], fBuffer, fTexBufSize );
+    }
+    else
+    {
+        /* Copy line by line */
+        uint8_t * in  = fBuffer;
+        uint8_t * out = fTexBuf[0];
+        for( int i = fTitle->height + 2; i--; )
+        {
+            memcpy( out, in, 4 * ( fTitle->width + 2 ) );
+            in  += 4 * ( fTitle->width + 2 );
+            out += 4 * GetAlignedSize( fTitle->width + 2 );
+        }
+    }
+
+    if( [fEffectsCheck state] == NSOffState )
+    {
+        anim = HB_ANIMATE_NONE;
+    }
+    else if( [[NSApp currentEvent] modifierFlags] & NSShiftKeyMask )
+    {
+        anim |= HB_ANIMATE_SLOW;
+    }
+
+    [fPictureGLView Display: anim buffer1: fTexBuf[0]
+        buffer2: fTexBuf[1] width: ( fTitle->width + 2 )
+        height: ( fTitle->height + 2 )];
+
+    [fInfoField setStringValue: [NSString stringWithFormat:
+        @"Source %dx%d, output %dx%d", fTitle->width, fTitle->height,
+        fTitle->job->width, fTitle->job->height]];
+
+    [fPrevButton setEnabled: ( fPicture > 0 )];
+    [fNextButton setEnabled: ( fPicture < 9 )];
+}
+
+- (IBAction) SettingsChanged: (id) sender
+{
+    hb_job_t * job = fTitle->job;
+
+    job->width       = [fWidthStepper  intValue];
+    job->height      = [fHeightStepper intValue];
+    job->keep_ratio  = ( [fRatioCheck state] == NSOnState );
+    job->deinterlace = ( [fDeinterlaceCheck state] == NSOnState );
+
+    bool autocrop = ( [fCropMatrix selectedRow] == 0 );
+    [fCropTopStepper    setEnabled: !autocrop];
+    [fCropBottomStepper setEnabled: !autocrop];
+    [fCropLeftStepper   setEnabled: !autocrop];
+    [fCropRightStepper  setEnabled: !autocrop];
+    if( autocrop )
+    {
+        memcpy( job->crop, fTitle->crop, 4 * sizeof( int ) );
+    }
+    else
+    {
+        job->crop[0] = [fCropTopStepper    intValue];
+        job->crop[1] = [fCropBottomStepper intValue];
+        job->crop[2] = [fCropLeftStepper   intValue];
+        job->crop[3] = [fCropRightStepper  intValue];
+    }
+
+    if( job->keep_ratio )
+    {
+        if( sender == fWidthStepper || sender == fRatioCheck ||
+            sender == fCropTopStepper || sender == fCropBottomStepper )
+        {
+            hb_fix_aspect( job, HB_KEEP_WIDTH );
+            if( job->height > fTitle->height )
+            {
+                job->height = fTitle->height;
+                hb_fix_aspect( job, HB_KEEP_HEIGHT );
+            }
+        }
+        else
+        {
+            hb_fix_aspect( job, HB_KEEP_HEIGHT );
+            if( job->width > fTitle->width )
+            {
+                job->width = fTitle->width;
+                hb_fix_aspect( job, HB_KEEP_WIDTH );
+            }
+        }
+    }
+    
+    [fWidthStepper      setIntValue: job->width];
+    [fWidthField        setIntValue: job->width];
+    [fHeightStepper     setIntValue: job->height];
+    [fHeightField       setIntValue: job->height];
+    [fCropTopStepper    setIntValue: job->crop[0]];
+    [fCropTopField      setIntValue: job->crop[0]];
+    [fCropBottomStepper setIntValue: job->crop[1]];
+    [fCropBottomField   setIntValue: job->crop[1]];
+    [fCropLeftStepper   setIntValue: job->crop[2]];
+    [fCropLeftField     setIntValue: job->crop[2]];
+    [fCropRightStepper  setIntValue: job->crop[3]];
+    [fCropRightField    setIntValue: job->crop[3]];
+    [self Display: HB_ANIMATE_NONE];
+}
+
+- (IBAction) PreviousPicture: (id) sender
+{   
+    if( fPicture <= 0 )
+    {
+        return;
+    }
+    fPicture--;
+    [self Display: HB_ANIMATE_BACKWARD];
+}
+
+- (IBAction) NextPicture: (id) sender
+{
+    if( fPicture >= 9 )
+    {
+        return;
+    }
+    fPicture++;
+    [self Display: HB_ANIMATE_FORWARD];
+}
+
+- (IBAction) ClosePanel: (id) sender
+{
+    [NSApp stopModal];
+}
+
+@end
index c558c3c..229d822 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: PictureGLView.h,v 1.1.1.1 2003/11/03 12:03:51 titer Exp $
+/* $Id: PictureGLView.h,v 1.7 2005/08/01 15:10:44 titer Exp $
 
    This file is part of the HandBrake source code.
    Homepage: <http://handbrake.m0k.org/>.
@@ -6,29 +6,41 @@
 
 #include <Cocoa/Cocoa.h>
 
-#include "HandBrake.h"
+#include "hb.h"
 
-#define HB_ANIMATE_NONE  0
-#define HB_ANIMATE_LEFT  1
-#define HB_ANIMATE_RIGHT 2
+#define HB_ANIMATE_NONE     1
+#define HB_ANIMATE_BACKWARD 2
+#define HB_ANIMATE_FORWARD  4
+#define HB_ANIMATE_SLOW     8
 
 @interface HBPictureGLView : NSOpenGLView
 
 {
-    HBHandle         * fHandle;
-    HBTitle          * fTitle;
-
-    uint8_t          * fPicture;
-    uint8_t          * fOldPicture;
+    bool            fHasQE;
+    unsigned long   fTarget;
+
+    int             fWidth;
+    int             fHeight;
+    int             fTexWidth;
+    int             fTexHeight;
+    float           fCoordX;
+    float           fCoordY;
+
+    uint8_t       * fBuffers[2];
+    unsigned long   fTextures[2];
+
+    int             fLastEffect;
+    int             fAnimDuration;
+    int             fFrameRate;
 }
 
 - (id) initWithFrame: (NSRect) frame;
 - (void) reshape;
 - (void) drawRect: (NSRect) rect;
-- (void) drawAnimation: (int) how;
+- (void) drawAnimation: (int) anim;
 
-- (void) SetHandle: (HBHandle*) handle;
-- (void) SetTitle: (HBTitle*) title;
-- (void) ShowPicture: (int) index animate: (int) how;
+- (void) Display: (int) anim buffer1: (uint8_t *) buffer1
+    buffer2: (uint8_t *) buffer2 width: (int) width
+    height: (int) height;
 
 @end
index dbb6417..611fb3a 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: PictureGLView.mm,v 1.6 2004/03/08 12:39:49 titer Exp $
+/* $Id: PictureGLView.mm,v 1.18 2005/08/01 15:10:44 titer Exp $
 
    This file is part of the HandBrake source code.
    Homepage: <http://handbrake.m0k.org/>.
 
 #include <OpenGL/OpenGL.h>
 #include <OpenGL/gl.h>
+#include <OpenGL/glext.h>
 #include <math.h>
 
 #include "PictureGLView.h"
 
-#define PROUT 2.5
-
-/* XXX This file needs some serious cleaning XXX */
-
-GLuint    texture[2];
-float     rotation;
-float     translation;
-uint8_t * truc;
-
-@implementation HBPictureGLView
-
-- (void) SetHandle: (HBHandle*) handle
-{
-    fHandle = handle;
-}
-
-- (void) SetTitle: (HBTitle*) title
-{
-    fTitle = title;
-
-    /* This is needed as the view's size may have changed */
-    [self clearGLContext];
-    [self openGLContext];
-}
-
-- (void) ShowPicture: (int) index animate: (int) how
+static int GetAlignedSize( int size )
 {
-    if( fOldPicture ) free( fOldPicture );
-    fOldPicture = fPicture;
-
-    /* Get the picture */
-    uint8_t * tmp = HBGetPreview( fHandle, fTitle, index );
-
-    /* Make it be upside-down */
-    fPicture = (uint8_t*) malloc( 4 * ( fTitle->outWidthMax + 2 ) *
-                                  ( fTitle->outHeightMax + 2 ) );
-    uint8_t * in  = tmp;
-    uint8_t * out = fPicture +
-        4 * ( fTitle->outWidthMax + 2 ) * ( fTitle->outHeightMax + 1 );
-    for( int i = fTitle->outHeightMax + 2; i--; )
-    {
-        memcpy( out, in, 4 * ( fTitle->outWidthMax + 2 ) );
-        in  += 4 * ( fTitle->outWidthMax + 2 );
-        out -= 4 * ( fTitle->outWidthMax + 2 );
-    }
-    free( tmp );
-
-    /* ARGB -> RGBA */
-    uint32_t * p = (uint32_t*) fPicture;
-    for( int i = ( fTitle->outHeightMax + 2 ) *
-            ( fTitle->outWidthMax + 2 ); i--; )
+    int result = 1;
+    while( result < size )
     {
-        *(p++) = ( ( (*p) & 0x00FFFFFF ) << 8 ) | 0xFF;
+        result *= 2;
     }
-
-    if( how == HB_ANIMATE_NONE )
-    {
-        [self drawRect: [self bounds]];
-        return;
-    }
-
-    in  = fOldPicture;
-    out = truc;
-    for( int i = fTitle->outHeightMax + 2; i--;  )
-    {
-        memcpy( out, in, ( fTitle->outWidthMax + 2 ) * 4 );
-        in  += ( fTitle->outWidthMax + 2 ) * 4;
-        out += 1024 * 4;
-    }
-    glBindTexture( GL_TEXTURE_2D, texture[0] );
-    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 1024,
-                  1024, 0, GL_RGBA,
-                  GL_UNSIGNED_BYTE, truc );
-    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
-    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
-
-    in  = fPicture;
-    out = truc;
-    for( int i = fTitle->outHeightMax + 2; i--; )
-    {
-        memcpy( out, in, ( fTitle->outWidthMax + 2 ) * 4 );
-        in  += ( fTitle->outWidthMax + 2 ) * 4;
-        out += 1024 * 4;
-    }
-    glBindTexture( GL_TEXTURE_2D, texture[1] );
-    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 1024,
-                 1024, 0, GL_RGBA,
-                 GL_UNSIGNED_BYTE, truc );
-    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
-    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
-
-    glEnable( GL_TEXTURE_2D );
-    glShadeModel( GL_SMOOTH );
-    glClearColor( 0.0f, 0.0f, 0.0f, 0.5f );
-    glClearDepth( 1.0f );
-    glEnable( GL_DEPTH_TEST );
-    glDepthFunc( GL_LEQUAL );
-    glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
-
-#define ANIMATION_TIME 500000
-#define FRAME_PER_SEC  50
-
-    rotation = 0.0;
-    float w = ( how == HB_ANIMATE_LEFT ) ? 1.0 : -1.0;
-    uint64_t date;
-    int64_t  wait;
-    for( ;; )
-    {
-        date = HBGetDate();
-        translation = - PROUT - cos( rotation * M_PI / 180 ) *
-                             ( 1 + w * tan( rotation * M_PI / 180 ) );
-        [self drawAnimation: how];
-
-        rotation += w * 90 * 1000000 / ANIMATION_TIME / FRAME_PER_SEC;
-        if( w * rotation >= 90.0 )
-        {
-            break;
-        }
-
-        wait = 1000000 / FRAME_PER_SEC - ( HBGetDate() - date );
-        if( wait > 0 )
-        {
-            HBSnooze( wait );
-        }
-    }
-
-    [self drawRect: [self bounds]];
+    return result;
 }
 
+@implementation HBPictureGLView
+
 - (id) initWithFrame: (NSRect) frame
 {
-    fHandle    = NULL;
-    fTitle      = NULL;
-    fPicture    = NULL;
-    fOldPicture = NULL;
+    fHasQE  = CGDisplayUsesOpenGLAcceleration( kCGDirectMainDisplay );
+    fTarget = fHasQE ? GL_TEXTURE_RECTANGLE_EXT : GL_TEXTURE_2D;
+
+    fBuffers[0] = NULL;
+    fBuffers[1] = NULL;
+    fWidth      = 0;
+    fHeight     = 0;
 
+    fLastEffect = -1;
+    
     GLuint attribs[] =
     {
         NSOpenGLPFANoRecovery,
@@ -173,110 +62,368 @@ uint8_t * truc;
     [[self openGLContext] makeCurrentContext];
     [self reshape];
 
-
-    glGenTextures( 2, texture );
-    truc = (uint8_t*) malloc( 1024*1024*4 );
+    glGenTextures( 2, fTextures );
 
     return self;
 }
 
-/*
- * Resize ourself
- */
 - (void) reshape
 {
-   NSRect bounds;
-
-   [[self openGLContext] update];
-   bounds = [self bounds];
-   if( fTitle )
-   {
-       glViewport( 0, 0, fTitle->outWidthMax + 2,
-                   fTitle->outHeightMax + 2 );
-   }
+    NSRect bounds;
+    [[self openGLContext] update];
+    [[self openGLContext] makeCurrentContext];
+    bounds = [self bounds];
+    glViewport( 0, 0, (int) bounds.size.width,
+                (int) bounds.size.height );
 }
 
-- (void) drawAnimation: (int) how
+- (void) drawRect: (NSRect) rect
 {
-    /* Swap buffers only during the vertical retrace of the monitor.
-       http://developer.apple.com/documentation/GraphicsImaging/
-       Conceptual/OpenGL/chap5/chapter_5_section_44.html */
-    long params[] = { 1 };
-    CGLSetParameter( CGLGetCurrentContext(), kCGLCPSwapInterval,
-                     params );
+    [[self openGLContext] makeCurrentContext];
+
+    glDisable( GL_DEPTH_TEST );
+    glDisable( GL_CULL_FACE );
+    glDisable( GL_BLEND );
 
     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+    if( fBuffers[0] )
+    {
+        glMatrixMode( GL_PROJECTION );
+        glLoadIdentity();
+        glMatrixMode( GL_MODELVIEW );
+        glLoadIdentity();
+
+        glEnable( fTarget );
+        glBindTexture( fTarget, fTextures[0] );
+        glTexImage2D( fTarget, 0, GL_RGBA, fTexWidth, fTexHeight, 0,
+                      GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, fBuffers[0] );
+        glTexParameteri( fTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+        glTexParameteri( fTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+
+        glBegin( GL_QUADS );
+        glTexCoord2f( 0.0    , 0.0     ); glVertex2f( -1.0,  1.0 );
+        glTexCoord2f( 0.0    , fCoordY ); glVertex2f( -1.0, -1.0 );
+        glTexCoord2f( fCoordX, fCoordY ); glVertex2f(  1.0, -1.0 );
+        glTexCoord2f( fCoordX, 0.0     ); glVertex2f(  1.0,  1.0 );
+        glEnd();
+    }
+    [[self openGLContext] flushBuffer];
+}
+
+#define FRUSTUM_NEAR   2.5
+#define FRUSTUM_FAR    20.0
+
+- (void) drawCube: (int) anim
+{
+    uint64_t date;
+    float w, rotation, translation;
+    
+    w = ( anim & HB_ANIMATE_BACKWARD ) ? 1.0 : -1.0;
+
+    glEnable( GL_DEPTH_TEST );
+    glEnable( GL_CULL_FACE );
+    glDisable( GL_BLEND );
+
+    for( rotation = 0.0; w * rotation < 90.0;
+         rotation += w * 90 * 1000 / fAnimDuration / fFrameRate )
+    {
+        date = hb_get_date();
+        translation = - FRUSTUM_NEAR - cos( rotation * M_PI / 180 ) *
+            ( 1 + w * tan( rotation * M_PI / 180 ) );
+
+        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+        glMatrixMode( GL_PROJECTION );
+        glLoadIdentity();
+        glFrustum( -1.0, 1.0, -1.0, 1.0, FRUSTUM_NEAR, FRUSTUM_FAR );
+        glMatrixMode( GL_MODELVIEW );
+        glLoadIdentity();
+        glTranslatef( 0.0, 0.0, translation );
+        glRotatef( rotation, 0.0, 1.0, 0.0 );
+     
+        glBindTexture( fTarget, fTextures[0] );
+        glBegin( GL_QUADS );
+        glTexCoord2f( 0.0    , 0.0 );     glVertex3f( -1.0,  1.0, 1.0 );
+        glTexCoord2f( 0.0    , fCoordY ); glVertex3f( -1.0, -1.0, 1.0 );
+        glTexCoord2f( fCoordX, fCoordY ); glVertex3f(  1.0, -1.0, 1.0 );
+        glTexCoord2f( fCoordX, 0.0 );     glVertex3f(  1.0,  1.0, 1.0 );
+        glEnd();
+     
+        glBindTexture( fTarget, fTextures[1] );
+        glBegin( GL_QUADS );
+        if( anim & HB_ANIMATE_FORWARD )
+        {
+            glTexCoord2f( 0.0,    0.0 );     glVertex3f( 1.0,  1.0,  1.0 );
+            glTexCoord2f( 0.0,    fCoordY ); glVertex3f( 1.0, -1.0,  1.0 );
+            glTexCoord2f( fCoordX, fCoordY ); glVertex3f( 1.0, -1.0, -1.0 );
+            glTexCoord2f( fCoordX, 0.0 );     glVertex3f( 1.0,  1.0, -1.0 );
+        }
+        else
+        {
+            glTexCoord2f( 0.0,    0.0 );     glVertex3f( -1.0,  1.0, -1.0 );
+            glTexCoord2f( 0.0,    fCoordY ); glVertex3f( -1.0, -1.0, -1.0 );
+            glTexCoord2f( fCoordX, fCoordY ); glVertex3f( -1.0, -1.0,  1.0 );
+            glTexCoord2f( fCoordX, 0.0 );     glVertex3f( -1.0,  1.0,  1.0 );
+        }
+        glEnd();
+     
+        [[self openGLContext] flushBuffer];
+
+        hb_snooze( 1000 / fFrameRate - ( hb_get_date() - date ) );
+    }
+
+}
+
+- (void) drawSwap: (int) anim
+{
+    uint64_t date;
+    float w, rotation, x, z;
+    
+    w = ( anim & HB_ANIMATE_BACKWARD ) ? 1.0 : -1.0;
+
+    glEnable( GL_DEPTH_TEST );
+    glEnable( GL_CULL_FACE );
+    glDisable( GL_BLEND );
+
     glMatrixMode( GL_PROJECTION );
     glLoadIdentity();
-    glFrustum( -1.0, 1.0, -1.0, 1.0, PROUT, 20.0 );
+    glFrustum( -1.0, 1.0, -1.0, 1.0, FRUSTUM_NEAR, FRUSTUM_FAR );
     glMatrixMode( GL_MODELVIEW );
     glLoadIdentity();
-    glTranslatef( 0.0, 0.0, translation );
-    glRotatef( rotation, 0.0, 1.0, 0.0 );
-    glEnable( GL_POLYGON_SMOOTH );
-    glHint( GL_POLYGON_SMOOTH_HINT, GL_NICEST );
-    glBindTexture( GL_TEXTURE_2D, texture[0] );
-    glBegin( GL_QUADS );
-    glTexCoord2f( 0.0, 0.0 );
-    glVertex3f( -1.0, -1.0,  1.0 );
-    glTexCoord2f( ( 2.0 + fTitle->outWidthMax ) / 1024, 0.0 );
-    glVertex3f(  1.0, -1.0,  1.0 );
-    glTexCoord2f( ( 2.0 + fTitle->outWidthMax ) / 1024,
-                  ( 2.0 + fTitle->outHeightMax ) / 1024 );
-    glVertex3f(  1.0,  1.0,  1.0 );
-    glTexCoord2f( 0.0, ( 2.0 + fTitle->outHeightMax ) / 1024 );
-    glVertex3f( -1.0,  1.0,  1.0 );
-    glEnd();
-    glBindTexture( GL_TEXTURE_2D, texture[1] );
-    glBegin( GL_QUADS );
-    if( how == HB_ANIMATE_RIGHT )
+    glTranslatef( 0.0, 0.0, - FRUSTUM_NEAR - 1.0 );
+
+    for( rotation = 0.0; w * rotation < 180.0;
+         rotation += w * 180 * 1000 / fAnimDuration / fFrameRate )
+    {
+        date = hb_get_date();
+
+        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+        x = 1.1 * sin( rotation * M_PI / 180 );
+        z = cos( rotation * M_PI / 180 );
+
+        glBindTexture( fTarget, fTextures[0] );
+        glBegin( GL_QUADS );
+        glTexCoord2f( 0.0,    0.0 );     glVertex3f( -1.0 + x,  1.0, z );
+        glTexCoord2f( 0.0,    fCoordY ); glVertex3f( -1.0 + x, -1.0, z );
+        glTexCoord2f( fCoordX, fCoordY ); glVertex3f(  1.0 + x, -1.0, z );
+        glTexCoord2f( fCoordX, 0.0 );     glVertex3f(  1.0 + x,  1.0, z );
+        glEnd();
+     
+        glBindTexture( fTarget, fTextures[1] );
+        glBegin( GL_QUADS );
+        glTexCoord2f( 0.0,    0.0 );     glVertex3f( -1.0 - x,  1.0, - z );
+        glTexCoord2f( 0.0,    fCoordY ); glVertex3f( -1.0 - x, -1.0, - z );
+        glTexCoord2f( fCoordX, fCoordY ); glVertex3f(  1.0 - x, -1.0, - z );
+        glTexCoord2f( fCoordX, 0.0 );     glVertex3f(  1.0 - x,  1.0, - z );
+        glEnd();
+     
+        [[self openGLContext] flushBuffer];
+
+        hb_snooze( 1000 / fFrameRate - ( hb_get_date() - date ) );
+    }
+}
+
+- (void) drawFade
+{
+    uint64_t date;
+    float alpha;
+
+    glDisable( GL_DEPTH_TEST );
+    glDisable( GL_CULL_FACE );
+    glEnable( GL_BLEND );
+
+    glMatrixMode( GL_PROJECTION );
+    glLoadIdentity();
+    glMatrixMode( GL_MODELVIEW );
+    glLoadIdentity();
+
+    for( alpha = 0.0; alpha < 1.0;
+         alpha += 1000.0 / fAnimDuration / fFrameRate )
+    {
+        date = hb_get_date();
+
+        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+        glColor4f( 1.0, 1.0, 1.0, 1.0 - alpha );
+        glBlendFunc( GL_SRC_ALPHA, GL_ONE );
+
+        glBindTexture( fTarget, fTextures[0] );
+        glBegin( GL_QUADS );
+        glTexCoord2f( 0.0,    0.0 );     glVertex2f( -1.0,  1.0 );
+        glTexCoord2f( 0.0,    fCoordY ); glVertex2f( -1.0, -1.0 );
+        glTexCoord2f( fCoordX, fCoordY ); glVertex2f(  1.0, -1.0 );
+        glTexCoord2f( fCoordX, 0.0 );     glVertex2f(  1.0,  1.0 );
+        glEnd();
+
+        glColor4f( 1.0, 1.0, 1.0, alpha );
+        glBlendFunc( GL_SRC_ALPHA, GL_ONE );
+
+        glBindTexture( fTarget, fTextures[1] );
+        glBegin( GL_QUADS );
+        glTexCoord2f( 0.0,    0.0 );     glVertex2f( -1.0,  1.0 );
+        glTexCoord2f( 0.0,    fCoordY ); glVertex2f( -1.0, -1.0 );
+        glTexCoord2f( fCoordX, fCoordY ); glVertex2f(  1.0, -1.0 );
+        glTexCoord2f( fCoordX, 0.0 );     glVertex2f(  1.0,  1.0 );
+        glEnd();
+
+        [[self openGLContext] flushBuffer];
+
+        hb_snooze( 1000 / fFrameRate - ( hb_get_date() - date ) );
+    }
+}
+
+- (void) drawSlide: (int) anim
+{
+    uint64_t date;
+    float foo, w;
+    int left, right;
+    if( anim & HB_ANIMATE_FORWARD )
     {
-        glTexCoord2f( 0.0, 0.0 );
-        glVertex3f(  1.0, -1.0,  1.0 );
-        glTexCoord2f( ( 2.0 + fTitle->outWidthMax ) / 1024, 0.0 );
-        glVertex3f(  1.0, -1.0,  -1.0 );
-        glTexCoord2f( ( 2.0 + fTitle->outWidthMax ) / 1024,
-                      ( 2.0 + fTitle->outHeightMax ) / 1024 );
-        glVertex3f(  1.0,  1.0,  -1.0 );
-        glTexCoord2f( 0.0, ( 2.0 + fTitle->outHeightMax ) / 1024 );
-        glVertex3f(  1.0,  1.0,  1.0 );
+        left  = 0;
+        right = 1;
+        w     = 1.0;
     }
     else
     {
-        glTexCoord2f( 0.0, 0.0 );
-        glVertex3f(  -1.0, -1.0, -1.0 );
-        glTexCoord2f( ( 2.0 + fTitle->outWidthMax ) / 1024, 0.0 );
-        glVertex3f(  -1.0, -1.0, 1.0 );
-        glTexCoord2f( ( 2.0 + fTitle->outWidthMax ) / 1024,
-                      ( 2.0 + fTitle->outHeightMax ) / 1024 );
-        glVertex3f(  -1.0,  1.0, 1.0 );
-        glTexCoord2f( 0.0, ( 2.0 + fTitle->outHeightMax ) / 1024 );
-        glVertex3f(  -1.0,  1.0, -1.0 );
+        left  = 1;
+        right = 0;
+        w     = -1.0;
+    }
+
+    glDisable( GL_DEPTH_TEST );
+    glDisable( GL_CULL_FACE );
+    glDisable( GL_BLEND );
+
+    glMatrixMode( GL_PROJECTION );
+    glLoadIdentity();
+    glMatrixMode( GL_MODELVIEW );
+    glLoadIdentity();
+
+    for( foo = w; foo >= -1.0 && foo <= 1.0;
+         foo -= w * 2000.0 / fAnimDuration / fFrameRate )
+    {
+        date = hb_get_date();
+
+        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+        glBindTexture( fTarget, fTextures[left] );
+        glBegin( GL_QUADS );
+        glTexCoord2f( 0.0,    0.0 );     glVertex2f( foo - 2.0,  1.0 );
+        glTexCoord2f( 0.0,    fCoordY ); glVertex2f( foo - 2.0, -1.0 );
+        glTexCoord2f( fCoordX, fCoordY ); glVertex2f( foo,       -1.0 );
+        glTexCoord2f( fCoordX, 0.0 );     glVertex2f( foo,        1.0 );
+        glEnd();
+
+        glBindTexture( fTarget, fTextures[right] );
+        glBegin( GL_QUADS );
+        glTexCoord2f( 0.0,    0.0 );     glVertex2f( foo,        1.0 );
+        glTexCoord2f( 0.0,    fCoordY ); glVertex2f( foo,       -1.0 );
+        glTexCoord2f( fCoordX, fCoordY ); glVertex2f( foo + 2.0, -1.0 );
+        glTexCoord2f( fCoordX, 0.0 );     glVertex2f( foo + 2.0,  1.0 );
+        glEnd();
+
+        [[self openGLContext] flushBuffer];
+
+        hb_snooze( 1000 / fFrameRate - ( hb_get_date() - date ) );
     }
-    glEnd();
-    [[self openGLContext] flushBuffer];
 }
 
-- (void) drawRect: (NSRect) rect
+#undef FRUSTUM_NEAR
+#undef FRUSTUM_FAR
+
+- (void) drawAnimation: (int) anim
+{
+    glEnable( fTarget );
+
+    glBindTexture( fTarget, fTextures[0] );
+    glTexImage2D( fTarget, 0, GL_RGBA, fTexWidth, fTexHeight, 0,
+                  GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, fBuffers[1] );
+    glTexParameteri( fTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+    glTexParameteri( fTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+
+    glBindTexture( fTarget, fTextures[1] );
+    glTexImage2D( fTarget, 0, GL_RGBA, fTexWidth, fTexHeight, 0,
+                  GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, fBuffers[0] );
+    glTexParameteri( fTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+    glTexParameteri( fTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+
+    /* Draw a random animation, just making sure we don't use the same
+       effect two times in a row */
+    int effect;
+    do
+    {
+        effect = hb_get_date() % 4;
+    }
+    while( effect == fLastEffect );
+
+    fAnimDuration = ( anim & HB_ANIMATE_SLOW ) ? 3000 : 600;
+    fFrameRate    = 60.0;
+    
+    switch( effect )
+    {
+        case 0:
+            [self drawCube: anim];
+            break;
+        case 1:
+            [self drawSwap: anim];
+            break;
+        case 2:
+            [self drawFade];
+            break;
+        case 3:
+            [self drawSlide: anim];
+            break;
+    }
+
+    fLastEffect = effect;
+}
+
+- (void) Display: (int) anim buffer1: (uint8_t *) buffer1
+    buffer2: (uint8_t *) buffer2 width: (int) width height: (int) height
 {
-   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+    [[self openGLContext] makeCurrentContext];
 
-   if( !fPicture )
-   {
-       return;
-   }
+    if( width != fWidth || height != fHeight )
+    {
+        fWidth  = width;
+        fHeight = height;
+        if( fHasQE )
+        {
+            fTexWidth  = fWidth;
+            fTexHeight = fHeight;
+            fCoordX    = (float) fWidth;
+            fCoordY    = (float) fHeight;
+        }
+        else
+        {
+            fTexWidth  = GetAlignedSize( fWidth );
+            fTexHeight = GetAlignedSize( fHeight );
+            fCoordX    = (float) fWidth  / (float) fTexWidth;
+            fCoordY    = (float) fHeight / (float) fTexHeight;
+        }
+        [self clearGLContext];
+        [self openGLContext];
+        [self reshape];
+    }
 
-   glDrawPixels( fTitle->outWidthMax + 2,
-                 fTitle->outHeightMax + 2, GL_RGBA,
-                 GL_UNSIGNED_BYTE, fPicture );
+    fBuffers[0] = buffer1;
+    fBuffers[1] = buffer2;
 
-   [[self openGLContext] flushBuffer];
+    /* Swap buffers only during the vertical retrace of the monitor.
+       http://developer.apple.com/documentation/GraphicsImaging/
+       Conceptual/OpenGL/chap5/chapter_5_section_44.html */
+    long params[] = { 1 };
+    CGLSetParameter( CGLGetCurrentContext(), kCGLCPSwapInterval,
+                     params );
+
+    if( !( anim & HB_ANIMATE_NONE ) )
+    {
+        [self drawAnimation: anim];
+    }
+    
+    [self drawRect: [self bounds]];
 }
 
 @end
diff --git a/macosx/PrefsController.h b/macosx/PrefsController.h
new file mode 100644 (file)
index 0000000..cdd960f
--- /dev/null
@@ -0,0 +1,15 @@
+/* PrefsController */
+
+#include <Cocoa/Cocoa.h>
+
+@interface PrefsController : NSObject
+{
+    IBOutlet NSPanel  * fPanel;
+    IBOutlet NSButton * fUpdateCheck;
+}
+
+- (IBAction) OpenPanel:    (id) sender;
+- (IBAction) ClosePanel:   (id) sender;
+- (IBAction) CheckChanged: (id) sender;
+
+@end
diff --git a/macosx/PrefsController.m b/macosx/PrefsController.m
new file mode 100644 (file)
index 0000000..8e7c865
--- /dev/null
@@ -0,0 +1,47 @@
+#import "PrefsController.h"
+
+@implementation PrefsController
+
+- (void) awakeFromNib
+{
+    NSUserDefaults * defaults;
+    NSDictionary   * appDefaults;
+    
+    /* Unless the user specified otherwise, default is to check
+       for update */
+    defaults    = [NSUserDefaults standardUserDefaults];
+    appDefaults = [NSDictionary dictionaryWithObject:@"YES"
+                   forKey:@"CheckForUpdates"];
+    [defaults registerDefaults: appDefaults];
+
+    /* Check or uncheck according to the preferences */
+    [fUpdateCheck setState: [defaults boolForKey:@"CheckForUpdates"] ?
+        NSOnState : NSOffState];
+}
+
+- (IBAction) OpenPanel: (id) sender;
+{
+    [NSApp runModalForWindow: fPanel];
+}
+
+- (IBAction) ClosePanel: (id) sender;
+{
+    [NSApp stopModal];
+    [fPanel orderOut: sender];
+}
+
+- (IBAction) CheckChanged: (id) sender
+{
+    NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
+    
+    if( [fUpdateCheck state] == NSOnState )
+    {
+        [defaults setObject:@"YES" forKey:@"CheckForUpdates"];
+    }
+    else
+    {
+        [defaults setObject:@"NO" forKey:@"CheckForUpdates"];
+    }
+}
+
+@end
diff --git a/macosx/QueueController.h b/macosx/QueueController.h
new file mode 100644 (file)
index 0000000..635adc7
--- /dev/null
@@ -0,0 +1,18 @@
+/* QueueController */
+
+#include <Cocoa/Cocoa.h>
+
+#include "hb.h"
+
+@interface QueueController : NSObject
+{
+    hb_handle_t            * fHandle;
+    IBOutlet NSScrollView  * fScrollView;
+    IBOutlet NSView        * fTaskView;
+}
+
+- (void)     SetHandle: (hb_handle_t *) handle;
+- (IBAction) Update: (id) sender;
+- (IBAction) ClosePanel: (id) sender;
+
+@end
diff --git a/macosx/QueueController.mm b/macosx/QueueController.mm
new file mode 100644 (file)
index 0000000..e775bb3
--- /dev/null
@@ -0,0 +1,120 @@
+#include "QueueController.h"
+
+@implementation QueueController
+
+- (void) SetHandle: (hb_handle_t *) handle
+{
+    fHandle = handle;
+}
+
+- (void) AddTextField: (NSString *) string rect: (NSRect *) rect
+{
+    NSTextField * textField;
+
+    rect->origin.x     = 10;
+    rect->origin.y    -= 17;
+    rect->size.height  = 17;
+    textField = [[NSTextField alloc] initWithFrame: *rect];
+
+    [textField setEditable: NO];
+    [textField setSelectable: NO];
+    [textField setDrawsBackground: NO];
+    [textField setBordered: NO];
+    [textField setStringValue: string];
+
+    [fTaskView addSubview: textField];
+}
+
+- (void) removeTask: (id) sender
+{
+    hb_rem( fHandle, hb_job( fHandle, [sender tag] ) );
+    [self performSelectorOnMainThread: @selector( Update: )
+        withObject: sender waitUntilDone: NO];
+}
+
+- (void) AddButton: (NSRect *) rect tag: (int) tag
+{
+    NSButton * button;
+
+    rect->origin.x     = rect->size.width - 90;
+    rect->origin.y    -= 20;
+    rect->size.width   = 100;
+    rect->size.height  = 20;
+    button = [[NSButton alloc] initWithFrame: *rect];
+    rect->size.width   = rect->origin.x + 90;
+
+    [button setTitle: @"Remove"];
+    [button setBezelStyle: NSRoundedBezelStyle];
+    [button setFont: [NSFont systemFontOfSize:
+        [NSFont systemFontSizeForControlSize: NSSmallControlSize]]];
+    [[button cell] setControlSize: NSSmallControlSize];
+
+    [button setTag: tag];
+    [button setTarget: self];
+    [button setAction: @selector( removeTask: )];
+
+    [fTaskView addSubview: button];
+
+    NSBox * box;
+
+    rect->origin.x     = 15;
+    rect->origin.y    -= 10;
+    rect->size.width  -= 10;
+    rect->size.height  = 1;
+    box = [[NSBox alloc] initWithFrame: *rect];
+    [box setBoxType: NSBoxSeparator];
+    rect->origin.y    -= 10;
+    rect->size.width  += 10;
+
+    [fTaskView addSubview: box];
+}
+
+- (IBAction) Update: (id) sender
+{
+    int i;
+    hb_job_t * j;
+    hb_title_t * title;
+
+    NSSize size = [fScrollView contentSize];
+    int height = MAX( 20 + 125 * hb_count( fHandle ), size.height );
+    [fTaskView setFrame: NSMakeRect(0,0,size.width,height)];
+
+    NSRect rect = NSMakeRect(10,height-10,size.width-20,10);
+
+    NSArray * subviews = [fTaskView subviews];
+    while( [subviews count] > 0 )
+    {
+        [[subviews objectAtIndex: 0]
+            removeFromSuperviewWithoutNeedingDisplay];
+    }
+
+    for( i = 0; i < hb_count( fHandle ); i++ )
+    {
+        j = hb_job( fHandle, i );
+        title = j->title;
+        
+        [self AddTextField: [NSString stringWithFormat:
+            @"DVD: %s", title->dvd] rect: &rect];
+        [self AddTextField: [NSString stringWithFormat:
+            @"Title: %d", title->index] rect: &rect];
+        [self AddTextField: [NSString stringWithFormat:
+            @"Chapters: %d to %d", j->chapter_start, j->chapter_end]
+            rect: &rect];
+        [self AddTextField: [NSString stringWithFormat:
+            @"Pass: %d of %d", MAX( 1, j->pass ), MIN( 2, j->pass + 1 )]
+            rect: &rect];
+        [self AddTextField: [NSString stringWithFormat:
+            @"Destination: %s", j->file] rect: &rect];
+        [self AddButton: &rect tag: i];
+    }
+
+    [fTaskView scrollPoint: NSMakePoint(0,height)];
+    [fTaskView setNeedsDisplay: YES];
+}
+
+- (IBAction) ClosePanel: (id) sender
+{
+    [NSApp stopModal];
+}
+
+@end
diff --git a/macosx/ScanController.h b/macosx/ScanController.h
new file mode 100644 (file)
index 0000000..d038e6e
--- /dev/null
@@ -0,0 +1,47 @@
+/* $Id: ScanController.h,v 1.4 2005/03/21 12:37:32 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 <Cocoa/Cocoa.h>
+
+#include "hb.h"
+
+@interface ScanController : NSObject
+{
+    hb_handle_t                  * fHandle;
+    
+    IBOutlet NSWindow            * fWindow;
+    IBOutlet NSPanel             * fPanel;
+    IBOutlet NSTextField         * fSelectString;
+    IBOutlet NSMatrix            * fMatrix;
+    IBOutlet NSButtonCell        * fDetectedCell;
+    IBOutlet NSPopUpButton       * fDetectedPopUp;
+    IBOutlet NSButtonCell        * fFolderCell;
+    IBOutlet NSTextField         * fFolderField;
+    IBOutlet NSButton            * fBrowseButton;
+    IBOutlet NSTextField         * fStatusField;
+    IBOutlet NSProgressIndicator * fIndicator;
+    IBOutlet NSButton            * fCancelButton;
+    IBOutlet NSButton            * fOpenButton;
+
+    uint64_t                       fLastCheck;
+}
+
+- (void)     TranslateStrings;
+- (void)     SetHandle:     (hb_handle_t *) handle;
+- (void)     DetectDrives:  (NSNotification *) notification;
+- (void)     UpdateUI:      (hb_state_t *) state;
+
+- (IBAction) MatrixChanged: (id) sender;
+- (IBAction) Browse:        (id) sender;
+- (IBAction) Open:          (id) sender;
+- (IBAction) Cancel:        (id) sender;
+
+- (void) Browse2: (id) sender;
+- (void) BrowseDone: (NSOpenPanel *) sheet
+    returnCode: (int) returnCode contextInfo: (void *) contextInfo;
+- (void) BrowseDone2: (id) sender;
+
+@end
diff --git a/macosx/ScanController.mm b/macosx/ScanController.mm
new file mode 100644 (file)
index 0000000..5a40754
--- /dev/null
@@ -0,0 +1,272 @@
+/* $Id: ScanController.mm,v 1.10 2005/04/27 21:05:24 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 <paths.h>
+#include <IOKit/IOKitLib.h>
+#include <IOKit/IOBSD.h>
+#include <IOKit/storage/IOMedia.h>
+#include <IOKit/storage/IODVDMedia.h>
+
+#include "ScanController.h"
+
+#define _(a) NSLocalizedString(a,nil)
+
+@implementation ScanController
+
+- (void) TranslateStrings
+{
+    [fSelectString setStringValue: _( @"Select a DVD:" )];
+    [fDetectedCell setTitle:       _( @"Detected volume" )];
+    [fFolderCell   setTitle:       _( @"DVD Folder / Image" )];
+    [fBrowseButton setTitle:       _( @"Browse" )];
+    [fCancelButton setTitle:       _( @"Cancel" )];
+    [fOpenButton   setTitle:       _( @"Open" )];
+}
+
+- (void) SetHandle: (hb_handle_t *) handle
+{
+    fHandle    = handle;
+    fLastCheck = 0;
+
+    [self TranslateStrings];
+
+    [fStatusField setStringValue: @""];
+}
+
+- (void) DetectDrives: (NSNotification *) notification
+{
+    if( [fMatrix isEnabled] == NO )
+    {
+        /* We're scanning */
+        return;
+    }
+    if( hb_get_date() < fLastCheck + 1000 )
+    {
+        /* Don't check more than every second */
+        return;
+    }
+    fLastCheck = hb_get_date();
+
+    /* Scan DVD drives (stolen from VLC) */
+    io_object_t            next_media;
+    mach_port_t            master_port;
+    kern_return_t          kern_result;
+    io_iterator_t          media_iterator;
+    CFMutableDictionaryRef classes_to_match;
+
+    kern_result = IOMasterPort( MACH_PORT_NULL, &master_port );
+    if( kern_result != KERN_SUCCESS )
+    {
+        return;
+    }
+
+    classes_to_match = IOServiceMatching( kIODVDMediaClass );
+    if( classes_to_match == NULL )
+    {
+        return;
+    }
+
+    CFDictionarySetValue( classes_to_match, CFSTR( kIOMediaEjectableKey ),
+                          kCFBooleanTrue );
+
+    kern_result = IOServiceGetMatchingServices( master_port,
+            classes_to_match, &media_iterator );
+    if( kern_result != KERN_SUCCESS )
+    {
+        return;
+    }
+
+    NSMutableArray * drivesList; 
+    drivesList = [NSMutableArray arrayWithCapacity: 1];
+
+    next_media = IOIteratorNext( media_iterator );
+    if( next_media )
+    {
+        char psz_buf[0x32];
+        size_t dev_path_length;
+        CFTypeRef str_bsd_path;
+        do
+        {
+            str_bsd_path =
+                IORegistryEntryCreateCFProperty( next_media,
+                                                 CFSTR( kIOBSDNameKey ),
+                                                 kCFAllocatorDefault,
+                                                 0 );
+            if( str_bsd_path == NULL )
+            {
+                IOObjectRelease( next_media );
+                continue;
+            }
+
+            snprintf( psz_buf, sizeof(psz_buf), "%s%c", _PATH_DEV, 'r' );
+            dev_path_length = strlen( psz_buf );
+
+            if( CFStringGetCString( (CFStringRef) str_bsd_path,
+                                    (char*)&psz_buf + dev_path_length,
+                                    sizeof(psz_buf) - dev_path_length,
+                                    kCFStringEncodingASCII ) )
+            {
+                [drivesList addObject:
+                    [NSString stringWithCString: psz_buf]];
+            }
+
+            CFRelease( str_bsd_path );
+
+            IOObjectRelease( next_media );
+
+        } while( ( next_media = IOIteratorNext( media_iterator ) ) );
+    }
+
+    IOObjectRelease( media_iterator );
+
+    [fDetectedPopUp removeAllItems];
+    for( unsigned i = 0; i < [drivesList count]; i++ )
+    {
+        [[fDetectedPopUp menu] addItemWithTitle:
+            [drivesList objectAtIndex: i] action: nil
+            keyEquivalent: @""];
+    }
+    [self MatrixChanged: self];
+}
+
+- (void) EnableUI: (bool) b
+{
+    [fMatrix        setEnabled: b];
+    [fDetectedCell  setEnabled: b];
+    [fDetectedPopUp setEnabled: b];
+    [fFolderCell    setEnabled: b];
+    [fFolderField   setEnabled: b];
+    [fBrowseButton  setEnabled: b];
+    [fOpenButton    setEnabled: b];
+
+    if( b )
+    {
+        [self MatrixChanged: nil];
+    }
+}
+
+- (void) UpdateUI: (hb_state_t *) s
+{
+    switch( s->state )
+    {
+#define p s->param.scanning
+        case HB_STATE_SCANNING:
+            [fStatusField setStringValue: [NSString stringWithFormat:
+                _( @"Scanning title %d of %d..." ),
+                p.title_cur, p.title_count]];
+            [fIndicator setDoubleValue: 100.0 * ( p.title_cur - 1 ) /
+                p.title_count];
+            break;
+#undef p
+
+        case HB_STATE_SCANDONE:
+            [self       EnableUI: YES];
+            [fIndicator setDoubleValue: 0.0];
+
+            if( hb_list_count( hb_get_titles( fHandle ) ) )
+            {
+                /* Success */
+                [fStatusField setStringValue: @""];
+                [NSApp abortModal];
+            }
+            else
+            {
+                [fStatusField setStringValue:
+                    _( @"No valid title found." )];
+            }
+            break;
+    }
+}
+
+- (IBAction) MatrixChanged: (id) sender
+{
+    /* Do we have detected drives */
+    if( [fDetectedPopUp numberOfItems] > 0 )
+    {
+        [fDetectedCell setEnabled: YES];
+    }
+    else
+    {
+        [fMatrix       selectCell: fFolderCell];
+        [fDetectedCell setEnabled: NO];
+    }
+    
+    /* Enable controls related to the current choice */
+    bool foo;
+    foo = ( [fMatrix selectedRow] == 0 );
+    [fDetectedPopUp setEnabled:  foo];
+    [fFolderField   setEnabled: !foo];
+    [fBrowseButton  setEnabled: !foo];
+}
+
+/* Browse:
+   Remove the current sheet (the scan panel) and show an OpenPanel.
+   Because we can't open the new sheet before the other one is
+   completely gone, we use performSelectorOnMainThread so it will be
+   done right afterwards */
+- (IBAction) Browse: (id) sender
+{
+    [NSApp stopModal];
+    [self performSelectorOnMainThread: @selector( Browse2: )
+        withObject: nil waitUntilDone: NO];
+}
+- (void) Browse2: (id) sender
+{
+    NSOpenPanel * panel;
+
+    panel = [NSOpenPanel openPanel];
+    [panel setAllowsMultipleSelection: NO];
+    [panel setCanChooseFiles: YES];
+    [panel setCanChooseDirectories: YES ];
+
+    [panel beginSheetForDirectory: nil file: nil types: nil
+        modalForWindow: [NSApp mainWindow] modalDelegate: self
+        didEndSelector: @selector( BrowseDone:returnCode:contextInfo: )
+        contextInfo: nil];
+}
+
+/* Get the folder and switch sheets again. Use the same trick as
+   above */
+- (void) BrowseDone: (NSOpenPanel *) sheet
+    returnCode: (int) returnCode contextInfo: (void *) contextInfo
+{
+    if( returnCode == NSOKButton )
+    {
+        [fFolderField setStringValue:
+            [[sheet filenames] objectAtIndex: 0]];
+        [self Open: nil];
+    }
+    
+    [self performSelectorOnMainThread: @selector( BrowseDone2: )
+        withObject: nil waitUntilDone: NO];
+}
+- (void) BrowseDone2: (id) sender
+{
+    [NSApp beginSheet: fPanel modalForWindow: fWindow
+        modalDelegate: nil didEndSelector: nil contextInfo: nil];
+    [NSApp runModalForWindow: fWindow];
+    [NSApp endSheet: fPanel];
+    [fPanel orderOut: self];
+}
+
+- (IBAction) Open: (id) sender
+{
+    NSString * path;
+    
+    [self         EnableUI: NO];
+    [fStatusField setStringValue: _( @"Opening..." )];
+
+    path = [fMatrix selectedRow] ? [fFolderField stringValue] :
+               [fDetectedPopUp titleOfSelectedItem];
+    hb_scan( fHandle, [path UTF8String], 0 );
+}
+
+- (IBAction) Cancel: (id) sender
+{
+    [NSApp stopModal];
+}
+
+@end
diff --git a/macosx/TargetSizeField.h b/macosx/TargetSizeField.h
deleted file mode 100644 (file)
index d9396ee..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/* $Id: TargetSizeField.h,v 1.3 2004/01/28 14:41:31 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 <Cocoa/Cocoa.h>
-
-#include "HandBrake.h"
-
-@interface HBTargetSizeField : NSTextField
-
-{
-    HBTitle                * fTitle;
-    IBOutlet NSPopUpButton * fRipFormatPopUp;
-    IBOutlet NSTextField   * fRipCustomField;
-    IBOutlet NSPopUpButton * fRipLang2PopUp;
-    IBOutlet NSPopUpButton * fRipAudBitPopUp;
-}
-
-- (void) SetHBTitle: (HBTitle *) title;
-- (void) UpdateBitrate;
-
-@end
diff --git a/macosx/TargetSizeField.mm b/macosx/TargetSizeField.mm
deleted file mode 100644 (file)
index e113a4b..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/* $Id: TargetSizeField.mm,v 1.4 2004/01/28 14:41:31 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 "TargetSizeField.h"
-
-@implementation HBTargetSizeField
-
-- (void) textDidBeginEditing: (NSNotification *) notification
-{
-    [self UpdateBitrate];
-    [super textDidBeginEditing: notification];
-}
-
-- (void) textDidEndEditing: (NSNotification *) notification
-{
-    [self UpdateBitrate];
-    [super textDidEndEditing: notification];
-}
-
-- (void) textDidChange: (NSNotification *) notification
-{
-    [self UpdateBitrate];
-    [super textDidChange: notification];
-}
-
-- (void) SetHBTitle: (HBTitle*) title
-{
-    fTitle = title;
-}
-
-- (void) UpdateBitrate
-{
-    int size   = [self intValue];
-    int format = [fRipFormatPopUp indexOfSelectedItem];
-    int muxer  = ( format == 0 ) ? HB_MUX_MP4 : ( ( format == 1 ) ?
-            HB_MUX_OGM : HB_MUX_AVI );
-    int audioCount = ( [fRipLang2PopUp selectedItem] ==
-            [fRipLang2PopUp lastItem] ) ? 1 : 2;
-    int audioBitrate = [[fRipAudBitPopUp titleOfSelectedItem] intValue];
-
-    [fRipCustomField setIntValue: HBGetBitrateForSize( fTitle, size,
-            muxer, audioCount, audioBitrate )];
-}
-
-@end
index 38da1de..3c32157 100755 (executable)
@@ -1,6 +1,6 @@
 #! /bin/sh
 rm -f genstrings.tmp
-cat Controller.mm | grep -v "^#define.*_(" | \
+cat *.mm | grep -v "^#define.*_(" | \
     sed 's/_( \(@"[^"]*"\) )/NSLocalizedString( \1, nil )/g' > \
     genstrings.tmp
 genstrings genstrings.tmp
index cbad7b5..d2415f3 100644 (file)
Binary files a/macosx/i18n/Localizable.strings and b/macosx/i18n/Localizable.strings differ
index c1218f2..a2841c4 100644 (file)
Binary files a/macosx/i18n/fr.strings and b/macosx/i18n/fr.strings differ
index bd649f8..78f659e 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: main.mm,v 1.1.1.1 2003/11/03 12:03:51 titer Exp $
+/* $Id: main.mm,v 1.2 2004/10/26 20:49:41 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. */
 
-#import <Cocoa/Cocoa.h>
+#include <Cocoa/Cocoa.h>
 
 int main( int argc, const char ** argv )
 {
index 67b9450..3f250bc 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: test.c,v 1.28 2004/03/22 19:18:57 titer Exp $
+/* $Id: test.c,v 1.81 2005/10/15 18:05:03 titer Exp $
 
    This file is part of the HandBrake source code.
    Homepage: <http://handbrake.m0k.org/>.
 #include <signal.h>
 #include <getopt.h>
 
-#include "HandBrake.h"
+#include "hb.h"
 
 /* Options */
-static int    verbose     = 0;
+static int    debug       = HB_DEBUG_NONE;
+static int    update      = 0;
 static char * input       = NULL;
 static char * output      = NULL;
 static char * format      = NULL;
 static int    titleindex  = 1;
 static int    twoPass     = 0;
 static int    deinterlace = 0;
-static int    vcodec      = HB_CODEC_FFMPEG;
+static int    grayscale   = 0;
+static int    vcodec      = HB_VCODEC_FFMPEG;
 static char * audios      = NULL;
+static int    sub         = 0;
 static int    width       = 0;
-static int    top         = 0;
-static int    bottom      = 0;
-static int    left        = 0;
-static int    right       = 0;
-static int    autocrop    = 0;
+static int    height      = 0;
+static int    crop[4]     = { -1,-1,-1,-1 };
 static int    cpu         = 0;
-static int    vbitrate    = 1024;
+static int    vrate       = 0;
+static int    arate       = 0;
+static float  vquality    = -1.0;
+static int    vbitrate    = 0;
 static int    size        = 0;
-static int    abitrate    = 128;
+static int    abitrate    = 0;
 static int    mux         = 0;
 static int    acodec      = 0;
+static int    chapter_start = 0;
+static int    chapter_end   = 0;
 
 /* Exit cleanly on Ctrl-C */
 static volatile int die = 0;
 static void SigHandler( int );
 
 /* Utils */
+static void ShowCommands();
 static void ShowHelp();
 static int  ParseOptions( int argc, char ** argv );
 static int  CheckOptions( int argc, char ** argv );
-
-/* libhb callbacks */
-static void Scanning( void * data, int title, int titleCount );
-static void ScanDone( void * data, HBList * titleList );
-static void Encoding( void * data, float position, int pass,
-                      int passCount, float frameRate,
-                      float avgFrameRate, int remainingTime );
-static void RipDone( void * data, int result );
+static int  HandleEvents( hb_handle_t * h );
 
 int main( int argc, char ** argv )
 {
-    HBHandle    * h;
-    HBCallbacks   callbacks;
-
-    fprintf( stderr, "HandBrake " HB_VERSION
-             " - http://handbrake.m0k.org/\n" );
+    hb_handle_t * h;
+    int           build;
+    char        * version;
 
+    /* Parse command line */
     if( ParseOptions( argc, argv ) ||
         CheckOptions( argc, argv ) )
     {
         return 1;
     }
 
-    /* Exit ASAP on Ctrl-C */
-    signal( SIGINT, SigHandler );
-
     /* Init libhb */
-    h = HBInit( verbose, cpu );
+    h = hb_init( debug, update );
+
+    /* Show version */
+    fprintf( stderr, "HandBrake %s (%d) - http://handbrake.m0k.org/\n",
+             hb_get_version( h ), hb_get_build( h ) );
+
+    /* Check for update */
+    if( update )
+    {
+        if( ( build = hb_check_update( h, &version ) ) > -1 )
+        {
+            fprintf( stderr, "You are using an old version of "
+                     "HandBrake.\nLatest is %s (build %d).\n", version,
+                     build );
+        }
+        else
+        {
+            fprintf( stderr, "Your version of HandBrake is up to "
+                     "date.\n" );
+        }
+        hb_close( &h );
+        return 0;
+    }
 
-    /* Set libhb callbacks */
-    callbacks.data     = h;
-    callbacks.scanning = Scanning;
-    callbacks.scanDone = ScanDone;
-    callbacks.encoding = Encoding;
-    callbacks.ripDone  = RipDone;
-    HBSetCallbacks( h, callbacks );
+    /* Geeky */
+    fprintf( stderr, "%d CPU%s detected\n", hb_get_cpu_count(),
+             hb_get_cpu_count( h ) > 1 ? "s" : "" );
+    if( cpu )
+    {
+        fprintf( stderr, "Forcing %d CPU%s\n", cpu,
+                 cpu > 1 ? "s" : "" );
+        hb_set_cpu_count( h, cpu );
+    }
+
+    /* Exit ASAP on Ctrl-C */
+    signal( SIGINT, SigHandler );
 
     /* Feed libhb with a DVD to scan */
     fprintf( stderr, "Opening %s...\n", input );
-    HBScanDVD( h, input, titleindex );
+    hb_scan( h, input, titleindex );
 
     /* Wait... */
     while( !die )
     {
-        HBSnooze( 500000 );
+#if !defined(SYS_BEOS)
+        fd_set         fds;
+        struct timeval tv;
+        int            ret;
+        char           buf[257];
+
+        tv.tv_sec  = 0;
+        tv.tv_usec = 100000;
+
+        FD_ZERO( &fds );
+        FD_SET( STDIN_FILENO, &fds );
+        ret = select( STDIN_FILENO + 1, &fds, NULL, NULL, &tv );
+
+        if( ret > 0 )
+        {
+            int size = 0;
+
+            while( size < 256 &&
+                   read( STDIN_FILENO, &buf[size], 1 ) > 0 )
+            {
+                if( buf[size] == '\n' )
+                {
+                    break;
+                }
+                size++;
+            }
+
+            if( size >= 256 || buf[size] == '\n' )
+            {
+                switch( buf[0] )
+                {
+                    case 'q':
+                        die = 1;
+                        break;
+                    case 'p':
+                        hb_pause( h );
+                        break;
+                    case 'r':
+                        hb_resume( h );
+                        break;
+                    case 'h':
+                        ShowCommands();
+                        break;
+                }
+            }
+        }
+#else
+        hb_snooze( 200 );
+#endif
+
+        HandleEvents( h );
     }
 
     /* Clean up */
-    HBClose( &h );
+    hb_close( &h );
+    if( input )  free( input );
+    if( output ) free( output );
+    if( format ) free( format );
+    if( audios ) free( audios );
+
+    fprintf( stderr, "HandBrake has exited.\n" );
+
+    return 0;
+}
+
+static void ShowCommands()
+{
+    fprintf( stderr, "Commands:\n" );
+    fprintf( stderr, " [h]elp    Show this message\n" );
+    fprintf( stderr, " [q]uit    Exit HBTest\n" );
+    fprintf( stderr, " [p]ause   Pause encoding\n" );
+    fprintf( stderr, " [r]esume  Resume encoding\n" );
+}
+
+static void PrintTitleInfo( hb_title_t * title )
+{
+    hb_chapter_t  * chapter;
+    hb_audio_t    * audio;
+    hb_subtitle_t * subtitle;
+    int i;
+
+    fprintf( stderr, "+ title %d:\n", title->index );
+    fprintf( stderr, "  + vts %d, ttn %d, cells %d->%d (%d blocks)\n",
+             title->vts, title->ttn, title->cell_start, title->cell_end,
+             title->block_count );
+    fprintf( stderr, "  + duration: %02d:%02d:%02d\n",
+             title->hours, title->minutes, title->seconds );
+    fprintf( stderr, "  + size: %dx%d, aspect: %.2f, %.3f fps\n",
+             title->width, title->height,
+             (float) title->aspect / HB_ASPECT_BASE,
+             (float) title->rate / title->rate_base );
+    fprintf( stderr, "  + autocrop: %d/%d/%d/%d\n", title->crop[0],
+             title->crop[1], title->crop[2], title->crop[3] );
+    fprintf( stderr, "  + chapters:\n" );
+    for( i = 0; i < hb_list_count( title->list_chapter ); i++ )
+    {
+        chapter = hb_list_item( title->list_chapter, i );
+        fprintf( stderr, "    + %d: cells %d->%d, %d blocks, duration "
+                 "%02d:%02d:%02d\n", chapter->index,
+                 chapter->cell_start, chapter->cell_end,
+                 chapter->block_count, chapter->hours, chapter->minutes,
+                 chapter->seconds );
+    }
+    fprintf( stderr, "  + audio tracks:\n" );
+    for( i = 0; i < hb_list_count( title->list_audio ); i++ )
+    {
+        audio = hb_list_item( title->list_audio, i );
+        if( audio->codec & HB_ACODEC_AC3 )
+        {
+            fprintf( stderr, "    + %x, %s, %dHz, %dbps\n", audio->id,
+                     audio->lang, audio->rate, audio->bitrate );
+        }
+        else
+        {
+            fprintf( stderr, "    + %x, %s\n", audio->id, audio->lang );
+        }
+    }
+    fprintf( stderr, "  + subtitle tracks:\n" );
+    for( i = 0; i < hb_list_count( title->list_subtitle ); i++ )
+    {
+        subtitle = hb_list_item( title->list_subtitle, i );
+        fprintf( stderr, "    + %x, %s\n", subtitle->id, subtitle->lang );
+    }
+}
+
+static int HandleEvents( hb_handle_t * h )
+{
+    hb_state_t s;
+    hb_get_state( h, &s );
+    switch( s.state )
+    {
+        case HB_STATE_IDLE:
+            /* Nothing to do */
+            break;
+
+#define p s.param.scanning
+        case HB_STATE_SCANNING:
+            /* Show what title is currently being scanned */
+            fprintf( stderr, "Scanning title %d", p.title_cur );
+            if( !titleindex )
+                fprintf( stderr, " of %d", p.title_count );
+            fprintf( stderr, "...\n" );
+            break;
+#undef p
+
+        case HB_STATE_SCANDONE:
+        {
+            hb_list_t  * list;
+            hb_title_t * title;
+            hb_job_t   * job;
+
+            list = hb_get_titles( h );
+
+            if( !hb_list_count( list ) )
+            {
+                /* No valid title, stop right there */
+                fprintf( stderr, "No title found.\n" );
+                die = 1;
+                break;
+            }
+            if( !titleindex )
+            {
+                /* Scan-only mode, print infos and exit */
+                int i;
+                for( i = 0; i < hb_list_count( list ); i++ )
+                {
+                    title = hb_list_item( list, i );
+                    PrintTitleInfo( title );
+                }
+                die = 1;
+                break;
+            }
+
+            /* Set job settings */
+            title = hb_list_item( list, 0 );
+            job   = title->job;
+
+            PrintTitleInfo( title );
+
+            if( chapter_start && chapter_end )
+            {
+                job->chapter_start = MAX( job->chapter_start,
+                                          chapter_start );
+                job->chapter_end   = MIN( job->chapter_end,
+                                          chapter_end );
+                job->chapter_end   = MAX( job->chapter_start,
+                                          job->chapter_end );
+            }
+
+            if( crop[0] >= 0 && crop[1] >= 0 &&
+                crop[2] >= 0 && crop[3] >= 0 )
+            {
+                memcpy( job->crop, crop, 4 * sizeof( int ) );
+            }
+
+            job->deinterlace = deinterlace;
+            job->grayscale   = grayscale;
+
+            if( width && height )
+            {
+                job->width  = width;
+                job->height = height;
+            }
+            else if( width )
+            {
+                job->width = width;
+                hb_fix_aspect( job, HB_KEEP_WIDTH );
+            }
+            else if( height )
+            {
+                job->height = height;
+                hb_fix_aspect( job, HB_KEEP_HEIGHT );
+            }
+            else
+            {
+                hb_fix_aspect( job, HB_KEEP_WIDTH );
+            }
+
+            if( vquality >= 0.0 && vquality <= 1.0 )
+            {
+                job->vquality = vquality;
+                job->vbitrate = 0;
+            }
+            else if( vbitrate )
+            {
+                job->vquality = -1.0;
+                job->vbitrate = vbitrate;
+            }
+            if( vcodec )
+            {
+                job->vcodec = vcodec;
+            }
+            if( vrate )
+            {
+                job->vrate = 27000000;
+                job->vrate_base = vrate;
+            }
+            if( arate )
+            {
+                job->arate = arate;
+            }
+
+            if( audios )
+            {
+                if( strcasecmp( audios, "none" ) )
+                {
+                    int    audio_count = 0;
+                    char * tmp         = audios;
+                    while( *tmp )
+                    {
+                        if( *tmp < '0' || *tmp > '9' )
+                        {
+                            /* Skip non numeric char */
+                            tmp++;
+                            continue;
+                        }
+                        job->audios[audio_count++] =
+                            strtol( tmp, &tmp, 0 ) - 1;
+                    }
+                    job->audios[audio_count] = -1;
+                }
+                else
+                {
+                    job->audios[0] = -1;
+                }
+            }
+            if( abitrate )
+            {
+                job->abitrate = abitrate;
+            }
+            if( acodec )
+            {
+                job->acodec = acodec;
+            }
+
+            if( size )
+            {
+                job->vbitrate = hb_calc_bitrate( job, size );
+                fprintf( stderr, "Calculated bitrate: %d kbps\n",
+                         job->vbitrate );
+            }
+            
+            if( sub )
+            {
+                job->subtitle = sub - 1;
+            }
+
+            if( job->mux )
+            {
+                job->mux = mux;
+            }
+            job->file = strdup( output );
+
+            if( twoPass )
+            {
+                job->pass = 1;
+                hb_add( h, job );
+                job->pass = 2;
+                hb_add( h, job );
+            }
+            else
+            {
+                job->pass = 0;
+                hb_add( h, job );
+            }
+            hb_start( h );
+            break;
+        }
 
-    fprintf( stderr, "HandBrake has exited cleanly.\n" );
+#define p s.param.working
+        case HB_STATE_WORKING:
+            fprintf( stderr, "\rEncoding: task %d of %d, %.2f %%",
+                     p.job_cur, p.job_count, 100.0 * p.progress );
+            if( p.seconds > -1 )
+            {
+                fprintf( stderr, " (%.2f fps, avg %.2f fps, ETA "
+                         "%02dh%02dm%02ds)", p.rate_cur, p.rate_avg,
+                         p.hours, p.minutes, p.seconds );
+            }
+            break;
+#undef p
 
+#define p s.param.workdone
+        case HB_STATE_WORKDONE:
+            /* Print error if any, then exit */
+            switch( p.error )
+            {
+                case HB_ERROR_NONE:
+                    fprintf( stderr, "\nRip done!\n" );
+                    break;
+                case HB_ERROR_CANCELED:
+                    fprintf( stderr, "\nRip canceled.\n" );
+                    break;
+                default:
+                    fprintf( stderr, "\nRip failed (error %x).\n",
+                             p.error );
+            }
+            die = 1;
+            break;
+#undef p
+    }
     return 0;
 }
 
@@ -103,16 +458,16 @@ void SigHandler( int i_signal )
 {
     if( die == 0 )
     {
-        i_die_date = HBGetDate();
+        die = 1;
+        i_die_date = hb_get_date();
         fprintf( stderr, "Signal %d received, terminating - do it "
                  "again in case it gets stuck\n", i_signal );
     }
-    else if( i_die_date + 500000 < HBGetDate() )
+    else if( i_die_date + 500 < hb_get_date() )
     {
         fprintf( stderr, "Dying badly, files might remain in your /tmp\n" );
         exit( 1 );
     }
-    die = 1;
 }
 
 /****************************************************************************
@@ -120,39 +475,63 @@ void SigHandler( int i_signal )
  ****************************************************************************/
 static void ShowHelp()
 {
+    int i;
+    
     fprintf( stderr,
     "Syntax: HBTest [options] -i <device> -o <file>\n"
     "\n"
-    "    -h, --help            Print help\n"
-    "    -v, --verbose         Be verbose\n"
-    "    -C, --cpu             Set CPU count (default: autodetected)\n"
+    "    -h, --help              Print help\n"
+    "    -u, --update            Check for updates and exit\n"
+    "    -v, --verbose           Be verbose\n"
+    "    -C, --cpu               Set CPU count (default: autodetected)\n"
     "\n"
-    "    -f, --format <string> Set output format (avi/mp4/ogm, default:\n"
-    "                          autodetected)\n"
-    "    -i, --input <string>  Set input device\n"
-    "    -o, --output <string> Set output file name\n"
+    "    -f, --format <string>   Set output format (avi/mp4/ogm, default:\n"
+    "                            autodetected from file name)\n"
+    "    -i, --input <string>    Set input device\n"
+    "    -o, --output <string>   Set output file name\n"
     "\n"
-    "        --scan            Only scan the device\n"
-    "    -t, --title <number>  Select a title to encode (0 to scan only,\n"
-    "                          default: 1)\n"
-    "    -a, --audio <string>  Select audio channel(s) (none for no audio,\n"
-    "                          default: first one)\n"
-    "        --noaudio         Disable audio\n"
+    "    -t, --title <number>    Select a title to encode (0 to scan only,\n"
+    "                            default: 1)\n"
+    "    -c, --chapters <string> Select chapters (e.g. \"1-3\" for chapters\n"
+    "                            1 to 3, or \"3\" for chapter 3 only,\n"
+    "                            default: all chapters)\n"
+    "    -a, --audio <string>    Select audio channel(s) (\"none\" for no \n"
+    "                            audio, default: first one)\n"
     "\n"
-    "    -c, --codec <string>  Set video library encoder (ffmpeg/xvid/x264,\n"
-    "                          default: ffmpeg)\n"
-    "    -2, --two-pass        Use two-pass mode\n"
-    "    -d, --deinterlace     Deinterlace video\n"
+    "    -s, --subtitle <number> Select subtitle (default: none)\n"
+    "    -e, --encoder <string>  Set video library encoder (ffmpeg/xvid/x264,\n"
+    "                            default: ffmpeg)\n"
+    "    -E, --aencoder <string> Set audio encoder (faac/lame/vorbis/ac3, ac3\n"
+    "                            meaning passthrough, default: guessed)\n"
+    "    -2, --two-pass          Use two-pass mode\n"
+    "    -d, --deinterlace       Deinterlace video\n"
+    "    -g, --grayscale         Grayscale encoding\n"
     "\n"
-    "    -b, --vb <kb/s>       Set video bitrate (default: 1024)\n"
-    "    -s, --size <MB>       Set target size instead of bitrate\n"
-    "    -B, --ab <kb/s>       Set audio bitrate (default: 128)\n"
-    "    -w, --width <number>  Set picture width\n"
-    "        --crop <T:B:L:R>  Set cropping values\n"
-    "        --autocrop        Use autodetected cropping values\n" );
+    "    -r, --rate              Set video framerate (" );
+    for( i = 0; i < hb_video_rates_count; i++ )
+    {
+        fprintf( stderr, hb_video_rates[i].string );
+        if( i != hb_video_rates_count - 1 )
+            fprintf( stderr, "/" );
+    }
+    fprintf( stderr, ")\n"
+    "    -R, --arate             Set audio samplerate (" );
+    for( i = 0; i < hb_audio_rates_count; i++ )
+    {
+        fprintf( stderr, hb_audio_rates[i].string );
+        if( i != hb_audio_rates_count - 1 )
+            fprintf( stderr, "/" );
+    }
+    fprintf( stderr, ")\n"
+    "    -b, --vb <kb/s>         Set video bitrate (default: 1000)\n"
+    "    -q, --quality <float>   Set video quality (0.0..1.0)\n"
+    "    -S, --size <MB>         Set target size\n"
+    "    -B, --ab <kb/s>         Set audio bitrate (default: 128)\n"
+    "    -w, --width <number>    Set picture width\n"
+    "    -l, --height <number>   Set picture height\n"
+    "        --crop <T:B:L:R>    Set cropping values (default: autocrop)\n" );
 }
 
-
 /****************************************************************************
  * ParseOptions:
  ****************************************************************************/
@@ -163,6 +542,7 @@ static int ParseOptions( int argc, char ** argv )
         static struct option long_options[] =
           {
             { "help",        no_argument,       NULL,    'h' },
+            { "update",      no_argument,       NULL,    'u' },
             { "verbose",     no_argument,       NULL,    'v' },
             { "cpu",         required_argument, NULL,    'C' },
 
@@ -170,21 +550,26 @@ static int ParseOptions( int argc, char ** argv )
             { "input",       required_argument, NULL,    'i' },
             { "output",      required_argument, NULL,    'o' },
 
-            { "scan",        no_argument,       NULL,    'S' },
             { "title",       required_argument, NULL,    't' },
+            { "chapters",    required_argument, NULL,    'c' },
             { "audio",       required_argument, NULL,    'a' },
-            { "noaudio",     no_argument,       NULL,    'a' },
+            { "subtitle",    required_argument, NULL,    's' },
 
-            { "codec",       required_argument, NULL,    'c' },
+            { "encoder",     required_argument, NULL,    'e' },
+            { "aencoder",    required_argument, NULL,    'E' },
             { "two-pass",    no_argument,       NULL,    '2' },
             { "deinterlace", no_argument,       NULL,    'd' },
+            { "grayscale",   no_argument,       NULL,    'g' },
             { "width",       required_argument, NULL,    'w' },
+            { "height",      required_argument, NULL,    'l' },
             { "crop",        required_argument, NULL,    'n' },
-            { "autocrop",    no_argument,       NULL,    'z' },
 
             { "vb",          required_argument, NULL,    'b' },
-            { "size",        required_argument, NULL,    's' },
+            { "quality",     required_argument, NULL,    'q' },
+            { "size",        required_argument, NULL,    'S' },
             { "ab",          required_argument, NULL,    'B' },
+            { "rate",        required_argument, NULL,    'r' },
+            { "arate",       required_argument, NULL,    'R' },
 
             { 0, 0, 0, 0 }
           };
@@ -192,7 +577,8 @@ static int ParseOptions( int argc, char ** argv )
         int option_index = 0;
         int c;
 
-        c = getopt_long( argc, argv, "hvC:f:i:o:St:a:c:2dw:n:zb:s:B:",
+        c = getopt_long( argc, argv,
+                         "hvuC:f:i:o:t:c:a:s:e:E:2dgw:l:n:b:q:S:B:r:R:",
                          long_options, &option_index );
         if( c < 0 )
         {
@@ -204,8 +590,11 @@ static int ParseOptions( int argc, char ** argv )
             case 'h':
                 ShowHelp();
                 exit( 0 );
+            case 'u':
+                update = 1;
+                break;
             case 'v':
-                verbose = 1;
+                debug = HB_DEBUG_ALL;
                 break;
             case 'C':
                 cpu = atoi( optarg );
@@ -221,14 +610,35 @@ static int ParseOptions( int argc, char ** argv )
                 output = strdup( optarg );
                 break;
 
-            case 'S':
-                titleindex = 0;
-                break;
             case 't':
                 titleindex = atoi( optarg );
                 break;
+            case 'c':
+            {
+                int start, end;
+                if( sscanf( optarg, "%d-%d", &start, &end ) == 2 )
+                {
+                    chapter_start = start;
+                    chapter_end   = end;
+                }
+                else if( sscanf( optarg, "%d", &start ) == 1 )
+                {
+                    chapter_start = start;
+                    chapter_end   = chapter_start;
+                }
+                else
+                {
+                    fprintf( stderr, "chapters: invalid syntax (%s)\n",
+                             optarg );
+                    return -1;
+                }
+                break;
+            }
             case 'a':
-                audios = strdup( optarg ? optarg : "none" );
+                audios = strdup( optarg );
+                break;
+            case 's':
+                sub = atoi( optarg );
                 break;
 
             case '2':
@@ -237,18 +647,21 @@ static int ParseOptions( int argc, char ** argv )
             case 'd':
                 deinterlace = 1;
                 break;
-            case 'c':
+            case 'g':
+                grayscale = 1;
+                break;
+            case 'e':
                 if( !strcasecmp( optarg, "ffmpeg" ) )
                 {
-                    vcodec = HB_CODEC_FFMPEG;
+                    vcodec = HB_VCODEC_FFMPEG;
                 }
                 else if( !strcasecmp( optarg, "xvid" ) )
                 {
-                    vcodec = HB_CODEC_XVID;
+                    vcodec = HB_VCODEC_XVID;
                 }
                 else if( !strcasecmp( optarg, "x264" ) )
                 {
-                    vcodec = HB_CODEC_X264;
+                    vcodec = HB_VCODEC_X264;
                 }
                 else
                 {
@@ -256,42 +669,78 @@ static int ParseOptions( int argc, char ** argv )
                     return -1;
                 }
                 break;
+            case 'E':
+                if( !strcasecmp( optarg, "ac3" ) )
+                {
+                    acodec = HB_ACODEC_AC3;
+                }
+                else if( !strcasecmp( optarg, "lame" ) )
+                {
+                    acodec = HB_ACODEC_LAME;
+                }
+                break;
             case 'w':
                 width = atoi( optarg );
                 break;
+            case 'l':
+                height = atoi( optarg );
+                break;
             case 'n':
             {
-                char * crop = strdup( optarg );
-                char * _2be3 = crop;
-
-                if( *crop )
+                int    i;
+                char * tmp = optarg;
+                for( i = 0; i < 4; i++ )
                 {
-                    top = strtol( crop, &crop, 0 ); crop++;
+                    if( !*tmp )
+                        break;
+                    crop[i] = strtol( tmp, &tmp, 0 );
+                    tmp++;
                 }
-                if( *crop )
+                break;
+            }
+            case 'r':
+            {
+                int i;
+                vrate = 0;
+                for( i = 0; i < hb_video_rates_count; i++ )
                 {
-                    bottom = strtol( crop, &crop, 0 ); crop++;
+                    if( !strcmp( optarg, hb_video_rates[i].string ) )
+                    {
+                        vrate = hb_video_rates[i].rate;
+                        break;
+                    }
                 }
-                if( *crop )
+                if( !vrate )
                 {
-                    left = strtol( crop, &crop, 0 ); crop++;
+                    fprintf( stderr, "invalid framerate %s\n", optarg );
                 }
-                if( *crop )
+                break;
+            }
+            case 'R':
+            {
+                int i;
+                arate = 0;
+                for( i = 0; i < hb_audio_rates_count; i++ )
                 {
-                    right = strtol( crop, &crop, 0 ); crop++;
+                    if( !strcmp( optarg, hb_audio_rates[i].string ) )
+                    {
+                        arate = hb_audio_rates[i].rate;
+                        break;
+                    }
+                }
+                if( !arate )
+                {
+                    fprintf( stderr, "invalid framerate %s\n", optarg );
                 }
-
-                free( _2be3 );
                 break;
             }
-            case 'z':
-               autocrop = 1;
-               break;
-
             case 'b':
                 vbitrate = atoi( optarg );
                 break;
-            case 's':
+            case 'q':
+                vquality = atof( optarg );
+                break;
+            case 'S':
                 size = atoi( optarg );
                 break;
             case 'B':
@@ -309,6 +758,11 @@ static int ParseOptions( int argc, char ** argv )
 
 static int CheckOptions( int argc, char ** argv )
 {
+    if( update )
+    {
+        return 0;
+    }
+
     if( input == NULL || *input == '\0' )
     {
         fprintf( stderr, "Missing input device. Run %s --help for "
@@ -328,7 +782,8 @@ static int CheckOptions( int argc, char ** argv )
 
         if( !format )
         {
-            char *p = strrchr( output, '.' );
+            char * p = strrchr( output, '.' );
+
             /* autodetect */
             if( p && !strcasecmp( p, ".avi" ) )
             {
@@ -343,12 +798,11 @@ static int CheckOptions( int argc, char ** argv )
             {
                 mux = HB_MUX_OGM;
             }
-
             else
             {
                 fprintf( stderr, "Output format couldn't be guessed "
-                         "from file name, please use --format.\n" );
-                return 1;
+                         "from file name, using default.\n" );
+                return 0;
             }
         }
         else if( !strcasecmp( format, "avi" ) )
@@ -370,145 +824,24 @@ static int CheckOptions( int argc, char ** argv )
                      "choices are avi, mp4 and ogm\n.", format );
             return 1;
         }
-        if( mux == HB_MUX_MP4 )
-        {
-            acodec = HB_CODEC_AAC;
-        }
-        else if( mux == HB_MUX_AVI )
-        {
-            acodec = HB_CODEC_MP3;
-        }
-        else if( mux == HB_MUX_OGM )
-        {
-            acodec = HB_CODEC_VORBIS;
-        }
-    }
-
-    return 0;
-}
 
-static void Scanning( void * data, int title, int titleCount )
-{
-    if( titleindex )
-    {
-        fprintf( stderr, "Scanning title %d...\n", title );
-    }
-    else
-    {
-        fprintf( stderr, "Scanning title %d/%d...\n", title, titleCount );
-    }
-}
-
-static void ScanDone( void * data, HBList * titleList )
-{
-    HBHandle * h = (HBHandle*) data;
-    HBAudio  * audio;
-    HBTitle  * title;
-
-    if( !titleList )
-    {
-        fprintf( stderr, "No title found. Invalid device?\n" );
-        die = 1;
-        return;
-    }
-    if( !titleindex )
-    {
-        die = 1;
-        return;
-    }
-
-    title = HBListItemAt( titleList, 0 );
-    title->file = strdup( output );
-    title->twoPass = twoPass;
-    title->deinterlace = deinterlace;
-    if( width )
-    {
-        title->outWidth = width;
-    }
-    if( autocrop )
-    {
-        title->topCrop    = title->autoTopCrop;
-        title->bottomCrop = title->autoBottomCrop;
-        title->leftCrop   = title->autoLeftCrop;
-        title->rightCrop  = title->autoRightCrop;
-    }
-    else
-    {
-        title->topCrop    = top;
-        title->bottomCrop = bottom;
-        title->leftCrop   = left;
-        title->rightCrop  = right;
-    }
-    fprintf( stderr, "Cropping: T=%d,B=%d,L=%d,R=%d\n",
-             title->topCrop, title->bottomCrop,
-             title->leftCrop, title->rightCrop );
-    title->bitrate = vbitrate;
-    title->codec = vcodec;
-    title->mux = mux;
-
-    if( audios == NULL )
-    {
-        audio = HBListItemAt( title->audioList, 0 );
-        audio->outBitrate = abitrate;
-        audio->outCodec = acodec;
-        HBListAdd( title->ripAudioList, audio );
-    }
-    else if( strcasecmp( audios, "none" ) )
-    {
-        char *tmp = audios;
-
-        while( *tmp )
+        if( !acodec )
         {
-            int i;
-
-            if( *tmp < '0' || *tmp > '9' )
+            if( mux == HB_MUX_MP4 )
             {
-                /* Skip non numeric char */
-                tmp++;
-                continue;
+                acodec = HB_ACODEC_FAAC;
+            }
+            else if( mux == HB_MUX_AVI )
+            {
+                acodec = HB_ACODEC_LAME;
+            }
+            else if( mux == HB_MUX_OGM )
+            {
+                acodec = HB_ACODEC_VORBIS;
             }
-
-            i = strtol( tmp, &tmp, 0 );
-            audio = HBListItemAt( title->audioList, i - 1 );
-            audio->outBitrate = abitrate;
-            audio->outCodec = acodec;
-            HBListAdd( title->ripAudioList, audio );
         }
     }
-    if( size )
-    {
-        title->bitrate = HBGetBitrateForSize( title, size, title->mux,
-                HBListCount( title->ripAudioList ), abitrate );
-        fprintf( stderr, "Calculated bitrate: %d kbps\n", title->bitrate );
-    }
 
-    HBStartRip( h, title );
-}
-
-static void Encoding( void * data, float position, int pass,
-                      int passCount, float frameRate,
-                      float avgFrameRate, int remainingTime )
-{
-    fprintf( stderr, "%6.2f %% (pass: %d/%d, cur/avg speed: "
-             "%5.2f/%5.2f fps, %02d:%02d:%02d remaining)\n",
-             100.0 * position, pass, passCount, frameRate, avgFrameRate,
-             remainingTime / 3600, ( remainingTime / 60 ) % 60,
-             remainingTime % 60 );
-}
-
-static void RipDone( void * data, int result )
-{
-    switch( result )
-    {
-        case HB_SUCCESS:
-            fprintf( stderr, "Rip done!\n" );
-            break;
-        case HB_CANCELED:
-            fprintf( stderr, "Rip canceled.\n" );
-            break;
-        default:
-            fprintf( stderr, "Rip failed (error %x).\n", result );
-    }
-    die = 1;
+    return 0;
 }
 
diff --git a/wx/hb32x32.xpm b/wx/hb32x32.xpm
new file mode 100644 (file)
index 0000000..baa88bc
--- /dev/null
@@ -0,0 +1,295 @@
+/* XPM */
+static char *hb_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"32 32 257 2",
+"   c #00044C",
+".  c #180F3C",
+"X  c #150C6A",
+"o  c #171465",
+"O  c #4E0A0D",
+"+  c #470D15",
+"@  c #1D1D3E",
+"#  c #670501",
+"$  c #5E080A",
+"%  c #10320A",
+"&  c #003D04",
+"*  c #770105",
+"=  c #0F3412",
+"-  c #511412",
+";  c #431733",
+":  c #29281F",
+">  c #880001",
+",  c #33261E",
+"<  c #442017",
+"1  c #930000",
+"2  c #372C16",
+"3  c #6C1501",
+"4  c #9B0200",
+"5  c #52250F",
+"6  c #631D13",
+"7  c #542225",
+"8  c #432C2A",
+"9  c #005603",
+"0  c #413416",
+"q  c #75124B",
+"w  c #81161A",
+"e  c #A6070B",
+"r  c #2D4034",
+"t  c #3C3837",
+"y  c #144F2E",
+"u  c #443B1C",
+"i  c #961219",
+"p  c #8F161C",
+"a  c #015C2A",
+"s  c #473B23",
+"d  c #393E41",
+"f  c #901B11",
+"g  c #56362E",
+"h  c #195629",
+"j  c #4A3A3C",
+"k  c #4F3E1F",
+"l  c #6D311F",
+"z  c #514118",
+"x  c #3E3B71",
+"c  c #45452D",
+"v  c #403E62",
+"b  c #792F18",
+"n  c #006B27",
+"m  c #3C4652",
+"M  c #5B4215",
+"N  c #424648",
+"B  c #52452C",
+"V  c #634117",
+"C  c #096B33",
+"Z  c #545004",
+"A  c #00732E",
+"S  c #57482A",
+"D  c #146D1C",
+"F  c #524A2F",
+"G  c #007D02",
+"H  c #23623A",
+"J  c #41552E",
+"K  c #644916",
+"L  c #5F4A22",
+"P  c #5D4C28",
+"I  c #B92312",
+"U  c #644C1E",
+"Y  c #007C2F",
+"T  c #59512B",
+"R  c #157139",
+"E  c #5F4C37",
+"W  c #2D654D",
+"Q  c #58523E",
+"!  c #2E6744",
+"~  c #724D16",
+"^  c #515350",
+"/  c #6E501C",
+"(  c #675229",
+")  c #684865",
+"_  c #0F832E",
+"`  c #42634F",
+"'  c #485B71",
+"]  c #009500",
+"[  c #685A22",
+"{  c #755523",
+"}  c #535B62",
+"|  c #76561E",
+" . c #16823A",
+".. c #357337",
+"X. c #CE2F03",
+"o. c #725824",
+"O. c #3C6B54",
+"+. c #575C5E",
+"@. c #71592A",
+"#. c #15882C",
+"$. c #7F571A",
+"%. c #2B7B49",
+"&. c #68595B",
+"*. c #5E5E5C",
+"=. c #7C5B1B",
+"-. c #80514C",
+";. c #00A100",
+":. c #66623F",
+">. c #357853",
+",. c #7B620E",
+"<. c #0E942C",
+"1. c #6A5F4F",
+"2. c #636449",
+"3. c #7F5D25",
+"4. c #845159",
+"5. c #8F5337",
+"6. c #7C6026",
+"7. c #64635C",
+"8. c #984D48",
+"9. c #357E52",
+"0. c #7D612D",
+"q. c #4E7061",
+"w. c #89601C",
+"e. c #717103",
+"r. c #626667",
+"t. c #7C6334",
+"y. c #7C633A",
+"u. c #786442",
+"i. c #746354",
+"p. c #6C6469",
+"a. c #856525",
+"s. c #89661F",
+"d. c #636B72",
+"f. c #836933",
+"g. c #72732F",
+"h. c #86692F",
+"j. c #716B5E",
+"k. c #766863",
+"l. c #806754",
+"z. c #5F6F84",
+"x. c #877302",
+"c. c #527C63",
+"v. c #6A6E6E",
+"b. c #5C795F",
+"n. c #637085",
+"m. c #BC4675",
+"M. c #946A26",
+"N. c #597B6C",
+"B. c #79714B",
+"V. c #956B1F",
+"C. c #8B6E2C",
+"Z. c #916C2A",
+"A. c #D64A27",
+"S. c #925F75",
+"D. c #1BAB2D",
+"F. c #C14A74",
+"G. c #84743B",
+"H. c #717678",
+"J. c #907239",
+"K. c #8C6B6C",
+"L. c #867452",
+"P. c #757773",
+"I. c #6E7882",
+"U. c #87745A",
+"Y. c #8C7644",
+"T. c #89830E",
+"R. c #867A48",
+"E. c #808329",
+"W. c #7F7A5E",
+"Q. c #6C7B8D",
+"!. c #A17522",
+"~. c #9A7730",
+"^. c #9F762A",
+"/. c #817A75",
+"(. c #6A7F99",
+"). c #88891E",
+"_. c #E45A2B",
+"`. c #20BF2A",
+"'. c #798189",
+"]. c #BD6D43",
+"[. c #A07F35",
+"{. c #81827E",
+"}. c #AA7D2A",
+"|. c #8A8074",
+" X c #AE7E25",
+".X c #987D8D",
+"XX c #AE8430",
+"oX c #AB8838",
+"OX c #868B8D",
+"+X c #998677",
+"@X c #948A7E",
+"#X c #9D8D58",
+"$X c #7D90AE",
+"%X c #A79430",
+"&X c #AC8E4A",
+"*X c #B19517",
+"=X c #BC8C2F",
+"-X c #819A86",
+";X c #7F92B7",
+":X c #7995B8",
+">X c #F76D38",
+",X c #A08E78",
+"<X c #998F8C",
+"1X c #A09B42",
+"2X c #929491",
+"3X c #9C966D",
+"4X c #919499",
+"5X c #9E9476",
+"6X c #809F91",
+"7X c #D48829",
+"8X c #FE628E",
+"9X c #FA7832",
+"0X c #8A99B8",
+"qX c #859DBA",
+"wX c #999B98",
+"eX c #74B486",
+"rX c #91A29B",
+"tX c #A8A263",
+"yX c #999FA5",
+"uX c #CC9B31",
+"iX c #CCA504",
+"pX c #D8887F",
+"aX c #FA8728",
+"sX c #E18971",
+"dX c #C99E42",
+"fX c #C4A23B",
+"gX c #CD9F3C",
+"hX c #A7A9A6",
+"jX c #9EA9C3",
+"kX c #99ACC3",
+"lX c #FB9C1A",
+"zX c #DCA645",
+"xX c #CFA39A",
+"cX c #FAAA05",
+"vX c #BAB971",
+"bX c #F29C75",
+"nX c #DAAD5E",
+"mX c #A9B7CB",
+"MX c #B1B9C1",
+"NX c #FFB904",
+"BX c #FBA873",
+"VX c #E7BE37",
+"CX c #B3C4BD",
+"ZX c #B8C4D4",
+"AX c #D1BFB4",
+"SX c #F1B49D",
+"DX c #FBBF48",
+"FX c #FECC00",
+"GX c #C5CACD",
+"HX c #FCBE8D",
+"JX c #CDCFCB",
+"KX c #C8D2DD",
+"LX c #C0DACB",
+"PX c #FBD5C2",
+"IX c #F7F698",
+"UX c gray100",
+"YX c None",
+/* pixels */
+"YXYXYXS.F.S.YXYXYXYXYXYXYXYXYX{.YXYXYXYXYXYXYXYXYXYXYXYX4XYXYXYX",
+"YXYXYXm.8Xm.YXYXYXYXYXYXYXYXW.1XYXYXYXYXYXYXYXMXYXYXYX} YXYXYXYX",
+"YXYXYX.Xq ) YXYXYXYXYXYXYXH.g.3XYXYXYXYXYXYXYXYXd.YXYXr YXYXYXYX",
+"YXYXYX{.x v j.,X/.YXYX` G 9 & = b.YXYXYXYXYXYXYXq.6XrXO.YXO.yXYX",
+"YXYX/.+X/.AX+Xj.E YXYX'.G ;.;.G ] ..YXYXYXYXH >.6XC ! 9.C q.YXYX",
+"YXYX1.U.Q U.l.i.|.YXYXYX-X% n D b.YXYXYXYXYXYXR A R n n O.LXYXYX",
+"YXYX/.+Xl.5.b &.YXYXYXYXYXT.YXwX/.YXYXYXYXYXYX6X_ <.A Y #.h +.MX",
+"YXYXYXYX-.X.X.8 H.v.H.H.2.E.2.T *X%XYXYXYXYXN.O.C D._ `.A y N.CX",
+"YXYXYXYXYX8 . <XGXyXwXwXT.c vXQ 2.FX#XYXYX6X%.D.A <.D. .a ` YXYX",
+"YXYXYXYX+.k.  +.<Xv.p.*.Z t N +.x.iX5XYXYXYXv.q.#.<.<.#._ a c.LX",
+"YXYXYXd.P.<Xo @ &.j 8 , e.j t s 5 7 YXYXr.u.uXgXQ J D _  .eXYXYX",
+"YXYXYX7 xXp ; X 1 e p ,.V w g IX- $ p.U.gX[.V.^.gXXX&XY.:.6XYXYX",
+"YXYXK.8.xX# - X p i w e.+ $ B IXtX6 < { ~.( ~.0.^.=XF }.h.&XYXYX",
+"YXYX4.sXpX1 > > * * * > > 1 > l tXIXB.P [.J.=.gXP [.XX0.J.J.{.YX",
+"YXYXk.bXpXI 1 4 4 1 1 e I e 1 > f B.R.f.M t.6.oX[.}.=XB XX=XN YX",
+"YXYXYX].PX>X>X1 A.I A.>X_._.e 3 x.0 o.t.Z.C.Y.$.zX( f.dXt.y.U.YX",
+"YXYXYX+XzXBXaXA.>X>X>X>XaX9XA.SX7Xk @.( J.V.f.XXf.J.dX| 6.o.o.YX",
+"YXYXYXYXW.nXDXlXaX9XlXlXcXcXHXnXK s Z.Z.0.3.Z.P  X XP ^.[.Y.h.YX",
+"YXYXYXYXYXYX5XfXFXNXFXFXFXVXG.k L =X( @.s.a. XZ.^.XX=.o.V.~.s YX",
+"YXYXYXYXYXYXYXYX7.[ R.R.T d.P.=.$.f.( !.!.=.w.Z.( a.uXs.s.6.L.YX",
+"YXYXYXYXYXYXYXYXYXI.wXOXI.YX1.| s s.XX{ =.0.@.h.=X3.=.K =.6.U.YX",
+"YXYXYXYXYXYXYXYXYXYXH.P.YXYXd.S { Z.oXB h. X!.( w.k | /  Xs.YXYX",
+"YXYXYXYXYXYXYXYXYXYXv.H.YXYX*.o.$.k 0.=Xf.Z.XXs | U uX0.w.S YXYX",
+"YXYXYXYXYXYXYXYXYXYXH.H.YXYXP./ K =Xf.~ ~.T 0.f. X6.| U s.L.YXYX",
+"YXYXYXYXYXYXYXYXYXYXH.{.YXYXYXS / ~ @.| t.C.!.0.w.L 0.( G.YXYXYX",
+"YXYXYXYXZXmXkXkXmXYXv.4X+.YXYXL.K M.o.t.3.3.a.s h.C.}.XX'.YXYXYX",
+"YXYXkX:X;X;X;X;Xn.m hX4Xr.r.YX{.3.: $.@.t.L C.f.~ @.0.2 kXYXYXYX",
+"mXqX;XqX:X$Xz.+.H.4XGX<X{.4XwXd d ^.k @.L ~ L z S ~.: (.jXYXYXYX",
+"0X$X;X$X:X;X} H.<X{.H.p.v.H.4X<X' P | $.k U { o.K Q ;X0XZXYXYXYX",
+"mX;X$X;X;X;X$Xn.Q.'.I.I.I.n.Q.:X$X;X*.Q P 2 B } z.;XqXZXYXYXYXYX",
+"YXZX0X;X$X;X;X;X;X;X:X;X;X;X;X;X$X$X0XkXjXmXmXmXZXKXYXYXYXYXYXYX",
+"YXYXYXGXmXjXjX0X$XqX;X$XjXjXmXMXmXKXYXYXYXYXYXYXYXYXYXYXYXYXYXYX"
+};
diff --git a/wx/hbWizard.cpp b/wx/hbWizard.cpp
new file mode 100644 (file)
index 0000000..c947306
--- /dev/null
@@ -0,0 +1,1259 @@
+/*****************************************************************************
+ * wxHB:
+ *****************************************************************************
+ * Copyright (C)
+ * $Id: hbWizard.cpp,v 1.4 2005/03/17 19:22:47 titer Exp $
+ *
+ * Authors:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+#include "wxHB.h"
+#include "hbWizard.h"
+
+#include "hb32x32.xpm"
+
+/* All IDs
+ * CB: ComboBox
+ * BT: Button
+ * RD: Radio
+ * NB: NoteBook
+ */
+enum
+{
+    /* Source page */
+    ID_SOURCE_RD_DRIVE = wxID_HIGHEST,
+    ID_SOURCE_RD_DIR,
+    ID_SOURCE_BT_DIR,
+    ID_SOURCE_CB_DRIVE,
+    ID_SOURCE_CB_DIR,
+
+    ID_SOURCE_BT_ABOUT,
+    ID_SOURCE_BT_PREFERENCES,
+
+    /* Settings page */
+    ID_SETTINGS_CB_TITLE = wxID_HIGHEST,
+    ID_SETTINGS_CB_CHAPTER_START,
+    ID_SETTINGS_CB_CHAPTER_END,
+    ID_SETTINGS_CB_AUDIO_LANGUAGE,
+    ID_SETTINGS_CB_AUDIO_QUALITY,
+    ID_SETTINGS_CB_SUBTITLE_LANGUAGE,
+    ID_SETTINGS_CB_VIDEO_QUALITY,
+    ID_SETTINGS_CB_OUTPUT_FILE,
+    ID_SETTINGS_CB_OUTPUT_SIZE,
+    ID_SETTINGS_CB_OUTPUT_BITRATE,
+    ID_SETTINGS_SC_OUTPUT_FILE_COUNT,
+
+    ID_SETTINGS_RD_OUTPUT_SIZE,
+    ID_SETTINGS_RD_OUTPUT_BITRATE,
+
+    ID_SETTINGS_CB_VIDEO_CODEC,
+    ID_SETTINGS_CB_VIDEO_FPS,
+    ID_SETTINGS_CH_VIDEO_DEINTERLACE,
+    ID_SETTINGS_CH_VIDEO_CROP,
+    ID_SETTINGS_SC_VIDEO_CROP_LEFT,
+    ID_SETTINGS_SC_VIDEO_CROP_TOP,
+    ID_SETTINGS_SC_VIDEO_CROP_RIGHT,
+    ID_SETTINGS_SC_VIDEO_CROP_BOTTOM,
+    ID_SETTINGS_SC_VIDEO_WIDTH,
+    ID_SETTINGS_SC_VIDEO_HEIGHT,
+
+    ID_SETTINGS_CB_AUDIO_SAMPLERATE,
+
+    ID_SETTINGS_CB_CPU,
+    ID_SETTINGS_CB_PRIORITY,
+
+    ID_SETTINGS_BT_FILE,
+
+    ID_SETTINGS_NB,
+
+    /* */
+    //ID_ALL_FIXME,
+};
+
+class hbImage: public wxControl
+{
+public:
+    hbImage( wxWindow *parent ) :
+        wxControl( parent, -1, wxDefaultPosition, wxSize(128,128),
+                   wxBORDER_NONE  )
+    {
+    }
+
+    void OnPaint(wxPaintEvent &event)
+    {
+        wxPaintDC dc(this);
+        dc.SetBrush( wxBrush(*wxGREEN, wxSOLID) );
+        dc.DrawText( wxU("Solid green"), 10, 10 );
+    }
+
+private:
+    DECLARE_EVENT_TABLE()
+};
+
+BEGIN_EVENT_TABLE( hbImage, wxControl )
+    EVT_PAINT( hbImage::OnPaint )
+END_EVENT_TABLE()
+
+/*****************************************************************************
+ * hbWizard
+ *****************************************************************************/
+static void hbWizardPageHeaders( wxWizardPageSimple *page,
+                                 char *psz_title,
+                                 char *psz_description,
+                                 wxSizer *sizerC )
+{
+    wxBoxSizer *sizerH = new wxBoxSizer(wxHORIZONTAL);
+
+    wxStaticBitmap *bm = new wxStaticBitmap( page, wxID_ANY,
+                                             wxBitmap(hb_xpm) );
+    wxBoxSizer *sizerV = new wxBoxSizer(wxVERTICAL);
+
+
+    wxStaticText *title = new wxStaticText( page, -1, wxU(psz_title) );
+    wxFont font = title->GetFont();
+    font.SetPointSize(14);
+    title->SetFont( font );
+
+    sizerV->Add( title, 0, wxALIGN_CENTER|wxALL, 5 );
+
+    sizerV->Add( new wxStaticLine(page, -1), 0, wxEXPAND|wxALL, 5 );
+
+    wxStaticText *text =  new wxStaticText( page, -1,
+                                            wxU( psz_description ) );
+    sizerV->Add( text, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 );
+
+    //sizerV->Add( 0, 1, 1, wxALL );
+
+    sizerV->Add( sizerC, 1, wxEXPAND|wxALIGN_CENTER|wxALL, 5 );
+
+
+    /* Add bmp */
+    sizerH->Add( bm, 0, wxALL|wxALIGN_CENTER, 5 );
+    /* Add sizer */
+    sizerH->Add( sizerV, 1, wxEXPAND|wxALIGN_CENTER|wxALL, 5 );
+
+    /* */
+    page->SetSizerAndFit( sizerH );
+
+    /* Needed ? */
+    page->SetAutoLayout( TRUE );
+    page->Layout();
+}
+
+/*****************************************************************************
+ * hbWizardPageSource:
+ *****************************************************************************/
+class hbWizardPageSource: public wxWizardPageSimple
+{
+public:
+    hbWizardPageSource( wxWizard *p_wizard );
+    virtual ~hbWizardPageSource();
+
+
+    void OnRadio( wxCommandEvent &event );
+    void OnBrowseDir( wxCommandEvent &event );
+    void OnTextDirChange( wxCommandEvent &event );
+    void OnTextDriveChange( wxCommandEvent &event );
+    void OnPageChanging( wxWizardEvent &event );
+    
+private:
+
+    wxDirDialog *dlgDir;
+    wxComboBox *comboDir;
+    wxComboBox *comboDrive;
+    wxButton   *buttonDir;
+
+    DECLARE_EVENT_TABLE()
+};
+
+
+hbWizardPageSource::hbWizardPageSource( wxWizard *p_wizard ) :
+                                                 wxWizardPageSimple(p_wizard)
+{
+    wxRadioButton *radio[2];
+    wxFlexGridSizer *sizerDrive;
+    wxFlexGridSizer *sizerDir;
+    wxBoxSizer *sizerH;
+    wxButton *button;
+    
+    /* Create radio and subpanel */
+    radio[0] = new wxRadioButton( this, ID_SOURCE_RD_DRIVE,
+                                  wxU("DVD drive" ) );
+    radio[1] = new wxRadioButton( this, ID_SOURCE_RD_DIR,
+                                  wxU("DVD directory" ) );
+
+    /* - Create DRIVE row */
+    sizerDrive = new wxFlexGridSizer( 1, 1, 20 );
+    /* combo */
+    wxArrayString &sD = *g_hbApp->GetSystemDrive();
+    comboDrive = new wxComboBox( this, ID_SOURCE_CB_DRIVE, sD[0],
+                                 wxDefaultPosition, wxDefaultSize,
+                                 sD );
+    sizerDrive->Add( comboDrive, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
+
+    /* - Create DIR row */
+    sizerDir = new wxFlexGridSizer( 2, 1, 20 );
+    /* combo */
+    comboDir = new wxComboBox( this, ID_SOURCE_CB_DIR,  wxU("") );
+    sizerDir->Add( comboDir, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
+    /* button */
+    buttonDir = new wxButton( this, ID_SOURCE_BT_DIR, wxU("Browse..."));
+    sizerDir->Add( buttonDir,
+                   0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
+
+    /* - Hop in the main */
+    wxFlexGridSizer *sizerChoice = new wxFlexGridSizer( 2, 2, 20 );
+    sizerChoice->Add( radio[0],
+                      0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+    sizerChoice->Add( sizerDrive, 1, wxEXPAND|wxALIGN_LEFT|
+                                     wxALIGN_CENTER_VERTICAL|wxALL, 5  );
+    sizerChoice->Add( radio[1],
+                      0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+    sizerChoice->Add( sizerDir, 1, wxEXPAND|wxALIGN_LEFT|
+                                   wxALIGN_CENTER_VERTICAL|wxALL, 5  );
+
+    wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
+    sizer->Add( sizerChoice, 1,
+                wxEXPAND|wxALIGN_CENTER|wxALL, 5 );
+
+    sizer->Add( 0, 0 );
+
+    sizerH = new wxBoxSizer( wxHORIZONTAL );
+    sizerH->Add( 0, 0, 1 );
+    button = new wxButton( this, ID_SOURCE_BT_ABOUT, wxU("About") );
+    button->Enable(FALSE);
+    sizerH->Add( button, 0, wxALL|wxALIGN_RIGHT, 5 );
+    button = new wxButton( this, ID_SOURCE_BT_PREFERENCES, wxU("Preferences"));
+    button->Enable(FALSE);
+    sizerH->Add( button, 0, wxALL|wxALIGN_RIGHT, 5 );
+
+    sizer->Add( sizerH, 0, wxALIGN_BOTTOM|wxEXPAND, 5 );
+
+    /* */
+#if 0
+    hbImage *img = new hbImage( this );
+    sizer->Add( img );
+#endif
+    
+
+    hbWizardPageHeaders( this, "Source",
+                         "Select the DVD (drive or a directory)", sizer );
+
+    comboDir->Enable( FALSE );
+    buttonDir->Enable( FALSE );
+
+    //SetAutoLayout( TRUE );
+    //Layout();
+
+    /* */
+    dlgDir = NULL;
+}
+
+hbWizardPageSource::~hbWizardPageSource()
+{
+}
+
+void hbWizardPageSource::OnRadio( wxCommandEvent &event )
+{
+    if( event.GetId() == ID_SOURCE_RD_DRIVE )
+    {
+        comboDrive->Enable( TRUE );
+
+        comboDir->Enable( FALSE );
+        buttonDir->Enable( FALSE );
+    }
+    else
+    {
+        comboDir->Enable( TRUE );
+        buttonDir->Enable( TRUE );
+
+        comboDrive->Enable( FALSE );
+    }
+}
+
+void hbWizardPageSource::OnBrowseDir( wxCommandEvent &event )
+{
+    if( dlgDir == NULL )
+        dlgDir = new wxDirDialog( this, wxU( "Choose a directory"),
+                                      wxGetCwd() );
+
+    if( dlgDir->ShowModal() == wxID_OK )
+    {
+        const wxChar *p = dlgDir->GetPath();
+
+        comboDir->SetValue( p );
+    }
+}
+
+void hbWizardPageSource::OnTextDirChange( wxCommandEvent &event )
+{
+}
+void hbWizardPageSource::OnTextDriveChange( wxCommandEvent &event )
+{
+}
+
+void hbWizardPageSource::OnPageChanging( wxWizardEvent &event )
+{
+    wxRadioButton *rdDrive = (wxRadioButton*)FindWindow( ID_SOURCE_RD_DRIVE );
+    wxString sDevice;
+
+    if( rdDrive->GetValue() )
+    {
+        wxComboBox *cbDrive = (wxComboBox*)FindWindow( ID_SOURCE_CB_DRIVE );
+        /* Get the drive value */
+        sDevice = cbDrive->GetValue();
+    }
+    else
+    {
+        wxComboBox *cbDir = (wxComboBox*)FindWindow( ID_SOURCE_CB_DIR );
+        sDevice = cbDir->GetValue();
+
+        if( sDevice.IsEmpty() )
+        {
+            hbError( this, wxU("You have to give a directory name") );
+            event.Veto();
+            return;
+        }
+    }
+
+    if( g_hbApp->Scan( sDevice ) < 0 )
+    {
+        event.Veto();
+    }
+}
+
+
+
+BEGIN_EVENT_TABLE( hbWizardPageSource, wxWizardPageSimple )
+    EVT_RADIOBUTTON( ID_SOURCE_RD_DRIVE, hbWizardPageSource::OnRadio )
+    EVT_RADIOBUTTON( ID_SOURCE_RD_DIR, hbWizardPageSource::OnRadio )
+
+    EVT_BUTTON( ID_SOURCE_BT_DIR, hbWizardPageSource::OnBrowseDir )
+
+    EVT_TEXT( ID_SOURCE_CB_DIR, hbWizardPageSource::OnTextDirChange )
+    EVT_TEXT( ID_SOURCE_CB_DRIVE, hbWizardPageSource::OnTextDriveChange )
+
+    EVT_WIZARD_PAGE_CHANGING( -1, hbWizardPageSource::OnPageChanging )
+END_EVENT_TABLE()
+
+
+/*****************************************************************************
+ * hbWizardPageSettings:
+ *****************************************************************************/
+static wxPanel *PanelSettingsGeneral( wxWindow *p_parent )
+{
+    wxPanel *panel = new wxPanel( p_parent, -1,
+                                  wxDefaultPosition, wxSize(200, 200));
+    wxBoxSizer *sizerV = new wxBoxSizer( wxVERTICAL );
+    wxGridSizer *sizerG;
+    wxBoxSizer *sizerS;
+    wxStaticBox *ibox;
+    wxStaticBoxSizer *sbox;
+    wxFlexGridSizer *sizerF;
+    wxComboBox  *combo;
+    wxButton *button;
+    wxRadioButton *radio;
+    wxSpinCtrl *spin;
+
+    wxArrayString aQ;
+
+    /* Selection (title/chapter) */
+    ibox = new wxStaticBox( panel, -1, wxU("Selection") );
+    sbox  = new wxStaticBoxSizer( ibox, wxHORIZONTAL);
+
+    sbox->Add( new wxStaticText( panel, -1, wxU("Title") ),
+                 0, wxALL, 5 );
+    combo = new wxComboBox( panel, ID_SETTINGS_CB_TITLE, wxU(""),
+                            wxDefaultPosition, wxDefaultSize, 0, NULL,
+                            wxCB_READONLY );
+
+    sbox->Add( combo, 1, wxEXPAND|wxALL, 5 );
+    //sbox->Add( 0, 0, 1 );
+
+    sbox->Add( new wxStaticText( panel, -1, wxU( "Chapters" ) ),
+                 0, wxALL, 5 );
+
+    combo = new wxComboBox( panel, ID_SETTINGS_CB_CHAPTER_START, wxU(""),
+                            wxDefaultPosition, wxDefaultSize, 0, NULL,
+                            wxCB_READONLY );
+    sbox->Add( combo, 0, wxEXPAND|wxALL, 5 );
+
+    sbox->Add( new wxStaticText( panel, -1, wxU( "to" ) ),
+                 0, wxALL, 5 );
+    combo = new wxComboBox( panel, ID_SETTINGS_CB_CHAPTER_END, wxU(""),
+                            wxDefaultPosition, wxDefaultSize, 0, NULL,
+                            wxCB_READONLY );
+
+    sbox->Add( combo, 0, wxEXPAND|wxALL, 5 );
+
+    sizerV->Add( sbox, 1, wxEXPAND|wxALL, 5 );
+
+    /* Sizer for audio + video box */
+    sizerG = new wxGridSizer( 1, 2, 10, 10 );
+
+    /* Audio */
+    ibox = new wxStaticBox( panel, -1, wxU("Audio") );
+    sbox  = new wxStaticBoxSizer( ibox, wxHORIZONTAL);
+
+    sizerF = new wxFlexGridSizer( 2, 2, 20 );
+    sizerF->Add( new wxStaticText( panel, -1, wxU( "Language" ) ),
+                 0, wxALL|wxALIGN_LEFT, 5 );
+    //sbox->Add( 0, 0, 1 );
+    combo = new wxComboBox( panel, ID_SETTINGS_CB_AUDIO_LANGUAGE, wxU(""),
+                            wxDefaultPosition, wxDefaultSize, 0, NULL,
+                            wxCB_READONLY );
+    sizerF->Add( combo, 1, wxEXPAND|wxALL|wxALIGN_RIGHT, 5 );
+    
+    sizerF->Add( new wxStaticText( panel, -1, wxU( "Quality" ) ),
+                 0, wxALL|wxALIGN_LEFT, 5 );
+    //sbox->Add( 0, 0, 1 );
+
+    aQ.Clear();
+    aQ.Add( wxU("Low - 64 kb/s") );
+    aQ.Add( wxU("Normal - 128 kb/s") );
+    aQ.Add( wxU("High - 160 kb/s") );
+    aQ.Add( wxU("Extra - 192 kb/s") );
+
+    combo = new wxComboBox( panel, ID_SETTINGS_CB_AUDIO_QUALITY, aQ[2],
+                            wxDefaultPosition, wxDefaultSize,
+                            aQ, wxCB_READONLY );
+    sizerF->Add( combo, 1, wxEXPAND|wxALL|wxALIGN_RIGHT, 5 );
+
+    sbox->Add( sizerF, 1, wxEXPAND|wxALL, 0 );
+    //sizerV->Add( sbox, 0, wxALL, 5 );
+    sizerG->Add( sbox, 1, wxEXPAND|wxALL, 0 );
+
+    /* Video */
+    ibox = new wxStaticBox( panel, -1, wxU("Video") );
+    sbox  = new wxStaticBoxSizer( ibox, wxHORIZONTAL);
+
+    sizerF = new wxFlexGridSizer( 2, 2, 20 );
+
+    sizerF->Add( new wxStaticText( panel, -1, wxU( "Quality" ) ),
+                 0, wxALL|wxALIGN_LEFT, 5 );
+
+    aQ.Clear();
+    aQ.Add( wxU("Low (fast)") );
+    aQ.Add( wxU("Normal") );
+    aQ.Add( wxU("High (slow)") );
+    combo = new wxComboBox( panel, ID_SETTINGS_CB_VIDEO_QUALITY, aQ[2],
+                            wxDefaultPosition, wxDefaultSize,
+                            aQ, wxCB_READONLY );
+    sizerF->Add( combo, 1, wxEXPAND|wxALL|wxALIGN_RIGHT, 5 );
+
+    sizerF->Add( new wxStaticText( panel, -1, wxU( "Subtitle" ) ),
+                 0, wxALL|wxALIGN_LEFT, 5 );
+    combo = new wxComboBox( panel, ID_SETTINGS_CB_SUBTITLE_LANGUAGE, wxU(""),
+                            wxDefaultPosition, wxDefaultSize, 0, NULL,
+                            wxCB_READONLY );
+    sizerF->Add( combo, 1, wxEXPAND|wxALL|wxALIGN_RIGHT, 5 );
+
+    sbox->Add( sizerF, 0, wxALL, 5 );
+
+    sizerG->Add( sbox, 1, wxEXPAND|wxALL, 0 );
+
+    sizerV->Add( sizerG, 1, wxEXPAND|wxALL, 5 );
+
+    /* Output */
+    ibox = new wxStaticBox( panel, -1, wxU("Output") );
+    sbox  = new wxStaticBoxSizer( ibox, wxVERTICAL);
+
+    sizerF = new wxFlexGridSizer( 3, 1, 20 );
+    sizerF->Add( new wxStaticText( panel, -1, wxU("File") ),
+                     0, wxALL|wxALIGN_LEFT, 5 );
+    combo = new wxComboBox( panel, ID_SETTINGS_CB_OUTPUT_FILE, wxU("") );
+
+    sizerF->Add( combo, 1, wxEXPAND|wxALIGN_RIGHT|
+                           wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+    button = new wxButton( panel, ID_SETTINGS_BT_FILE, wxU("Browse..."));
+    sizerF->Add( button, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+    sbox->Add( sizerF, 0, wxEXPAND|wxALL, 5 );
+
+
+    sizerS = new wxBoxSizer( wxHORIZONTAL );
+
+    sizerF = new wxFlexGridSizer( 2, 2, 20 );
+
+    aQ.Clear();
+    aQ.Add( wxU("800") ); aQ.Add( wxU("700") );
+    aQ.Add( wxU("650") ); aQ.Add( wxU("350") );
+    aQ.Add( wxU("250") ); aQ.Add( wxU("200") );
+    aQ.Add( wxU("150") );
+    radio = new wxRadioButton( panel, ID_SETTINGS_RD_OUTPUT_SIZE, wxU("Size") );
+    combo = new wxComboBox( panel, ID_SETTINGS_CB_OUTPUT_SIZE, wxU(""),
+                            wxDefaultPosition, wxDefaultSize, aQ );
+    sizerF->Add( radio, 0, wxALL|wxALIGN_LEFT );
+    sizerF->Add( combo, 1, wxEXPAND|wxALL|wxALIGN_RIGHT );
+    radio->SetValue( FALSE );
+    combo->Enable( FALSE );
+
+    aQ.Clear();
+    aQ.Add( wxU("2500") ); aQ.Add( wxU("2000") );
+    aQ.Add( wxU("1500") ); aQ.Add( wxU("1000") );
+    aQ.Add( wxU("800") ); aQ.Add( wxU("500") );
+    aQ.Add( wxU("300") );
+    radio = new wxRadioButton( panel, ID_SETTINGS_RD_OUTPUT_BITRATE,
+                               wxU("Bitrate" ) );
+    combo = new wxComboBox( panel, ID_SETTINGS_CB_OUTPUT_BITRATE, aQ[3],
+                            wxDefaultPosition, wxDefaultSize, aQ );
+    sizerF->Add( radio, 0, wxALL|wxALIGN_LEFT );
+    sizerF->Add( combo, 1, wxEXPAND|wxALL|wxALIGN_RIGHT );
+    radio->SetValue( TRUE );
+    combo->Enable( TRUE );
+
+    sizerS->Add( sizerF, 0, wxALL|wxALIGN_CENTER_VERTICAL );
+
+
+    wxBoxSizer *sizerSS = new wxBoxSizer( wxHORIZONTAL );
+    sizerSS->Add( new wxStaticText( panel, -1, wxU( "x" ) ), 0, wxALL, 5 );
+    spin = new wxSpinCtrl( panel, ID_SETTINGS_SC_OUTPUT_FILE_COUNT, wxU("1"),
+                           wxDefaultPosition, wxDefaultSize,
+                           wxSP_ARROW_KEYS, 1, 5, 1 );
+    spin->Enable( FALSE );
+    sizerSS->Add( spin, 0, wxALL, 5 );
+
+    sizerS->Add( sizerSS, 0, wxALL|wxALIGN_CENTER_VERTICAL );
+
+    sbox->Add( sizerS, 1, wxEXPAND|wxALL, 5 );
+
+    sizerV->Add( sbox, 1, wxEXPAND|wxALL, 5 );
+
+    panel->SetSizerAndFit( sizerV );
+
+    return panel;
+}
+
+static wxPanel *PanelSettingsVideo( wxWindow *p_parent )
+{
+    wxPanel *panel = new wxPanel( p_parent, -1,
+                                  wxDefaultPosition, wxSize(200, 200));
+    wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 5, 20 );
+    wxBoxSizer *sizer2;
+    wxBoxSizer *sizer3;
+    wxArrayString aS;
+    wxComboBox *combo;
+    wxCheckBox *check;
+    wxSpinCtrl *spin;
+    int i;
+
+    
+    /* Codec */
+    sizer->Add( new wxStaticText( panel, -1, wxU("Codec") ),
+                1, wxEXPAND|wxALL|wxALIGN_LEFT, 5 );
+    aS.Clear();
+    aS.Add( wxU("FFmpeg") );
+    aS.Add( wxU("XviD") );
+    aS.Add( wxU("x264") );
+    combo = new wxComboBox( panel, ID_SETTINGS_CB_VIDEO_CODEC, aS[0],
+                            wxDefaultPosition, wxDefaultSize,
+                            aS, wxCB_READONLY );
+    sizer->Add( combo, 0, wxALL|wxALIGN_RIGHT, 5 );
+
+    /* FPS */
+    sizer->Add( new wxStaticText( panel, -1, wxU("Fps") ),
+                1, wxEXPAND|wxALL|wxALIGN_LEFT, 5 );
+    aS.Clear();
+    for( i = 0; i < hb_video_rates_count; i++ )
+        aS.Add( wxU(hb_video_rates[i].string) );
+    combo = new wxComboBox( panel, ID_SETTINGS_CB_VIDEO_FPS, wxU(""),
+                            wxDefaultPosition, wxDefaultSize,
+                            aS, wxCB_READONLY );
+    sizer->Add( combo, 0, wxALL|wxALIGN_RIGHT, 5 );
+
+    
+    /* Deinterlace */
+    check = new wxCheckBox( panel, ID_SETTINGS_CH_VIDEO_DEINTERLACE,
+                            wxU("Deinterlace") );
+    check->SetValue( FALSE );
+
+    sizer->Add( check, 1, wxEXPAND|wxALL|wxALIGN_LEFT, 5 );
+    sizer->Add( 0, 0, 0 );
+
+    /* Crop */
+    check = new wxCheckBox( panel, ID_SETTINGS_CH_VIDEO_CROP, wxU("Crop") );
+    check->SetValue( FALSE );
+    sizer->Add( check, 0, wxTOP|wxBOTTOM|
+                          wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
+#if 0
+    sizer2 = new wxBoxSizer( wxVERTICAL );
+    radio = new wxRadioButton( panel, ID_SETTINGS_RD_VIDEO_AUTOCROP,
+                                  wxU("Autocrop" ) );
+    radio->SetValue( TRUE );
+    sizer2->Add( radio, 0, wxTOP|wxBOTTOM|
+                           wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
+    radio = new wxRadioButton( panel, ID_SETTINGS_RD_VIDEO_CUSTOMCROP,
+                                  wxU("Custom crop" ) );
+    radio->SetValue( FALSE );
+    sizer2->Add( radio, 0, wxTOP|wxBOTTOM|
+                           wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
+    sizer->Add( sizer2, 0, wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5 );
+#endif
+
+    sizer2 = new wxBoxSizer( wxVERTICAL);
+    spin = new wxSpinCtrl( panel, ID_SETTINGS_SC_VIDEO_CROP_TOP, wxU(""),
+                           wxDefaultPosition, wxDefaultSize,
+                           wxSP_ARROW_KEYS, 0, 2048, 2 );
+    spin->Enable( FALSE );
+    sizer2->Add( spin, 0, wxALL|wxALIGN_CENTER, 2 );
+    sizer3 = new wxBoxSizer( wxHORIZONTAL);
+    spin = new wxSpinCtrl( panel, ID_SETTINGS_SC_VIDEO_CROP_LEFT, wxU(""),
+                           wxDefaultPosition, wxDefaultSize,
+                           wxSP_ARROW_KEYS, 0, 2048, 2 );
+    spin->Enable( FALSE );
+    sizer3->Add( spin, 0, wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 2 );
+    spin = new wxSpinCtrl( panel, ID_SETTINGS_SC_VIDEO_CROP_RIGHT, wxU(""),
+                           wxDefaultPosition, wxDefaultSize,
+                           wxSP_ARROW_KEYS, 0, 2048, 2 );
+    spin->Enable( FALSE );
+    sizer3->Add( spin, 0, wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 2 );
+    sizer2->Add( sizer3, 0, wxALL|wxALIGN_CENTER );
+    spin = new wxSpinCtrl( panel, ID_SETTINGS_SC_VIDEO_CROP_BOTTOM, wxU(""),
+                           wxDefaultPosition, wxDefaultSize,
+                           wxSP_ARROW_KEYS, 0, 2048, 2 );
+    spin->Enable( FALSE );
+    sizer2->Add( spin, 0, wxALL|wxALIGN_CENTER, 2 );
+    sizer->Add( sizer2, 0, wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5 );
+
+    /* Size */
+    sizer->Add( new wxStaticText( panel, -1, wxU("Size") ),
+                0, wxALL|wxALIGN_LEFT, 5 );
+    sizer2 = new wxBoxSizer( wxHORIZONTAL );
+    spin = new wxSpinCtrl( panel, ID_SETTINGS_SC_VIDEO_WIDTH, wxU(""),
+                           wxDefaultPosition, wxDefaultSize,
+                           wxSP_ARROW_KEYS, 0, 2048, 2 );
+    spin->Enable( FALSE );
+    sizer2->Add( spin, 0, wxALL, 5 );
+    sizer2->Add( new wxStaticText( panel, -1, wxU("x") ), 0, wxALL, 5 );
+    spin = new wxSpinCtrl( panel, ID_SETTINGS_SC_VIDEO_HEIGHT, wxU(""),
+                           wxDefaultPosition, wxDefaultSize,
+                           wxSP_ARROW_KEYS, 0, 2048, 2 );
+    spin->Enable( FALSE );
+    sizer2->Add( spin, 0, wxALL, 5 );
+
+    sizer->Add( sizer2, 0, wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5 );
+
+#if 0
+    sizer->Add( new wxStaticText( panel, -1, wxU("Autocrop: []\n"
+                                                 "Crop: [] [] [] []\n"
+                                                 "2 pass: []\n"
+                                                 "Width: []\n"
+                                                 "Height: []\n"
+                                                 "Preview [..]" ) ),
+                0, wxALL, 5 );
+#endif
+    panel->SetSizerAndFit( sizer );
+    panel->SetAutoLayout( TRUE );
+    panel->Layout();
+
+    return panel;
+}
+
+static wxPanel *PanelSettingsAudio( wxWindow *p_parent )
+{
+    wxPanel *panel = new wxPanel( p_parent, -1,
+                                  wxDefaultPosition, wxSize(200, 200));
+    wxFlexGridSizer * sizer = new wxFlexGridSizer( 2, 1, 20 );
+    wxArrayString aS;
+    wxComboBox *combo;
+    unsigned int i;
+
+#if 0
+    /* TODO in the right way (there is a few problem with file type) */
+    /* Codec */
+    sizer->Add( new wxStaticText( panel, -1, wxU("Codec") ),
+                0, wxALL|wxALIGN_LEFT, 5 );
+    aS.Clear();
+    aS.Add( "Faac" );
+    aS.Add( "Lame" );
+    aS.Add( "Vorbis" );
+    aS.Add( "Ac3" );
+    aS.Add( "Mpga" );
+    aS.Add( "LPCM" );
+    combo = new wxComboBox( panel, ID_SETTINGS_CB_VIDEO_CODEC, aS[0],
+                            wxDefaultPosition, wxDefaultSize,
+                            aS, wxCB_READONLY );
+    sizer->Add( combo, 1, wxEXPAND|wxALL|wxALIGN_RIGHT, 5 );
+#endif
+    sizer->Add( new wxStaticText( panel, -1, wxU("Samplerate") ),
+                1, wxEXPAND|wxALL|wxALIGN_LEFT, 5 );
+    aS.Clear();
+    for( i = 0; i < hb_audio_rates_count; i++ )
+        aS.Add( wxString::Format( wxU("%d"), hb_audio_rates[i].rate ) );
+    combo = new wxComboBox( panel, ID_SETTINGS_CB_AUDIO_SAMPLERATE, wxU(""),
+                            wxDefaultPosition, wxDefaultSize,
+                            aS, wxCB_READONLY );
+    sizer->Add( combo, 0, wxALL|wxALIGN_RIGHT, 5 );
+
+
+    panel->SetSizerAndFit( sizer );
+
+    return panel;
+}
+
+static wxPanel *PanelSettingsOthers( wxWindow *p_parent )
+{
+    wxPanel *panel = new wxPanel( p_parent, -1,
+                                  wxDefaultPosition, wxSize(200, 200));
+
+    wxBoxSizer *sizer_row = new wxBoxSizer( wxVERTICAL );
+    wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 2, 20 );
+    wxComboBox *combo;
+    wxArrayString aS;
+    int i;
+    int i_count;
+
+    
+    /* CPU */
+    sizer->Add( new wxStaticText( panel, -1, wxU( "CPU" ) ),
+                1, wxEXPAND|wxALL|wxALIGN_LEFT );
+
+    i_count = g_hbApp->GetSystemCpuCount();
+    aS.Clear();
+    for( i = 0; i < i_count; i++ )
+        aS.Add( wxString::Format( wxU("%d"), i+1 ) );
+
+    combo = new wxComboBox( panel, ID_SETTINGS_CB_CPU,
+                            aS[g_hbApp->GetDefaultCpuCount()-1],
+                            wxDefaultPosition, wxDefaultSize,
+                            aS, wxCB_READONLY );
+    sizer->Add( combo, 0, wxALL|wxALIGN_RIGHT );
+
+    /* Priority */
+    sizer->Add( new wxStaticText( panel, -1, wxU( "Priority" ) ),
+                1, wxEXPAND|wxALL|wxALIGN_LEFT );
+
+    aS.Clear();
+    aS.Add( wxU("Highest") );
+    aS.Add( wxU("Above Normal") );
+    aS.Add( wxU("Normal") );
+    aS.Add( wxU("Below Normal") );
+    aS.Add( wxU("Lowest") );
+    combo = new wxComboBox( panel, ID_SETTINGS_CB_PRIORITY,
+                            aS[4-g_hbApp->GetDefaultPriority()],
+                            wxDefaultPosition, wxDefaultSize,
+                            aS, wxCB_READONLY );
+    sizer->Add( combo, 0, wxALL|wxALIGN_RIGHT );
+    combo->Enable( FALSE ); /* Marche pas pr le moment */
+
+    sizer_row->Add( sizer, 0, wxEXPAND|wxALL, 5 );
+
+    panel->SetSizerAndFit( sizer_row );
+
+    return panel;
+}
+
+
+class hbWizardPageSettings: public wxWizardPageSimple
+{
+public:
+    hbWizardPageSettings( wxWizard *p_wizard );
+    virtual ~hbWizardPageSettings();
+
+    void OnBrowse( wxCommandEvent &event );
+    void OnTitle( wxCommandEvent &event );
+    void OnChapter( wxCommandEvent &event );
+    void OnRadio( wxCommandEvent &event );
+    void OnAudio( wxCommandEvent &event );
+
+    void SetTitle( int i_title = -1 );
+    void OnPageChanging( wxWizardEvent &event );
+    void OnPageChanged( wxWizardEvent &event );
+
+private:
+    DECLARE_EVENT_TABLE()
+    wxFileDialog *dlgFile;
+};
+
+hbWizardPageSettings::hbWizardPageSettings( wxWizard *p_wizard ) :
+                                                wxWizardPageSimple(p_wizard)
+{
+    wxNotebook *nb = new wxNotebook( this, ID_SETTINGS_NB );
+    wxNotebookSizer *sizerN = new wxNotebookSizer( nb );
+
+    /* General settings */
+    nb->AddPage( PanelSettingsGeneral(nb), wxU("General"), TRUE );
+
+    /* Advanced */
+    nb->AddPage( PanelSettingsVideo(nb), wxU("Advanced Video"), FALSE );
+
+    /* Advanced */
+    nb->AddPage( PanelSettingsAudio(nb), wxU("Advanced Audio"), FALSE );
+    
+    /* Others */
+    nb->AddPage( PanelSettingsOthers(nb), wxU("Others"), FALSE );
+
+
+    hbWizardPageHeaders( this, "Settings", "Set your settings ;).",
+                         sizerN );
+
+    /* */
+    dlgFile = NULL;
+}
+
+hbWizardPageSettings::~hbWizardPageSettings()
+{
+}
+
+void hbWizardPageSettings::SetTitle( int i_title )
+{
+    wxArrayString &aT = *g_hbApp->GetTitles();
+    wxArrayString *p_array;
+    wxComboBox *title;
+    wxComboBox *chp;
+    wxComboBox *lg;
+    wxComboBox *fps;
+    wxComboBox *arate;
+    wxString sL;
+    bool bSetDefault = false;
+    int i;
+
+    /* Update title */
+    title = (wxComboBox*)FindWindow( ID_SETTINGS_CB_TITLE );
+    if( i_title < 0 )
+    {
+        title->Clear();
+        title->Append( aT );
+
+        i_title = g_hbApp->GetDefaultTitle();
+        title->SetValue( aT[i_title] );
+        bSetDefault = true;
+    }
+
+    g_hbApp->SetTitle( i_title );
+
+
+    /* Update chapter start/end */
+    chp = (wxComboBox*)FindWindow( ID_SETTINGS_CB_CHAPTER_START );
+    chp->Clear();
+    for( i = 0; i < g_hbApp->GetChaptersCount(); i++ )
+        chp->Append( wxString::Format( wxU("%d"), i+1 ) );
+    chp->SetValue( wxU("1") );
+
+    chp = (wxComboBox*)FindWindow( ID_SETTINGS_CB_CHAPTER_END );
+    chp->Clear();
+    for( i = 0; i < g_hbApp->GetChaptersCount(); i++ )
+        chp->Append( wxString::Format( wxU("%d"), i+1 ) );
+    chp->SetValue( wxString::Format( wxU("%d"), g_hbApp->GetChaptersCount() ) );
+
+    /* Update Audio language */
+    lg = (wxComboBox*)FindWindow( ID_SETTINGS_CB_AUDIO_LANGUAGE );
+    sL = lg->GetValue();
+    lg->Clear();
+    p_array = g_hbApp->GetTracksAudio();
+    lg->Append( *p_array );
+
+    if( bSetDefault || p_array->Index(sL) == wxNOT_FOUND )
+    {
+        sL = g_hbApp->GetDefaultAudio();
+        if( p_array->Index( sL ) == wxNOT_FOUND )
+            sL = (*p_array)[0];
+    }
+    lg->SetValue( sL );
+    g_hbApp->SetTrackAudio( p_array->Index(sL) );/* Needed for audio settings */
+
+    lg = (wxComboBox*)FindWindow( ID_SETTINGS_CB_SUBTITLE_LANGUAGE );
+    sL = lg->GetValue();
+    lg->Clear();
+    p_array = g_hbApp->GetTracksSubtitle();
+    lg->Append( *p_array );
+
+    if( bSetDefault || p_array->Index(sL) == wxNOT_FOUND )
+    {
+        sL = g_hbApp->GetDefaultSubtitle();
+        if( p_array->Index( sL ) == wxNOT_FOUND )
+            sL = p_array->Last();
+    }
+    lg->SetValue( sL );
+
+    if( bSetDefault || g_hbApp->GetDefaultVideoRateBase() != 0 )
+    {
+        int i_base = g_hbApp->GetDefaultVideoRateBase();
+
+        if( i_base == 0 || !bSetDefault )
+            i_base = g_hbApp->GetVideoRateBase();
+
+        fps = (wxComboBox*)FindWindow( ID_SETTINGS_CB_VIDEO_FPS );
+        for( i = 0; i  < hb_video_rates_count; i++ )
+        {
+            if( hb_video_rates[i].rate  == i_base )
+            {
+                fps->SetSelection( i );
+                break;
+            }
+        }
+    }
+
+    if( bSetDefault || g_hbApp->GetDefaultAudioSamplerate() != 0 )
+    {
+        int i_rate = g_hbApp->GetDefaultAudioSamplerate();
+
+        if( i_rate == 0 || !bSetDefault )
+            i_rate = g_hbApp->GetAudioSamplerate();
+        if( i_rate == 0 )
+            i_rate = 44100;
+
+        arate = (wxComboBox*)FindWindow( ID_SETTINGS_CB_AUDIO_SAMPLERATE );
+        arate->SetValue( wxString::Format( wxU("%d"), i_rate ) );
+    }
+
+    /* Set auto crop values and width size */
+    if( bSetDefault )
+    {
+        wxSpinCtrl *spin;
+        int crop[4];
+        int i_width, i_height;
+
+        g_hbApp->GetVideoAutocrop( crop );
+        g_hbApp->GetVideoSize( &i_width, &i_height );
+
+        /* Crop */
+        spin = (wxSpinCtrl*)FindWindow( ID_SETTINGS_SC_VIDEO_CROP_TOP );
+        spin->SetValue( crop[0] );
+        spin = (wxSpinCtrl*)FindWindow( ID_SETTINGS_SC_VIDEO_CROP_BOTTOM );
+        spin->SetValue( crop[1] );
+        spin = (wxSpinCtrl*)FindWindow( ID_SETTINGS_SC_VIDEO_CROP_LEFT );
+        spin->SetValue( crop[2] );
+        spin = (wxSpinCtrl*)FindWindow( ID_SETTINGS_SC_VIDEO_CROP_RIGHT );
+        spin->SetValue( crop[3] );
+
+        /* Size */
+        spin = (wxSpinCtrl*)FindWindow( ID_SETTINGS_SC_VIDEO_WIDTH );
+        spin->SetValue( i_width - (crop[2]+crop[3]) );
+        spin = (wxSpinCtrl*)FindWindow( ID_SETTINGS_SC_VIDEO_HEIGHT );
+        spin->SetValue( i_height - (crop[0]+crop[1]) );
+    }
+}
+
+
+void hbWizardPageSettings::OnTitle( wxCommandEvent &event )
+{
+    SetTitle( event.GetSelection() );
+}
+
+void hbWizardPageSettings::OnChapter( wxCommandEvent &event )
+{
+    wxComboBox *start = (wxComboBox*)FindWindow( ID_SETTINGS_CB_CHAPTER_START );
+    wxComboBox *end   = (wxComboBox*)FindWindow( ID_SETTINGS_CB_CHAPTER_END );
+
+    if( event.GetId() == ID_SETTINGS_CB_CHAPTER_START )
+    {
+        if( start->GetSelection() > end->GetSelection() )
+            end->SetSelection( start->GetSelection() );
+    }
+    else
+    {
+        if( end->GetSelection() < start->GetSelection() )
+            start->SetSelection( end->GetSelection() );
+    }
+}
+
+void hbWizardPageSettings::OnBrowse( wxCommandEvent &event )
+{
+    if( dlgFile == NULL )
+        dlgFile = new wxFileDialog( this, wxU( "Choose a file"),
+                                      wxGetCwd() );
+
+    if( dlgFile->ShowModal() == wxID_OK )
+    {
+        const wxChar *p = dlgFile->GetPath();
+        wxComboBox *file = (wxComboBox*)FindWindow(ID_SETTINGS_CB_OUTPUT_FILE);
+        file->SetValue( p );
+    }
+}
+
+void hbWizardPageSettings::OnRadio( wxCommandEvent &event )
+{
+    wxRadioButton *rSize =
+        (wxRadioButton*)FindWindow( ID_SETTINGS_RD_OUTPUT_SIZE );
+    wxRadioButton *rBitrate =
+        (wxRadioButton*)FindWindow( ID_SETTINGS_RD_OUTPUT_BITRATE );
+    wxComboBox *cSize =
+        (wxComboBox*)FindWindow( ID_SETTINGS_CB_OUTPUT_SIZE );
+    wxComboBox *cBitrate =
+        (wxComboBox*)FindWindow( ID_SETTINGS_CB_OUTPUT_BITRATE );
+
+    if( event.GetId() == ID_SETTINGS_RD_OUTPUT_SIZE )
+    {
+        /* FIXME is that needed ?? */
+        rBitrate->SetValue(FALSE);
+        cBitrate->Enable(FALSE);
+        cSize->Enable(TRUE);
+    }
+    else
+    {
+        rSize->SetValue(FALSE);
+        cSize->Enable(FALSE);
+        cBitrate->Enable(TRUE);
+    }
+}
+void hbWizardPageSettings::OnAudio( wxCommandEvent &event )
+{
+    if( g_hbApp->GetDefaultAudioSamplerate() == 0 )
+    {
+        int i_rate = g_hbApp->GetAudioSamplerate();
+        wxComboBox *arate =
+            (wxComboBox*)FindWindow( ID_SETTINGS_CB_AUDIO_SAMPLERATE );
+
+        if( i_rate == 0 ) i_rate = 44100;
+        arate->SetValue( wxString::Format( wxU("%d"), i_rate ) );
+    }
+}
+
+void hbWizardPageSettings::OnPageChanging( wxWizardEvent &event )
+{
+    wxComboBox *cFile;
+    wxComboBox *cChap;
+    wxComboBox *cLang;
+    wxComboBox *cQ;
+    wxComboBox *cCombo;
+    wxCheckBox *cCheck;
+    wxRadioButton *rSize;
+    wxSpinCtrl *spin;
+    int i_bitrate_audio;
+    int crop[4];
+    int i_width, i_height;
+
+    wxString sFile;
+
+    if( !event.GetDirection() )
+        return;
+
+    /* We need to validate params and start encoding */
+
+    /* Get and Check validity of parameters */
+    cFile = (wxComboBox*)FindWindow( ID_SETTINGS_CB_OUTPUT_FILE );
+    sFile = cFile->GetValue();
+    if( sFile.IsEmpty() )
+    {
+        hbError( this, wxU("You have to give a output file name") );
+        event.Veto();
+        return;
+    }
+    g_hbApp->SetOutputFile( sFile );
+
+    /* Chapter start/end */
+    cChap = (wxComboBox*)FindWindow( ID_SETTINGS_CB_CHAPTER_START );
+    g_hbApp->SetChapterStart( cChap->GetSelection() + 1 );
+
+    cChap = (wxComboBox*)FindWindow( ID_SETTINGS_CB_CHAPTER_END );
+    g_hbApp->SetChapterEnd( cChap->GetSelection() + 1 );
+
+    /* Audio */
+    cLang = (wxComboBox*)FindWindow( ID_SETTINGS_CB_AUDIO_LANGUAGE );
+    g_hbApp->SetTrackAudio( cLang->GetSelection(), 0 );
+    /* FIXME find a better way */
+    cQ = (wxComboBox*)FindWindow( ID_SETTINGS_CB_AUDIO_QUALITY );
+    sscanf( cQ->GetValue().ToAscii(), "%*s - %d kb/s", &i_bitrate_audio );
+    g_hbApp->SetAudioBitrate( i_bitrate_audio );
+
+    long arate;
+    cCombo = (wxComboBox*)FindWindow( ID_SETTINGS_CB_AUDIO_SAMPLERATE );
+    cCombo->GetValue().ToLong( &arate );
+    g_hbApp->SetAudioSamplerate( arate );
+
+    /* Subs */
+    cLang = (wxComboBox*)FindWindow( ID_SETTINGS_CB_SUBTITLE_LANGUAGE );
+    g_hbApp->SetTrackSubtitle( cLang->GetSelection() );
+
+    /* Video/Quality */
+    cQ = (wxComboBox*)FindWindow( ID_SETTINGS_CB_VIDEO_QUALITY );
+    if( cQ->GetSelection() == 3 )
+        g_hbApp->SetVideoPass( 2 );
+    else
+        g_hbApp->SetVideoPass( 1 );
+    /* Video codec */
+    cCombo = (wxComboBox*)FindWindow( ID_SETTINGS_CB_VIDEO_CODEC );
+    g_hbApp->SetVideoCodec( cCombo->GetValue() );
+    /* Video fps */
+    cCombo = (wxComboBox*)FindWindow( ID_SETTINGS_CB_VIDEO_FPS );
+    g_hbApp->SetVideoRateBase( hb_video_rates[cCombo->GetSelection()].rate );
+    /* Deinterlace */
+    cCheck = (wxCheckBox*)FindWindow( ID_SETTINGS_CH_VIDEO_DEINTERLACE );
+    g_hbApp->SetVideoDeinterlace( cCheck->GetValue() );
+    /* Crop */
+    cCheck = (wxCheckBox*)FindWindow( ID_SETTINGS_CH_VIDEO_CROP );
+    if( cCheck->GetValue() )
+    {
+        spin = (wxSpinCtrl*)FindWindow( ID_SETTINGS_SC_VIDEO_CROP_TOP );
+        crop[0] = spin->GetValue();
+        spin = (wxSpinCtrl*)FindWindow( ID_SETTINGS_SC_VIDEO_CROP_BOTTOM );
+        crop[1] = spin->GetValue();
+        spin = (wxSpinCtrl*)FindWindow( ID_SETTINGS_SC_VIDEO_CROP_LEFT );
+        crop[2] = spin->GetValue();
+        spin = (wxSpinCtrl*)FindWindow( ID_SETTINGS_SC_VIDEO_CROP_RIGHT );
+        crop[3] = spin->GetValue();
+        g_hbApp->SetVideoCrop( crop );
+    }
+    else
+    {
+        g_hbApp->SetVideoCrop( NULL );
+    }
+    spin = (wxSpinCtrl*)FindWindow( ID_SETTINGS_SC_VIDEO_WIDTH );
+    i_width = spin->GetValue();
+    spin = (wxSpinCtrl*)FindWindow( ID_SETTINGS_SC_VIDEO_HEIGHT );
+    i_height = spin->GetValue();
+    g_hbApp->SetVideoSize( i_width, i_height );
+
+
+    rSize = (wxRadioButton*)FindWindow( ID_SETTINGS_RD_OUTPUT_SIZE );
+    if( rSize->GetValue() )
+    {
+        wxComboBox *cSize =
+            (wxComboBox*)FindWindow( ID_SETTINGS_CB_OUTPUT_SIZE );
+        long i_size;
+        
+        cSize->GetValue().ToLong( &i_size );
+        if( i_size <= 0 )
+        {
+            hbError( this, wxU("Invalide file size") );
+            event.Veto();
+            return;
+        }
+        g_hbApp->SetTotalSize( i_size );
+    }
+    else
+    {
+        wxComboBox *cBitrate =
+            (wxComboBox*)FindWindow( ID_SETTINGS_CB_OUTPUT_BITRATE );
+        long i_bitrate;
+
+       cBitrate->GetValue().ToLong( &i_bitrate );
+        if( i_bitrate<= 0 )
+        {
+            hbError( this, wxU("Invalid total bitrate") );
+            event.Veto();
+            return;
+        }
+        else if( i_bitrate <= i_bitrate_audio )
+        {
+            hbError( this, wxU("Incompatible total bitrate with audio bitrate") );
+            event.Veto();
+            return;
+        }
+        g_hbApp->SetTotalBitrate( i_bitrate );
+    }
+
+    /* Other settings */
+    /* CPU */
+    cCombo = (wxComboBox*)FindWindow( ID_SETTINGS_CB_CPU );
+    g_hbApp->SetCpuCount( cCombo->GetSelection() );
+
+    cCombo = (wxComboBox*)FindWindow( ID_SETTINGS_CB_PRIORITY );
+    g_hbApp->SetPriority( cCombo->GetSelection() );
+
+    /* TODO finish */
+
+    /* Start the encode (TODO) */
+    if( g_hbApp->Encode() < 0 )
+    {
+        event.Veto();   /* Wrong */
+        return;
+    }
+}
+void hbWizardPageSettings::OnPageChanged( wxWizardEvent &event )
+{
+    /* Initialise avec le titre par défaut */
+    SetTitle();
+}
+
+BEGIN_EVENT_TABLE( hbWizardPageSettings, wxWizardPageSimple )
+    EVT_BUTTON( ID_SETTINGS_BT_FILE, hbWizardPageSettings::OnBrowse )
+    EVT_COMBOBOX( ID_SETTINGS_CB_TITLE, hbWizardPageSettings::OnTitle )
+    EVT_COMBOBOX( ID_SETTINGS_CB_CHAPTER_START,hbWizardPageSettings::OnChapter)
+    EVT_COMBOBOX( ID_SETTINGS_CB_CHAPTER_END, hbWizardPageSettings::OnChapter )
+    EVT_COMBOBOX( ID_SETTINGS_CB_AUDIO_LANGUAGE, hbWizardPageSettings::OnAudio )
+    EVT_WIZARD_PAGE_CHANGING( -1, hbWizardPageSettings::OnPageChanging )
+    EVT_WIZARD_PAGE_CHANGED( -1, hbWizardPageSettings::OnPageChanged )
+    EVT_RADIOBUTTON( ID_SETTINGS_RD_OUTPUT_SIZE, hbWizardPageSettings::OnRadio)
+    EVT_RADIOBUTTON( ID_SETTINGS_RD_OUTPUT_BITRATE, hbWizardPageSettings::OnRadio)
+END_EVENT_TABLE()
+
+
+/*****************************************************************************
+ * hbWizardPageEncode:
+ *****************************************************************************/
+class hbWizardPageEncode: public wxWizardPageSimple
+{
+public:
+    hbWizardPageEncode( wxWizard *p_wizard );
+    virtual ~hbWizardPageEncode();
+
+private:
+    //DECLARE_EVENT_TABLE()
+};
+
+hbWizardPageEncode::hbWizardPageEncode( wxWizard *p_wizard ) :
+                                             wxWizardPageSimple(p_wizard)
+{
+    wxBoxSizer *sizer;
+    sizer = new wxBoxSizer( wxVERTICAL );
+#if 0
+    wxGauge * gauge;
+    sizer->Add( new wxStaticText( this, -1, wxU("Progess: x%%" ) ) );
+
+    gauge = new wxGauge( this, -1, 100 );
+    gauge->SetValue( 50 );
+
+    sizer->Add( gauge );
+#endif
+
+
+    hbWizardPageHeaders( this, "Success",
+                         "The encode is finished",
+                         sizer );
+
+}
+
+hbWizardPageEncode::~hbWizardPageEncode()
+{
+}
+
+/****************************************************************************
+ * hbWizard:
+ ****************************************************************************/
+hbWizard::hbWizard( wxWindow *p_parent) :
+     wxWizard( p_parent, -1, wxU("HandBrake"), wxNullBitmap, wxDefaultPosition)
+{
+    page1 = new hbWizardPageSource( this );
+    page2 = new hbWizardPageSettings( this );
+    page3 = new hbWizardPageEncode( this );
+
+    wxWizardPageSimple::Chain( page1, page2 );
+    wxWizardPageSimple::Chain( page2, page3 );
+
+    //SetPageSize( wxSize( 500, 400 ) );
+    FitToPage( page1 );
+    FitToPage( page2 );
+    FitToPage( page3 );
+}
+
+hbWizard::~hbWizard()
+{
+    Destroy();
+    /* Is that ok */
+    delete page1;
+    delete page2;
+    delete page3;
+}
+
+void hbWizard::Run()
+{
+    fprintf( stderr, "hbWizard::Run\n" );
+
+    RunWizard( page1 );
+}
+
diff --git a/wx/hbWizard.h b/wx/hbWizard.h
new file mode 100644 (file)
index 0000000..a66413a
--- /dev/null
@@ -0,0 +1,43 @@
+/*****************************************************************************
+ * wizard.h:
+ *****************************************************************************
+ * Copyright (C) 
+ * $Id: hbWizard.h,v 1.1 2005/01/16 15:59:21 titer Exp $
+ *
+ * Authors:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+class hbWizardPageSource;
+class hbWizardPageSettings;
+class hbWizardPageEncode;
+
+class hbWizard: public wxWizard
+{
+public:
+    hbWizard( wxWindow *p_parent );
+    virtual ~hbWizard();
+
+    void Run();
+
+private:
+    int i_essai;
+    hbWizardPageSource   *page1;
+    hbWizardPageSettings *page2;
+    hbWizardPageEncode   *page3;
+
+    //DECLARE_EVENT_TABLE()
+};
diff --git a/wx/wxHB.cpp b/wx/wxHB.cpp
new file mode 100644 (file)
index 0000000..b336290
--- /dev/null
@@ -0,0 +1,684 @@
+/*****************************************************************************
+ * wxHB:
+ *****************************************************************************
+ * Copyright (C)
+ * $Id: wxHB.cpp,v 1.8 2005/03/26 23:04:17 titer Exp $
+ *
+ * Authors:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+#include "wxHB.h"
+#include "hbWizard.h"
+
+#ifdef SYS_CYGWIN
+#   include <windows.h>
+#endif
+
+/****************************************************************************
+ * Definitions / Variables
+ ****************************************************************************/
+class hbApp *g_hbApp = NULL;
+
+IMPLEMENT_APP( hbApp )
+
+/****************************************************************************
+ * Helpers class
+ ****************************************************************************/
+class hbAppTimer: public wxTimer
+{
+public:
+    hbAppTimer()
+    {
+        Start( 50, wxTIMER_CONTINUOUS );
+    }
+    virtual void Notify()
+    {
+        g_hbApp->Update();
+    }
+};
+
+class hbAppProgress: public wxDialog
+{
+public:
+    hbAppProgress( wxWindow *parent, wxString title, wxString msg ) :
+        wxDialog( parent, -1, title, wxDefaultPosition, wxSize( 250, 300),
+                  wxDEFAULT_DIALOG_STYLE )
+    {
+        /* Create widgets */
+        txt = new wxStaticText( this, -1, msg );
+        gauge = new wxGauge( this, -1, 100 );
+        button = new wxButton( this, wxID_CANCEL, wxU("Cancel") );
+
+        /* Add evrything in a sizer */
+        wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
+        sizer->Add( txt, 1, wxEXPAND|wxALIGN_CENTER|wxALL, 5 );
+
+        wxBoxSizer *sizerH = new wxBoxSizer( wxHORIZONTAL );
+        sizerH->Add( gauge, 1, wxALIGN_CENTER|wxALL, 5 );
+        sizer->Add( sizerH, 0, wxALIGN_CENTER|wxALL, 5 );
+
+        sizer->Add( button, 0, wxALIGN_CENTER_HORIZONTAL|
+                               wxALIGN_BOTTOM|wxALL, 5 );
+        //SetSizerAndFit( sizer );
+        SetSizer( sizer );
+    }
+
+    void SetProgress( int i_percent, wxString msg )
+    {
+        gauge->SetValue( i_percent );
+        txt->SetLabel( msg );
+    }
+
+    void OnClose( wxCloseEvent &event )
+    {
+        EndModal( wxID_CANCEL );
+    }
+
+private:
+    wxStaticText *txt;
+    wxGauge      *gauge;
+    wxButton     *button;
+
+    DECLARE_EVENT_TABLE()
+};
+
+BEGIN_EVENT_TABLE( hbAppProgress, wxDialog )
+    EVT_CLOSE( hbAppProgress::OnClose )
+END_EVENT_TABLE()
+
+/****************************************************************************
+ * hbApp class
+ ****************************************************************************/
+
+/* OnInit: Call at the very start and put every in place
+ */
+bool hbApp::OnInit()
+{
+    /* Export hbApp */
+    g_hbApp = this;
+
+
+    /* Init all variables */
+    isEnd = false;
+
+    progress = NULL;
+
+    i_title = -1;
+    titles  = NULL;
+    title = NULL;
+
+    audios = NULL;
+    subs = NULL;
+
+    systemDrive = NULL;
+
+    /* Start HB */
+    if( Init() )
+        return false;
+
+    /* Start out timer */
+    timer = new hbAppTimer();
+
+    /* Create and Start the wizard */
+    wizard = new hbWizard( NULL );
+    wizard->Run();
+
+    /* Special hack FIXME */
+    isEnd = true;
+
+    return true;
+}
+
+/* OnExit:
+ */
+int hbApp::OnExit()
+{
+    delete timer;
+    delete wizard;
+
+    /* End hb */
+    End();
+
+    /* Delete others FIXME */
+
+    return 0;
+}
+
+/* Init:
+ */
+int hbApp::Init()
+{
+    /* Create a hb instance */
+    hbHandle = hb_init( HB_DEBUG_NONE, 1 );
+    if( hbHandle == NULL )
+        return -1;
+
+    return 0;
+}
+/* Scan:
+ */
+int hbApp::Scan( wxString sDevice )
+{
+    if( sDevice.IsEmpty() )
+        return -1;
+
+    /* Reset state */
+    i_title = -1;
+    if( titles ) delete titles; titles  = NULL;
+    if( audios ) delete audios; audios = NULL;
+    if( subs ) delete subs; subs = NULL;
+    title = NULL;
+
+    /* Append a \ if needed */
+    if( sDevice.Length() == 2 && sDevice.Last() == ':' )
+        sDevice.Append( '\\' );
+
+    /* Launch the scan (all titles) */
+    hb_scan( hbHandle, sDevice.ToAscii(), 0 );
+
+    /* Create a progress report */
+    progress = new hbAppProgress( wizard, wxU("Scanning..."), wxU("Opening ")+sDevice);
+    progress->ShowModal();
+
+    if( !hb_list_count( hb_get_titles( hbHandle ) ) )
+    {
+        hbError( wizard, wxU("Scanning failed") );
+        return -1;
+    }
+
+    /* FIXME test if the scan is complete */
+
+
+    return 0;
+}
+/* Encode:
+ */
+int hbApp::Encode()
+{
+    hb_state_t s;
+
+    /* Maybe check a few things like:
+     *  - compatible muxer and codecs */
+
+    /* Start the encoding */
+    hb_add( hbHandle, title->job );
+    hb_start( hbHandle );
+
+    /* FIXME use the wizard instead */
+    /* Create a progress report */
+    progress = new hbAppProgress( wizard, wxU("Encoding..."), wxU("0%"));
+    progress->ShowModal();
+
+    hb_get_state( hbHandle, &s );
+    if( s.param.workdone.error != HB_ERROR_NONE )
+    {
+        hb_stop( hbHandle );    /* FIXME to a proper handling */
+        hbError( wizard, wxU("Encoding failed/stopped") );
+        return -1;
+    }
+
+    /* bad */
+    return 0;
+}
+
+/* End:
+ */
+void hbApp::End()
+{
+    hb_close( &hbHandle );
+}
+
+
+wxArrayString *hbApp::GetTitles()
+{
+    hb_list_t *list;
+    int i_count;
+    int i;
+
+    if( titles )
+        return titles;
+
+    /* Create the title list */
+    list = hb_get_titles( hbHandle );
+
+    i_count = hb_list_count( list );
+    if( i_count <= 0 )
+        return NULL;
+
+    titles = new wxArrayString();
+    for( i = 0; i < i_count; i++ )
+    {
+        hb_title_t *t = (hb_title_t*)hb_list_item( list, i );
+        wxString name = wxString::Format( wxU("%d  - %d:%02d:%02d"),
+                                          t->index,
+                                          t->hours, t->minutes, t->seconds );
+        titles->Add( name );
+    }
+
+    return titles;
+}
+
+void hbApp::SetTitle( int _i_title )
+{
+    int i;
+
+    if( i_title == _i_title )
+        return;
+
+    i_title = _i_title;
+    title = (hb_title_t*)hb_list_item( hb_get_titles( hbHandle ), i_title );
+    if( audios ) delete audios; audios = NULL;
+    if( subs ) delete subs; subs = NULL;
+
+    for( i = 0; i < 8; i++ )
+        title->job->audios[i] = -1;
+    title->job->subtitle = -1;
+}
+
+int hbApp::GetDefaultTitle()
+{
+    hb_list_t *list;
+    int i_best = -1;
+    int i_best_length = 0;
+    int i;
+
+    list = hb_get_titles( hbHandle );
+    for( i = 0; i < hb_list_count( list ); i++ )
+    {
+        hb_title_t *t = (hb_title_t*)hb_list_item( list, i );
+        int i_length = t->hours * 3600 + t->minutes*60 + t->seconds;
+
+        if( i_best < 0 || i_length > i_best_length )
+        {
+            i_best = i;
+            i_best_length = i_length;
+        }
+    }
+
+    return i_best;
+}
+
+
+
+int hbApp::GetChaptersCount()
+{
+    if( i_title < 0 )
+        return 0;
+
+    return hb_list_count( title->list_chapter );
+}
+
+void hbApp::SetChapterStart( int i_chapter )
+{
+    title->job->chapter_start = i_chapter;
+}
+
+void hbApp::SetChapterEnd( int i_chapter )
+{
+    title->job->chapter_end = i_chapter;
+}
+
+wxArrayString *hbApp::GetTracksAudio()
+{
+    int i;
+    if( audios )
+        return audios;
+
+    audios = new wxArrayString();
+    for( i = 0; i < hb_list_count( title->list_audio ); i++ )
+    {
+        hb_audio_t *a = (hb_audio_t*)hb_list_item( title->list_audio, i );
+
+        audios->Add( wxU(a->lang) );
+    }
+    audios->Add( wxU("None") );
+
+    return audios;
+}
+void hbApp::SetTrackAudio( int i_track, int i_pos )
+{
+    if( i_pos >= 0 && i_pos < hb_list_count( title->list_audio ) )
+        title->job->audios[i_pos] = i_track;
+    else
+        title->job->audios[i_pos] = -1;
+}
+
+wxArrayString *hbApp::GetTracksSubtitle()
+{
+    int i;
+
+    if( subs )
+        return subs;
+
+    subs = new wxArrayString();
+    for( i = 0; i < hb_list_count( title->list_subtitle ); i++ )
+    {
+        hb_subtitle_t *s =
+            (hb_subtitle_t*)hb_list_item( title->list_subtitle, i );
+
+        subs->Add( wxU(s->lang) );
+    }
+    subs->Add( wxU("None") );
+
+    return subs;
+}
+
+void hbApp::SetTrackSubtitle( int i_track )
+{
+    if( i_track >= 0 && i_track < hb_list_count( title->list_subtitle ) )
+        title->job->subtitle = i_track;
+    else
+        title->job->subtitle = -1;
+}
+
+void hbApp::SetOutputFile( wxString sFile )
+{
+    char *psz;
+
+    title->job->file = strdup( sFile.ToAscii() ); /* FIXME do we need strdup ? */
+
+    psz = strrchr( title->job->file, '.' );
+    if( psz == NULL )
+        title->job->mux = HB_MUX_AVI; /* By default, FIXME */
+    else if( !strcasecmp( psz, ".avi" ) )
+        title->job->mux = HB_MUX_AVI;
+    else if( !strcasecmp( psz, ".mp4" ) || !strcasecmp( psz, ".mov") )
+        title->job->mux = HB_MUX_MP4;
+    else if( !strcasecmp( psz, ".ogg" ) || !strcasecmp( psz, ".ogm") )
+        title->job->mux = HB_MUX_OGM;
+    else
+        title->job->mux = HB_MUX_AVI; /* By default */
+
+    /* Fix acodec value */
+    switch( title->job->mux )
+    {
+        case HB_MUX_AVI:
+            title->job->acodec = HB_ACODEC_LAME;
+            break;
+        case HB_MUX_MP4:
+            title->job->acodec = HB_ACODEC_FAAC;
+            break;
+        case HB_MUX_OGM:
+            title->job->acodec = HB_ACODEC_VORBIS;
+            break;
+    }
+}
+
+void hbApp::SetAudioBitrate( int i_bitrate )
+{
+    int i_old = title->job->abitrate;
+
+    title->job->abitrate = i_bitrate;
+
+    if( title->job->vbitrate > 0 )
+        title->job->vbitrate = title->job->vbitrate + (i_old - i_bitrate);
+}
+
+void hbApp::SetTotalBitrate( int i_bitrate )
+{
+    title->job->vbitrate = i_bitrate - title->job->abitrate;
+
+    if( title->job->vbitrate <= 0 )
+        title->job->vbitrate = 1;
+}
+
+void hbApp::SetTotalSize( int i_size )
+{
+    /* XXX */
+}
+
+void hbApp::SetVideoPass( int i_pass )
+{
+    /* FIXME is 0 or 1 valid for 1 pass ? */
+    if( i_pass <= 1 )
+        title->job->pass = 0;
+    else if( i_pass == 2 )
+        title->job->pass = 2;
+}
+
+void hbApp::SetVideoCodec( wxString sCodec )
+{
+    if( sCodec.Lower() == wxU("ffmpeg") )
+        title->job->vcodec = HB_VCODEC_FFMPEG;
+    else if( sCodec.Lower() == wxU("xvid") )
+        title->job->vcodec = HB_VCODEC_XVID;
+    else if( sCodec.Lower() == wxU("x264") )
+        title->job->vcodec = HB_VCODEC_XVID;
+}
+
+void hbApp::SetVideoDeinterlace( bool b_deinterlace )
+{
+    title->job->deinterlace = b_deinterlace ? 1 : 0;
+}
+
+void hbApp::SetPriority( int i_priority )
+{
+    /* Doesn't work :(( */
+#ifdef SYS_CYGWIN
+    switch( i_priority )
+    {
+        case HB_PRIORITY_ABOVE_NORMAL:
+            i_priority = THREAD_PRIORITY_ABOVE_NORMAL;
+            break;
+        case HB_PRIORITY_BELOW_NORMAL:
+            i_priority = THREAD_PRIORITY_BELOW_NORMAL;
+            break;
+        case HB_PRIORITY_LOWEST:
+            i_priority = THREAD_PRIORITY_LOWEST;
+            break;
+        case HB_PRIORITY_HIGHEST:
+            i_priority = THREAD_PRIORITY_HIGHEST;
+            break;
+
+        case HB_PRIORITY_NORMAL:
+        default:
+            i_priority = THREAD_PRIORITY_NORMAL;
+            break;
+    }
+    ::SetThreadPriority( GetCurrentThread(), i_priority );
+#else
+    /* TODO */
+#endif
+}
+
+void hbApp::SetCpuCount( int i_cpu )
+{
+    hb_set_cpu_count( hbHandle, i_cpu );
+}
+
+int hbApp::GetVideoRateBase()
+{
+    return title->rate_base;
+}
+
+void hbApp::SetVideoRateBase( int i_base )
+{
+    title->job->vrate_base = i_base;
+    title->job->vrate = HB_VIDEO_RATE_BASE;
+}
+void hbApp::GetVideoAutocrop( int crop[4] )
+{
+    int i;
+    for( i = 0; i < 4; i++ )
+        crop[i] = title->crop[i];
+}
+void hbApp::SetVideoCrop( int crop[4] )
+{
+    int i;
+    for( i = 0; i < 4; i++ )
+        title->job->crop[i] = crop ? crop[i] : 0;
+}
+void hbApp::GetVideoSize( int *pi_width, int *pi_height )
+{
+    *pi_width = title->width;
+    *pi_height = title->height;
+}
+void hbApp::SetVideoSize( int i_width, int i_height )
+{
+    title->job->width = i_width;
+    title->job->height = i_height;
+}
+
+
+int hbApp::GetAudioSamplerate()
+{
+    int idx = title->job->audios[0];
+    if( idx >= 0 && idx < hb_list_count( title->list_audio ) )
+    {
+        hb_audio_t *a = (hb_audio_t*)hb_list_item( title->list_audio, 0 );
+        return a->rate;
+    }
+
+    /* FIXME not good */
+    return title->job->arate;
+}
+
+void hbApp::SetAudioSamplerate( int i_rate )
+{
+    title->job->arate = i_rate;
+}
+
+wxString hbApp::GetDefaultAudio()
+{
+    return wxU("English");
+}
+
+wxString hbApp::GetDefaultSubtitle()
+{
+    return wxU("None");
+}
+
+int hbApp::GetDefaultCpuCount()
+{
+    return GetSystemCpuCount();
+}
+
+int hbApp::GetDefaultPriority()
+{
+    return HB_PRIORITY_NORMAL;
+}
+
+int hbApp::GetDefaultVideoRateBase()
+{
+    return 0;
+}
+
+int hbApp::GetDefaultAudioSamplerate()
+{
+    return 0;
+}
+
+/* Drive */
+wxArrayString *hbApp::GetSystemDrive()
+{
+    if( systemDrive )
+        return systemDrive;
+
+    systemDrive = new wxArrayString();
+#ifdef SYS_CYGWIN
+    char c;
+    for( c = 'A'; c <= 'Z'; c++ )
+    {
+        char pszDrive[4];
+        pszDrive[0] = c;
+        pszDrive[1] = ':';
+        pszDrive[2] = '\\';
+        pszDrive[3] = '\0';
+
+        if( GetDriveType( pszDrive ) == DRIVE_CDROM )
+            systemDrive->Add( wxString::Format( wxU("%c:"), c ) );
+    }
+#else
+    /* TODO true detection */
+    systemDrive->Add( wxU("/dev/dvd") );
+    systemDrive->Add( wxU("/dev/cdrom") );
+#endif
+
+    return systemDrive;
+}
+
+int hbApp::GetSystemCpuCount()
+{
+    return hb_get_cpu_count();
+}
+
+void hbApp::Update()
+{
+    hb_state_t s;
+
+    /* Special hack FIXME */
+    if( isEnd )
+    {
+        g_hbApp->ExitMainLoop();
+        return;
+    }
+
+    /* */
+    hb_get_state( hbHandle, &s );
+    switch( s.state )
+    {
+        case HB_STATE_IDLE:
+            break;
+
+        case HB_STATE_SCANNING:
+        {
+            int i_cur = s.param.scanning.title_cur;
+            int i_cnt = s.param.scanning.title_count;
+
+            if( i_cnt > 0 )
+            {
+                progress->SetProgress( 100*(i_cur-1)/i_cnt,
+                                   wxString::Format(wxU("Scanning title %d of %d."),
+                                                    i_cur, i_cnt) );
+            }
+            break;
+        }
+
+        case HB_STATE_SCANDONE:
+            if( progress )
+            {
+                progress->SetProgress( 100, wxU("Scanning complete.") );
+                progress->Close( TRUE );
+                //delete progress;
+                progress = NULL;
+            }
+            break;
+
+        case HB_STATE_WORKING:
+        {
+            float f_progress = s.param.working.progress;
+            float f_rate_cur = s.param.working.rate_cur;
+            float f_rate_avg = s.param.working.rate_avg;
+
+            progress->SetProgress( (int)(100 * f_progress),
+                wxString::Format(wxU("Encoding: %.2f %% (%.2f fps, avg %.2f fps)\n"),
+                                 100.0 * f_progress, f_rate_cur, f_rate_avg ));
+            break;
+        }
+
+        case HB_STATE_WORKDONE:
+            if( progress )
+            {
+                progress->SetProgress( 100, wxU("Encoding complete.") );
+                progress->Close( TRUE );
+                //delete progress;
+                progress = NULL;
+            }
+            break;
+    }
+}
+
diff --git a/wx/wxHB.h b/wx/wxHB.h
new file mode 100644 (file)
index 0000000..c762305
--- /dev/null
+++ b/wx/wxHB.h
@@ -0,0 +1,170 @@
+/*****************************************************************************
+ * wxHB:
+ *****************************************************************************
+ * Copyright (C) 
+ * $Id: wxHB.h,v 1.2 2005/01/16 17:44:56 titer Exp $
+ *
+ * Authors:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+#include "hb.h"
+
+#include <wx/wx.h>
+#include <wx/wizard.h>
+#include <wx/listctrl.h>
+#include <wx/textctrl.h>
+#include <wx/notebook.h>
+#include <wx/spinctrl.h>
+#include <wx/dnd.h>
+#include <wx/treectrl.h>
+#include <wx/gauge.h>
+#include <wx/accel.h>
+#include <wx/checkbox.h>
+#include <wx/image.h>
+#include <wx/wizard.h>
+
+#include "wx/file.h"
+#include "wx/mstream.h"
+#include "wx/wfstream.h"
+#include <wx/statline.h>
+
+#if wxUSE_UNICODE
+#define wxU(psz) wxString(psz, *wxConvCurrent)
+#else
+#define wxU(psz) psz
+#endif
+
+/* Unique global variable: our App
+ * XXX: we could use wxGetApp() instead (but it is a bit longer ;)
+ */
+extern class hbApp *g_hbApp;
+
+/* */
+class hbAppTimer;
+class hbAppProgress;
+class hbWizard;
+
+/* */
+enum
+{
+    HB_PRIORITY_LOWEST = 0,
+    HB_PRIORITY_BELOW_NORMAL,
+    HB_PRIORITY_NORMAL,
+    HB_PRIORITY_ABOVE_NORMAL,
+    HB_PRIORITY_HIGHEST,
+};
+
+/* Our wxApp */
+class hbApp: public wxApp
+{
+public:
+    virtual bool OnInit();
+    virtual int  OnExit();
+
+    /* HB related */
+    int  Init();
+    int  Scan( wxString sDevice );
+    int  Encode();
+    void End();
+
+    /* */
+    /* XXX: the wxArrayString aren't duplicated, so don't delete them */
+    wxArrayString *GetTitles();
+    void           SetTitle( int i_title );
+
+    int            GetChaptersCount();
+    void           SetChapterStart( int i_chapter );
+    void           SetChapterEnd( int i_chapter );
+
+    wxArrayString *GetTracksAudio();
+    void           SetTrackAudio( int i_track, int i_pos = 0 );
+
+    wxArrayString *GetTracksSubtitle();
+    void           SetTrackSubtitle( int i_track );
+
+    void           SetOutputFile( wxString );
+    void           SetAudioBitrate( int );
+    void           SetTotalBitrate( int );
+    void           SetTotalSize( int );
+    void           SetVideoPass( int );
+    void           SetPriority( int );
+    void           SetVideoCodec( wxString );
+    void           SetVideoDeinterlace( bool );
+    void           SetCpuCount( int );
+
+    int            GetVideoRateBase();
+    void           SetVideoRateBase( int );
+
+    int            GetAudioSamplerate();
+    void           SetAudioSamplerate( int );
+
+    void           GetVideoAutocrop( int crop[4] );
+    void           SetVideoCrop( int crop[4] );
+    void           GetVideoSize( int *pi_width, int *pi_height );
+    void           SetVideoSize( int i_width, int i_height );
+
+
+    /* Get Default value (from config file or from logic) */
+    int            GetDefaultTitle();
+    wxString       GetDefaultAudio();
+    wxString       GetDefaultSubtitle();
+    int            GetDefaultCpuCount();
+    int            GetDefaultPriority();
+    int            GetDefaultVideoRateBase();
+    int            GetDefaultAudioSamplerate();
+
+    /* Drive */
+    wxArrayString *GetSystemDrive();
+    int            GetSystemCpuCount();
+
+
+    /* wx related */
+    /* Called regulary by a timer
+     * FIXME derive hbApp from timer too instead ? */
+    void  Update();
+
+private:
+    bool isEnd;
+
+    hbAppTimer *timer;
+    hbWizard *wizard;
+    hbAppProgress *progress;
+
+    hb_handle_t *hbHandle;
+
+    /* */
+    int           i_title;
+    wxArrayString *titles;
+    hb_title_t    *title;
+
+    int            i_chapters;
+    wxArrayString *audios;
+    wxArrayString *subs;
+
+    /* System */
+    wxArrayString *systemDrive;
+};
+
+static void hbError( wxWindow *p_parent, wxString sTitle )
+{
+    wxMessageDialog *dlg = new wxMessageDialog( p_parent,
+                                                sTitle,
+                                                wxU("Error"),
+                                                wxOK|wxCENTRE|wxICON_ERROR );
+    dlg->ShowModal();
+    delete dlg;
+}