summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AUTHORS6
-rw-r--r--BUILD42
-rw-r--r--Jamfile69
-rw-r--r--Jamrules164
-rw-r--r--NEWS25
-rw-r--r--THANKS15
-rw-r--r--TODO45
-rw-r--r--beos/HBApp.cpp62
-rw-r--r--beos/HBApp.h26
-rw-r--r--beos/HBWindow.cpp283
-rw-r--r--beos/HBWindow.h41
-rw-r--r--beos/MainWindow.cpp986
-rw-r--r--beos/MainWindow.h121
-rw-r--r--beos/PicWindow.cpp369
-rw-r--r--beos/PicWindow.h54
-rw-r--r--beos/QueueWindow.cpp132
-rw-r--r--beos/QueueWindow.h38
-rw-r--r--beos/ScanWindow.cpp320
-rw-r--r--beos/ScanWindow.h56
-rw-r--r--beos/Stepper.cpp130
-rw-r--r--beos/Stepper.h31
-rw-r--r--beos/liblayout/HGroup.h40
-rw-r--r--beos/liblayout/LayeredGroup.h37
-rw-r--r--beos/liblayout/MApplication.h29
-rw-r--r--beos/liblayout/MBViewWrapper.h30
-rw-r--r--beos/liblayout/MBorder.h68
-rw-r--r--beos/liblayout/MButton.h53
-rw-r--r--beos/liblayout/MCheckBox.h33
-rw-r--r--beos/liblayout/MDividable.h35
-rw-r--r--beos/liblayout/MDragBar.h38
-rw-r--r--beos/liblayout/MEject.h23
-rw-r--r--beos/liblayout/MFFWD.h24
-rw-r--r--beos/liblayout/MGroup.h31
-rw-r--r--beos/liblayout/MListView.h30
-rw-r--r--beos/liblayout/MMenuBar.h33
-rw-r--r--beos/liblayout/MOutlineListView.h32
-rw-r--r--beos/liblayout/MPictureButton.h55
-rw-r--r--beos/liblayout/MPlayBW.h23
-rw-r--r--beos/liblayout/MPlayFW.h22
-rw-r--r--beos/liblayout/MPopup.h45
-rw-r--r--beos/liblayout/MProgressBar.h58
-rw-r--r--beos/liblayout/MRadioGroup.h46
-rw-r--r--beos/liblayout/MRew.h22
-rw-r--r--beos/liblayout/MScrollView.h39
-rw-r--r--beos/liblayout/MSlider.h30
-rw-r--r--beos/liblayout/MSplitter.h38
-rw-r--r--beos/liblayout/MStop.h22
-rw-r--r--beos/liblayout/MStringView.h25
-rw-r--r--beos/liblayout/MTabView.h33
-rw-r--r--beos/liblayout/MTextControl.h36
-rw-r--r--beos/liblayout/MTextView.h31
-rw-r--r--beos/liblayout/MVolume.h48
-rw-r--r--beos/liblayout/MWindow.h62
-rw-r--r--beos/liblayout/PropGadget.h75
-rw-r--r--beos/liblayout/Space.h22
-rw-r--r--beos/liblayout/SpinButton.h78
-rw-r--r--beos/liblayout/TabGroup.h46
-rw-r--r--beos/liblayout/VGroup.h41
-rw-r--r--beos/liblayout/layout-all.h35
-rw-r--r--beos/liblayout/layout.h168
-rwxr-xr-xconfigure90
-rw-r--r--contrib/Jamfile270
-rw-r--r--contrib/version_a52dec.txt1
-rw-r--r--contrib/version_faac.txt1
-rw-r--r--contrib/version_ffmpeg.txt1
-rw-r--r--contrib/version_lame.txt1
-rw-r--r--contrib/version_libdvdcss.txt1
-rw-r--r--contrib/version_libdvdread.txt1
-rw-r--r--contrib/version_libogg.txt1
-rw-r--r--contrib/version_libsamplerate.txt1
-rw-r--r--contrib/version_libvorbis.txt1
-rw-r--r--contrib/version_mpeg2dec.txt1
-rw-r--r--contrib/version_mpeg4ip.txt1
-rw-r--r--contrib/version_x264.txt1
-rw-r--r--contrib/version_xvidcore.txt1
-rw-r--r--core/Ac3Dec.c157
-rw-r--r--core/AviMux.c559
-rw-r--r--core/DVDRead.c257
-rw-r--r--core/FaacEnc.c140
-rw-r--r--core/FfmpegEnc.c255
-rw-r--r--core/Fifo.c135
-rw-r--r--core/Fifo.h217
-rw-r--r--core/HBInternal.h86
-rw-r--r--core/HandBrake.c780
-rw-r--r--core/HandBrake.h75
-rw-r--r--core/Jamfile39
-rw-r--r--core/LpcmDec.c124
-rw-r--r--core/Mp3Enc.c138
-rw-r--r--core/Mp4Mux.c197
-rw-r--r--core/Mpeg2Dec.c160
-rw-r--r--core/MpgaDec.c132
-rw-r--r--core/Mux.c228
-rw-r--r--core/Mux.h21
-rw-r--r--core/OgmMux.c396
-rw-r--r--core/Resample.c159
-rw-r--r--core/Scale.c140
-rw-r--r--core/Scan.c597
-rw-r--r--core/Thread.c187
-rw-r--r--core/Thread.h144
-rw-r--r--core/Utils.c379
-rw-r--r--core/Utils.h219
-rw-r--r--core/VorbisEnc.c172
-rw-r--r--core/Work.c176
-rw-r--r--core/Work.h21
-rw-r--r--core/X264Enc.c155
-rw-r--r--core/XvidEnc.c247
-rw-r--r--doc/faq.txt147
-rwxr-xr-xdoc/genhtml.sh42
-rw-r--r--libhb/Jamfile18
-rw-r--r--libhb/common.c502
-rw-r--r--libhb/common.h349
-rw-r--r--libhb/deca52.c200
-rw-r--r--libhb/decavcodec.c137
-rw-r--r--libhb/declpcm.c113
-rw-r--r--libhb/decmpeg2.c253
-rw-r--r--libhb/decsub.c420
-rw-r--r--libhb/demuxmpeg.c125
-rw-r--r--libhb/dvd.c735
-rw-r--r--libhb/encavcodec.c201
-rw-r--r--libhb/encfaac.c166
-rw-r--r--libhb/enclame.c154
-rw-r--r--libhb/encvorbis.c205
-rw-r--r--libhb/encx264.c221
-rw-r--r--libhb/encxvid.c222
-rw-r--r--libhb/fifo.c180
-rw-r--r--libhb/hb.c514
-rw-r--r--libhb/hb.h76
-rw-r--r--libhb/internal.h172
-rw-r--r--libhb/lang.h (renamed from core/Languages.h)37
-rw-r--r--libhb/muxavi.c551
-rw-r--r--libhb/muxcommon.c215
-rw-r--r--libhb/muxmp4.c160
-rw-r--r--libhb/muxogm.c364
-rw-r--r--libhb/ports.c593
-rw-r--r--libhb/ports.h86
-rw-r--r--libhb/reader.c155
-rw-r--r--libhb/render.c167
-rw-r--r--libhb/scan.c491
-rw-r--r--libhb/sync.c664
-rw-r--r--libhb/update.c157
-rw-r--r--libhb/work.c400
-rw-r--r--macosx/Controller.h217
-rw-r--r--macosx/Controller.mm1496
-rw-r--r--macosx/English.lproj/MainMenu.nib/classes.nib226
-rw-r--r--macosx/English.lproj/MainMenu.nib/info.nib21
-rw-r--r--macosx/English.lproj/MainMenu.nib/keyedobjects.nibbin0 -> 56340 bytes
-rw-r--r--macosx/English.lproj/MainMenu.nib/objects.nibbin20043 -> 0 bytes
-rw-r--r--macosx/HandBrake.icnsbin64031 -> 47214 bytes
-rw-r--r--macosx/HandBrake.xcode/project.pbxproj560
-rw-r--r--macosx/HandBrake.xcodeproj/project.pbxproj502
-rw-r--r--macosx/Info.plist36
-rw-r--r--macosx/PictureController.h55
-rw-r--r--macosx/PictureController.mm228
-rw-r--r--macosx/PictureGLView.h40
-rw-r--r--macosx/PictureGLView.mm561
-rw-r--r--macosx/PrefsController.h15
-rw-r--r--macosx/PrefsController.m47
-rw-r--r--macosx/QueueController.h18
-rw-r--r--macosx/QueueController.mm120
-rw-r--r--macosx/ScanController.h47
-rw-r--r--macosx/ScanController.mm272
-rw-r--r--macosx/TargetSizeField.h24
-rw-r--r--macosx/TargetSizeField.mm48
-rwxr-xr-xmacosx/genstrings.sh2
-rw-r--r--macosx/i18n/Localizable.stringsbin9912 -> 8426 bytes
-rw-r--r--macosx/i18n/fr.stringsbin10100 -> 8246 bytes
-rw-r--r--macosx/main.mm4
-rw-r--r--test/test.c805
-rw-r--r--wx/hb32x32.xpm295
-rw-r--r--wx/hbWizard.cpp1259
-rw-r--r--wx/hbWizard.h43
-rw-r--r--wx/wxHB.cpp684
-rw-r--r--wx/wxHB.h170
173 files changed, 17554 insertions, 11149 deletions
diff --git a/AUTHORS b/AUTHORS
index d5fa5bf7b..744cdf8b7 100644
--- 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 <[email protected]>
+ 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 <[email protected]>
+ H264 and Vorbis encoders (w/ libx264/libvorbis)
+ OGG/OGM muxer (w/ libogg)
+ Gtk2 interface
+ + wxWidgets interface
diff --git a/BUILD b/BUILD
index 6eb184e86..413644061 100644
--- 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 ([email protected]).
-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 2399c9197..8066a1bd9 100644
--- 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 ;
diff --git a/Jamrules b/Jamrules
index ff970c26b..6b15be6a3 100644
--- a/Jamrules
+++ b/Jamrules
@@ -1,116 +1,21 @@
-# $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 525142848..9f06cfe13 100644
--- 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 ec543c2b6..81b04f46c 100644
--- 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
index cfa765a2e..000000000
--- 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
-
diff --git a/beos/HBApp.cpp b/beos/HBApp.cpp
index add6259f2..702c74d94 100644
--- a/beos/HBApp.cpp
+++ b/beos/HBApp.cpp
@@ -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();
+}
+
diff --git a/beos/HBApp.h b/beos/HBApp.h
index 75f3fc173..042a791b9 100644
--- a/beos/HBApp.h
+++ b/beos/HBApp.h
@@ -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
index 4bb51d61f..000000000
--- a/beos/HBWindow.cpp
+++ /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
index 52ddfbf1b..000000000
--- a/beos/HBWindow.h
+++ /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
index 000000000..5b2741bb9
--- /dev/null
+++ b/beos/MainWindow.cpp
@@ -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
index 000000000..1558556f0
--- /dev/null
+++ b/beos/MainWindow.h
@@ -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
index 000000000..6b30f27c2
--- /dev/null
+++ b/beos/PicWindow.cpp
@@ -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
index 000000000..9fe5d3131
--- /dev/null
+++ b/beos/PicWindow.h
@@ -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
index 000000000..2b0319e32
--- /dev/null
+++ b/beos/QueueWindow.cpp
@@ -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
index 000000000..e9b86e3a7
--- /dev/null
+++ b/beos/QueueWindow.h
@@ -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
index 000000000..615731f11
--- /dev/null
+++ b/beos/ScanWindow.cpp
@@ -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
index 000000000..f46c1c14f
--- /dev/null
+++ b/beos/ScanWindow.h
@@ -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
index 000000000..8f2733ac5
--- /dev/null
+++ b/beos/Stepper.cpp
@@ -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
index 000000000..2b0493f6e
--- /dev/null
+++ b/beos/Stepper.h
@@ -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
index 9eee83fea..000000000
--- a/beos/liblayout/HGroup.h
+++ /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
index 61264ca36..000000000
--- a/beos/liblayout/LayeredGroup.h
+++ /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
index acdd13214..000000000
--- a/beos/liblayout/MApplication.h
+++ /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
index 351dfb800..000000000
--- a/beos/liblayout/MBViewWrapper.h
+++ /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
index 4e925ec2d..000000000
--- a/beos/liblayout/MBorder.h
+++ /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
index 64cd3e32b..000000000
--- a/beos/liblayout/MButton.h
+++ /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
index 7b39abda2..000000000
--- a/beos/liblayout/MCheckBox.h
+++ /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
index 800772b88..000000000
--- a/beos/liblayout/MDividable.h
+++ /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
index e345668c4..000000000
--- a/beos/liblayout/MDragBar.h
+++ /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
index a9c017346..000000000
--- a/beos/liblayout/MEject.h
+++ /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
index 97c0d53e1..000000000
--- a/beos/liblayout/MFFWD.h
+++ /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
index 73dcbfb9c..000000000
--- a/beos/liblayout/MGroup.h
+++ /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
index 95c4d42ca..000000000
--- a/beos/liblayout/MListView.h
+++ /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
index a5b061a19..000000000
--- a/beos/liblayout/MMenuBar.h
+++ /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
index acb00e19b..000000000
--- a/beos/liblayout/MOutlineListView.h
+++ /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
index 687b5c28a..000000000
--- a/beos/liblayout/MPictureButton.h
+++ /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
index 043aa46d3..000000000
--- a/beos/liblayout/MPlayBW.h
+++ /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
index 7f847df7b..000000000
--- a/beos/liblayout/MPlayFW.h
+++ /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
index 2223664ec..000000000
--- a/beos/liblayout/MPopup.h
+++ /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
index 3938c2583..000000000
--- a/beos/liblayout/MProgressBar.h
+++ /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
index bb430f2da..000000000
--- a/beos/liblayout/MRadioGroup.h
+++ /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
index f21683b5d..000000000
--- a/beos/liblayout/MRew.h
+++ /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
index 8ba21ce0e..000000000
--- a/beos/liblayout/MScrollView.h
+++ /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
index 6e7077d3d..000000000
--- a/beos/liblayout/MSlider.h
+++ /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
index 411c5d14f..000000000
--- a/beos/liblayout/MSplitter.h
+++ /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
index b99fc2fe4..000000000
--- a/beos/liblayout/MStop.h
+++ /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
index 4db74452e..000000000
--- a/beos/liblayout/MStringView.h
+++ /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
index 04c69ec59..000000000
--- a/beos/liblayout/MTabView.h
+++ /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
index 46f1a746f..000000000
--- a/beos/liblayout/MTextControl.h
+++ /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
index 512a85cd1..000000000
--- a/beos/liblayout/MTextView.h
+++ /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
index 9d70b7955..000000000
--- a/beos/liblayout/MVolume.h
+++ /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
index 6118f87bc..000000000
--- a/beos/liblayout/MWindow.h
+++ /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
index 81a3f1f9b..000000000
--- a/beos/liblayout/PropGadget.h
+++ /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
index c49f6fbd2..000000000
--- a/beos/liblayout/Space.h
+++ /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
index 3bb00db69..000000000
--- a/beos/liblayout/SpinButton.h
+++ /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
index 64a2cf9cc..000000000
--- a/beos/liblayout/TabGroup.h
+++ /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
index 56be070df..000000000
--- a/beos/liblayout/VGroup.h
+++ /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
index b2e78df10..000000000
--- a/beos/liblayout/layout-all.h
+++ /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
index 772b251db..000000000
--- a/beos/liblayout/layout.h
+++ /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
index 000000000..d0c292873
--- /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
index 000000000..5bdf71bfa
--- /dev/null
+++ b/contrib/Jamfile
@@ -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
index 000000000..86617fd36
--- /dev/null
+++ b/contrib/version_a52dec.txt
@@ -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
index 000000000..e3466666b
--- /dev/null
+++ b/contrib/version_faac.txt
@@ -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
index 000000000..b8a5c6f6e
--- /dev/null
+++ b/contrib/version_ffmpeg.txt
@@ -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
index 000000000..b4bb63c81
--- /dev/null
+++ b/contrib/version_lame.txt
@@ -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
index 000000000..81d1ef157
--- /dev/null
+++ b/contrib/version_libdvdcss.txt
@@ -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
index 000000000..b7be38fd7
--- /dev/null
+++ b/contrib/version_libdvdread.txt
@@ -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
index 000000000..57daaf702
--- /dev/null
+++ b/contrib/version_libogg.txt
@@ -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
index 000000000..a0f5b3804
--- /dev/null
+++ b/contrib/version_libsamplerate.txt
@@ -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
index 000000000..db3f67caf
--- /dev/null
+++ b/contrib/version_libvorbis.txt
@@ -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
index 000000000..87a73c92a
--- /dev/null
+++ b/contrib/version_mpeg2dec.txt
@@ -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
index 000000000..f60e5972a
--- /dev/null
+++ b/contrib/version_mpeg4ip.txt
@@ -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
index 000000000..560f081ab
--- /dev/null
+++ b/contrib/version_x264.txt
@@ -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
index 000000000..573cd3c8a
--- /dev/null
+++ b/contrib/version_xvidcore.txt
@@ -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
index ef805588c..000000000
--- a/core/Ac3Dec.c
+++ /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
index c0209dd49..000000000
--- a/core/AviMux.c
+++ /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
index 4c36f3942..000000000
--- a/core/DVDRead.c
+++ /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
index 689e6e18f..000000000
--- a/core/FaacEnc.c
+++ /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
index ae474d00b..000000000
--- a/core/FfmpegEnc.c
+++ /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
index ae0c412da..000000000
--- a/core/Fifo.c
+++ /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
index 26c4b5581..000000000
--- a/core/Fifo.h
+++ /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
index 4fa45f8b0..000000000
--- a/core/HBInternal.h
+++ /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
index 6d16b4640..000000000
--- a/core/HandBrake.c
+++ /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
index 9d84d39dc..000000000
--- a/core/HandBrake.h
+++ /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
index 3c683531b..000000000
--- a/core/Jamfile
+++ /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
index 425f429d9..000000000
--- a/core/LpcmDec.c
+++ /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
index c1aae34fe..000000000
--- a/core/Mp3Enc.c
+++ /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
index d48c1adc6..000000000
--- a/core/Mp4Mux.c
+++ /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
index 043c416dc..000000000
--- a/core/Mpeg2Dec.c
+++ /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
index e397a7234..000000000
--- a/core/MpgaDec.c
+++ /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
index c9449e7ff..000000000
--- a/core/Mux.c
+++ /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
index fbd1fd98f..000000000
--- a/core/Mux.h
+++ /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
index e99a494f5..000000000
--- a/core/OgmMux.c
+++ /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
index f3632b371..000000000
--- a/core/Resample.c
+++ /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
index 2908d6456..000000000
--- a/core/Scale.c
+++ /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
index 9315e59d0..000000000
--- a/core/Scan.c
+++ /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
index 9379223f0..000000000
--- a/core/Thread.c
+++ /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
index bf343214d..000000000
--- a/core/Thread.h
+++ /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
index 45ebf7bd4..000000000
--- a/core/Utils.c
+++ /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
index fce20e557..000000000
--- a/core/Utils.h
+++ /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
index 8b7b10f8f..000000000
--- a/core/VorbisEnc.c
+++ /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
index e23af2421..000000000
--- a/core/Work.c
+++ /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
index b764e1160..000000000
--- a/core/Work.h
+++ /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
index be8d76709..000000000
--- a/core/X264Enc.c
+++ /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
index 4c06da69e..000000000
--- a/core/XvidEnc.c
+++ /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
index 6375637de..000000000
--- a/doc/faq.txt
+++ /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
index a88d4149a..000000000
--- a/doc/genhtml.sh
+++ /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
index 000000000..29f9c7774
--- /dev/null
+++ b/libhb/Jamfile
@@ -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
index 000000000..7bd125c84
--- /dev/null
+++ b/libhb/common.c
@@ -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
index 000000000..402ae7f29
--- /dev/null
+++ b/libhb/common.h
@@ -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
index 000000000..a4f7492b3
--- /dev/null
+++ b/libhb/deca52.c
@@ -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
index 000000000..f18579f36
--- /dev/null
+++ b/libhb/decavcodec.c
@@ -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
index 000000000..59163c366
--- /dev/null
+++ b/libhb/declpcm.c
@@ -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
index 000000000..d914c03a6
--- /dev/null
+++ b/libhb/decmpeg2.c
@@ -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
index 000000000..72f742bd9
--- /dev/null
+++ b/libhb/decsub.c
@@ -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
index 000000000..721478e80
--- /dev/null
+++ b/libhb/demuxmpeg.c
@@ -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
index 000000000..9b2aef13b
--- /dev/null
+++ b/libhb/dvd.c
@@ -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
index 000000000..deff7c527
--- /dev/null
+++ b/libhb/encavcodec.c
@@ -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
index 000000000..a5b704f4c
--- /dev/null
+++ b/libhb/encfaac.c
@@ -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
index 000000000..19014ac26
--- /dev/null
+++ b/libhb/enclame.c
@@ -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
index 000000000..86b824372
--- /dev/null
+++ b/libhb/encvorbis.c
@@ -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
index 000000000..cf58452e7
--- /dev/null
+++ b/libhb/encx264.c
@@ -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
index 000000000..a874d9f00
--- /dev/null
+++ b/libhb/encxvid.c
@@ -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
index 000000000..81ca2a184
--- /dev/null
+++ b/libhb/fifo.c
@@ -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
index 000000000..f27a353bc
--- /dev/null
+++ b/libhb/hb.c
@@ -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
index 000000000..4a64c9047
--- /dev/null
+++ b/libhb/hb.h
@@ -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
index 000000000..e22da82ee
--- /dev/null
+++ b/libhb/internal.h
@@ -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 );
+
diff --git a/core/Languages.h b/libhb/lang.h
index 7949688c9..f88f539ff 100644
--- a/core/Languages.h
+++ b/libhb/lang.h
@@ -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
index 000000000..8746a3cdd
--- /dev/null
+++ b/libhb/muxavi.c
@@ -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
index 000000000..090f332b2
--- /dev/null
+++ b/libhb/muxcommon.c
@@ -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
index 000000000..a02a05232
--- /dev/null
+++ b/libhb/muxmp4.c
@@ -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
index 000000000..d326c9828
--- /dev/null
+++ b/libhb/muxogm.c
@@ -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
index 000000000..20c2cae94
--- /dev/null
+++ b/libhb/ports.c
@@ -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
index 000000000..4639c6b93
--- /dev/null
+++ b/libhb/ports.h
@@ -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
index 000000000..e57467d8d
--- /dev/null
+++ b/libhb/reader.c
@@ -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
index 000000000..914fa3995
--- /dev/null
+++ b/libhb/render.c
@@ -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
index 000000000..812e84026
--- /dev/null
+++ b/libhb/scan.c
@@ -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
index 000000000..e0530a03a
--- /dev/null
+++ b/libhb/sync.c
@@ -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
index 000000000..767807038
--- /dev/null
+++ b/libhb/update.c
@@ -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
index 000000000..6c0be24e3
--- /dev/null
+++ b/libhb/work.c
@@ -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;
+ }
+}
diff --git a/macosx/Controller.h b/macosx/Controller.h
index 400246af8..c32dacc04 100644
--- a/macosx/Controller.h
+++ b/macosx/Controller.h
@@ -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/>.
@@ -6,153 +6,138 @@
#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
diff --git a/macosx/Controller.mm b/macosx/Controller.mm
index eb53a9dd5..a4ba98afe 100644
--- a/macosx/Controller.mm
+++ b/macosx/Controller.mm
@@ -1,229 +1,488 @@
-/* $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
diff --git a/macosx/English.lproj/MainMenu.nib/classes.nib b/macosx/English.lproj/MainMenu.nib/classes.nib
index b77248ae6..59629f07f 100644
--- a/macosx/English.lproj/MainMenu.nib/classes.nib
+++ b/macosx/English.lproj/MainMenu.nib/classes.nib
@@ -3,102 +3,85 @@
{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;
@@ -115,7 +98,82 @@
};
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
diff --git a/macosx/English.lproj/MainMenu.nib/info.nib b/macosx/English.lproj/MainMenu.nib/info.nib
index 07d1cfa67..0854e6d3d 100644
--- a/macosx/English.lproj/MainMenu.nib/info.nib
+++ b/macosx/English.lproj/MainMenu.nib/info.nib
@@ -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
index 000000000..9d8af0121
--- /dev/null
+++ b/macosx/English.lproj/MainMenu.nib/keyedobjects.nib
Binary files differ
diff --git a/macosx/English.lproj/MainMenu.nib/objects.nib b/macosx/English.lproj/MainMenu.nib/objects.nib
deleted file mode 100644
index 5a2d37443..000000000
--- a/macosx/English.lproj/MainMenu.nib/objects.nib
+++ /dev/null
Binary files differ
diff --git a/macosx/HandBrake.icns b/macosx/HandBrake.icns
index f1d08d36f..f81352be3 100644
--- a/macosx/HandBrake.icns
+++ b/macosx/HandBrake.icns
Binary files differ
diff --git a/macosx/HandBrake.xcode/project.pbxproj b/macosx/HandBrake.xcode/project.pbxproj
deleted file mode 100644
index c9ac3a6a3..000000000
--- a/macosx/HandBrake.xcode/project.pbxproj
+++ /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;[email protected]&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
index 000000000..e733e1991
--- /dev/null
+++ b/macosx/HandBrake.xcodeproj/project.pbxproj
@@ -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
index 000000000..f7df901d4
--- /dev/null
+++ b/macosx/Info.plist
@@ -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;[email protected]&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
index 000000000..3a279e133
--- /dev/null
+++ b/macosx/PictureController.h
@@ -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
index 000000000..f4e9d51d9
--- /dev/null
+++ b/macosx/PictureController.mm
@@ -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
diff --git a/macosx/PictureGLView.h b/macosx/PictureGLView.h
index c558c3c0f..229d822ac 100644
--- a/macosx/PictureGLView.h
+++ b/macosx/PictureGLView.h
@@ -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
diff --git a/macosx/PictureGLView.mm b/macosx/PictureGLView.mm
index dbb641729..611fb3a86 100644
--- a/macosx/PictureGLView.mm
+++ b/macosx/PictureGLView.mm
@@ -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/>.
@@ -6,146 +6,35 @@
#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
index 000000000..cdd960f89
--- /dev/null
+++ b/macosx/PrefsController.h
@@ -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
index 000000000..8e7c865e2
--- /dev/null
+++ b/macosx/PrefsController.m
@@ -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
index 000000000..635adc7b8
--- /dev/null
+++ b/macosx/QueueController.h
@@ -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
index 000000000..e775bb33d
--- /dev/null
+++ b/macosx/QueueController.mm
@@ -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
index 000000000..d038e6eea
--- /dev/null
+++ b/macosx/ScanController.h
@@ -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
index 000000000..5a4075416
--- /dev/null
+++ b/macosx/ScanController.mm
@@ -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
index d9396ee3a..000000000
--- a/macosx/TargetSizeField.h
+++ /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
index e113a4bf1..000000000
--- a/macosx/TargetSizeField.mm
+++ /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
diff --git a/macosx/genstrings.sh b/macosx/genstrings.sh
index 38da1de92..3c3215777 100755
--- a/macosx/genstrings.sh
+++ b/macosx/genstrings.sh
@@ -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
diff --git a/macosx/i18n/Localizable.strings b/macosx/i18n/Localizable.strings
index cbad7b524..d2415f302 100644
--- a/macosx/i18n/Localizable.strings
+++ b/macosx/i18n/Localizable.strings
Binary files differ
diff --git a/macosx/i18n/fr.strings b/macosx/i18n/fr.strings
index c1218f28c..a2841c40e 100644
--- a/macosx/i18n/fr.strings
+++ b/macosx/i18n/fr.strings
Binary files differ
diff --git a/macosx/main.mm b/macosx/main.mm
index bd649f8ba..78f659e03 100644
--- a/macosx/main.mm
+++ b/macosx/main.mm
@@ -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 )
{
diff --git a/test/test.c b/test/test.c
index 67b9450a9..3f250bc6c 100644
--- a/test/test.c
+++ b/test/test.c
@@ -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/>.
@@ -7,91 +7,446 @@
#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
index 000000000..baa88bca4
--- /dev/null
+++ b/wx/hb32x32.xpm
@@ -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{ [email protected].=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.: [email protected] 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
index 000000000..c9473067c
--- /dev/null
+++ b/wx/hbWizard.cpp
@@ -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
index 000000000..a66413abe
--- /dev/null
+++ b/wx/hbWizard.h
@@ -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
index 000000000..b336290dd
--- /dev/null
+++ b/wx/wxHB.cpp
@@ -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
index 000000000..c762305d7
--- /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;
+}