summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CREDITS220
-rw-r--r--Jamfile53
-rw-r--r--NEWS6
-rw-r--r--TODO21
-rw-r--r--beos/HBApp.cpp (renamed from beos/HandBrake.cpp)6
-rw-r--r--beos/HBApp.h (renamed from beos/HandBrake.h)8
-rw-r--r--beos/MainWindow.cpp61
-rw-r--r--beos/MainWindow.h8
-rw-r--r--beos/PictureWin.cpp45
-rw-r--r--beos/PictureWin.h11
-rw-r--r--beos/RipView.cpp393
-rw-r--r--beos/RipView.h27
-rw-r--r--beos/ScanView.cpp50
-rw-r--r--beos/ScanView.h12
-rw-r--r--core/Ac3Dec.c219
-rw-r--r--core/Ac3Dec.h15
-rw-r--r--core/Ac3Decoder.cpp204
-rw-r--r--core/Ac3Decoder.h47
-rw-r--r--core/AviMux.c640
-rw-r--r--core/AviMux.h15
-rw-r--r--core/AviMuxer.cpp481
-rw-r--r--core/AviMuxer.h153
-rw-r--r--core/Common.cpp288
-rw-r--r--core/Common.h215
-rw-r--r--core/DVDRead.c328
-rw-r--r--core/DVDRead.h16
-rw-r--r--core/DVDReader.cpp99
-rw-r--r--core/DVDReader.h25
-rw-r--r--core/FfmpegEnc.c230
-rw-r--r--core/FfmpegEnc.h15
-rw-r--r--core/Fifo.c105
-rw-r--r--core/Fifo.cpp120
-rw-r--r--core/Fifo.h100
-rw-r--r--core/HandBrake.c767
-rw-r--r--core/HandBrake.h55
-rw-r--r--core/HandBrakeInternal.h35
-rw-r--r--core/Languages.h6
-rw-r--r--core/MadDec.c9
-rw-r--r--core/MadDec.h15
-rw-r--r--core/Manager.cpp652
-rw-r--r--core/Manager.h64
-rw-r--r--core/Mp3Enc.c281
-rw-r--r--core/Mp3Enc.h15
-rw-r--r--core/Mp3Encoder.cpp185
-rw-r--r--core/Mp3Encoder.h43
-rw-r--r--core/Mpeg2Dec.c195
-rw-r--r--core/Mpeg2Dec.h15
-rw-r--r--core/Mpeg2Decoder.cpp175
-rw-r--r--core/Mpeg2Decoder.h40
-rw-r--r--core/Mpeg4Encoder.cpp181
-rw-r--r--core/Mpeg4Encoder.h41
-rw-r--r--core/MpegDemux.cpp308
-rw-r--r--core/MpegDemux.h43
-rw-r--r--core/Resizer.cpp138
-rw-r--r--core/Resizer.h38
-rw-r--r--core/Scale.c139
-rw-r--r--core/Scale.h15
-rw-r--r--core/Scan.c395
-rw-r--r--core/Scan.h15
-rw-r--r--core/Scanner.cpp303
-rw-r--r--core/Scanner.h27
-rw-r--r--core/Thread.c138
-rw-r--r--core/Thread.cpp160
-rw-r--r--core/Thread.h81
-rw-r--r--core/Utils.c352
-rw-r--r--core/Utils.h213
-rw-r--r--core/Work.c187
-rw-r--r--core/Work.h27
-rw-r--r--core/Worker.cpp150
-rw-r--r--core/Worker.h28
-rw-r--r--core/XvidEnc.c170
-rw-r--r--core/XvidEnc.h15
-rw-r--r--macosx/Controller.h17
-rw-r--r--macosx/Controller.mm657
-rw-r--r--macosx/English.lproj/InfoPlist.stringsbin496 -> 488 bytes
-rw-r--r--macosx/English.lproj/MainMenu.nib/classes.nib4
-rw-r--r--macosx/English.lproj/MainMenu.nib/info.nib20
-rw-r--r--macosx/English.lproj/MainMenu.nib/objects.nibbin17820 -> 18217 bytes
-rw-r--r--macosx/HandBrake.pbproj/project.pbxproj146
-rw-r--r--macosx/PictureGLView.h24
-rw-r--r--macosx/PictureGLView.mm258
-rw-r--r--macosx/TargetSizeField.h6
-rw-r--r--macosx/TargetSizeField.mm12
-rw-r--r--macosx/main.mm4
-rw-r--r--test/Test.cpp265
-rw-r--r--test/test.c237
86 files changed, 6210 insertions, 5392 deletions
diff --git a/CREDITS b/CREDITS
index 110e1cc02..4000b2ddc 100644
--- a/CREDITS
+++ b/CREDITS
@@ -1,117 +1,123 @@
HandBrake uses a lot of cool libraries from the GNU/Linux world. Thank
their authors !
-libdvdcss authors :
+liba52 authors:
+ Aaron Holtzman
+ Michel Lespinasse
+ Gildas Bazin
+ Billy Biggs
+ Eduard Hasenleithner
+ H�kan Hjort
+ Charles M. Hannum
+ Chris Hodges
+ Michael Holzt
+ Angelos Keromytis
+ David I. Lehn
+ Don Mahurin
+ Jim Miller
+ Takefumi Sayo
+ Shoji Tokunaga
-Billy Biggs
-St�phane Borel
-H�kan Hjort
-Samuel Hocevar
-Eugenio Jarosiewicz
-Jon Lech Johansen
-Markus Kuespert
-Pascal Levesque
-Steven M. Schultz
-David Sieb�rger
-Alex Strelnikov
-German Tischler
-Gildas Bazin
+libavcodec authors:
+ Fabrice Bellard
+ Alex Beregszaszi
+ Brian Foley
+ Arpad Gereoffy
+ Philip Gladstone
+ Falk Hueffner
+ Zdenek Kabelac
+ Nick Kurshev
+ Michael Niedermayer
+ Fran�ois Revol
+ Dieter Shirley
+ Juan J. Sierralta
+ Lionel Ulmer
-libdvdread authors :
+libdvdcss authors:
+ Billy Biggs
+ St�phane Borel
+ H�kan Hjort
+ Samuel Hocevar
+ Eugenio Jarosiewicz
+ Jon Lech Johansen
+ Markus Kuespert
+ Pascal Levesque
+ Steven M. Schultz
+ David Sieb�rger
+ Alex Strelnikov
+ German Tischler
+ Gildas Bazin
-Bj�rn Englund
-H�kan Hjort
-Billy Biggs
-Christian Wolff
+libdvdread authors:
+ Bj�rn Englund
+ H�kan Hjort
+ Billy Biggs
+ Christian Wolff
-libdvdplay authors :
+libdvdplay authors:
+ H�kan Hjort
+ Martin Norb�ck
+ St�phane Borel
-H�kan Hjort
-Martin Norb�ck
-St�phane Borel
+libmp3lame authors:
+ Mike Cheng
+ Robert Hegemann
+ Frank Klemm
+ Alexander Leidinger
+ Naoki Shibata
+ Mark Taylor
+ Takehiro Tominiga
+ Iv�n Cavero Belaunde
+ Gabriel Bouvigne
+ Florian Bomers
+ CISC
+ John Dahlstrom
+ John Dee
+ Albert Faber
+ Peter Gubanov
+ Lars Magne Ingebrigtsen
+ Yosi Markovich
+ Zdenek Kabelac
+ Iwasa Kazmi
+ Guillaume Lessard
+ Steve Lhomme
+ Don Melton
+ Viral Shah
+ Acy Stapp
+ Roel VdB
-mpeg2dec authors :
+libmpeg2 authors:
+ Aaron Holtzman
+ Michel Lespinasse
+ Bruno Barreyra
+ Gildas Bazin
+ Alexander W. Chin
+ Stephen Crowley
+ Didier Gautheron
+ Ryan C. Gordon
+ Peter Gubanov
+ H�kan Hjort
+ Nicolas Joly
+ Gerd Knorr
+ David I. Lehn
+ Olie Lho
+ Rick Niles
+ Real Ouellet
+ Bajusz Peter
+ Franck Sicard
+ Brion Vibber
+ Martin Vogt
+ Fredrik Vraalsen
-Aaron Holtzman
-Michel Lespinasse
-Bruno Barreyra
-Gildas Bazin
-Alexander W. Chin
-Stephen Crowley
-Didier Gautheron
-Ryan C. Gordon
-Peter Gubanov
-H�kan Hjort
-Nicolas Joly
-Gerd Knorr
-David I. Lehn
-Olie Lho
-Rick Niles
-Real Ouellet
-Bajusz Peter
-Franck Sicard
-Brion Vibber
-Martin Vogt
-Fredrik Vraalsen
-
-Ffmpeg authors :
-
-Fabrice Bellard
-Alex Beregszaszi
-Brian Foley
-Arpad Gereoffy
-Philip Gladstone
-Falk Hueffner
-Zdenek Kabelac
-Nick Kurshev
-Michael Niedermayer
-Fran�ois Revol
-Dieter Shirley
-Juan J. Sierralta
-Lionel Ulmer
-
-a52dec authors :
-
-Aaron Holtzman
-Michel Lespinasse
-Gildas Bazin
-Billy Biggs
-Eduard Hasenleithner
-H�kan Hjort
-Charles M. Hannum
-Chris Hodges
-Michael Holzt
-Angelos Keromytis
-David I. Lehn
-Don Mahurin
-Jim Miller
-Takefumi Sayo
-Shoji Tokunaga
-
-lame authors :
-
-Mike Cheng
-Robert Hegemann
-Frank Klemm
-Alexander Leidinger
-Naoki Shibata
-Mark Taylor
-Takehiro Tominiga
-Iv�n Cavero Belaunde
-Gabriel Bouvigne
-Florian Bomers
-CISC
-John Dahlstrom
-John Dee
-Albert Faber
-Peter Gubanov
-Lars Magne Ingebrigtsen
-Yosi Markovich
-Zdenek Kabelac
-Iwasa Kazmi
-Guillaume Lessard
-Steve Lhomme
-Don Melton
-Viral Shah
-Acy Stapp
-Roel VdB
+libxvidcore authors:
+ Christoph Lampert
+ Michael Militzer
+ Peter Ross
+ Benjamin Herrenschmidt
+ Daniel Smith
+ Dirk Knop
+ Edouard Gomez
+ Guillaume Morin
+ MinChen
+ Pascal Massimino
+ Radoslaw Czyz
diff --git a/Jamfile b/Jamfile
index 471473592..11dd93332 100644
--- a/Jamfile
+++ b/Jamfile
@@ -1,16 +1,20 @@
-# $Id: Jamfile,v 1.41 2003/10/16 13:46:32 titer Exp $
+# $Id: Jamfile,v 1.5 2003/11/07 22:28:30 titer Exp $
#
# This file is part of the HandBrake source code.
-# Homepage: <http://beos.titer.org/handbrake/>.
+# Homepage: <http://handbrake.m0k.org/>.
# It may be used under the terms of the GNU General Public License.
-HB_VERSION = 0.4.1 ;
+HB_VERSION = 0.5 ;
# Compilers
+CC = gcc ;
C++ = g++ ;
-LINK = g++ ;
+LINK = gcc ;
# Flags
+CCFLAGS = $(CFLAGS) ;
+CCFLAGS += -g -Wall -Werror ;
+CCFLAGS += -DVERSION=\\\"$(HB_VERSION)\\\" -DSYS_$(OS) ;
C++FLAGS = $(CPPFLAGS) ;
C++FLAGS += -g -Wall -Werror ;
C++FLAGS += -DVERSION=\\\"$(HB_VERSION)\\\" -DSYS_$(OS) ;
@@ -18,15 +22,18 @@ LINKFLAGS = $(LDFLAGS) ;
HDRS = core ;
# Optims
+CCFLAGS += -funroll-loops ;
C++FLAGS += -funroll-loops ;
OPTIM = -O3 ;
# Libs
-LINKLIBS = -ldvdplay -ldvdread -ldvdcss -lmpeg2 -lavcodec -la52 -lmp3lame ;
+LINKLIBS = -ldvdplay -ldvdread -ldvdcss -lmpeg2 -lavcodec -la52
+ -lmp3lame -lxvidcore ;
# OS specific
if $(OS) = BEOS
{
+ CCFLAGS += -Wno-multichar ;
C++FLAGS += -Wno-multichar ;
LINKLIBS += -lbe -ltracker ;
}
@@ -36,9 +43,19 @@ else if $(OS) = LINUX
}
else if $(OS) = MACOSX
{
+ CCFLAGS += -no-cpp-precomp ;
+ C++FLAGS += -no-cpp-precomp ;
+ LINKFLAGS += -multiply_defined suppress ;
+
# needed to clean HandBrake.app
RM = rm -rf ;
}
+else if $(OS) = CYGWIN
+{
+ CCFLAGS += -mno-cygwin ;
+ C++FLAGS += -mno-cygwin ;
+ LINKFLAGS += -mno-cygwin ;
+}
# Do not remove temporary object files
# There MUST be a cleaner way to do this
@@ -46,36 +63,36 @@ actions quietly updated piecemeal together RmTemps
{
}
-# Build HandBrake.app using ProjectBuilder
+# Build HandBrake.app using Xcode
rule OSXApp
{
- Clean clean : $(1) ;
+ Clean clean : $(1) macosx/build ;
BuildOSXApp $(1) ;
}
actions BuildOSXApp
{
$(RM) HandBrake.app ;
- ( cd macosx && pbxbuild ) && mv macosx/build/HandBrake.app . ;
- $(RM) macosx/build ;
+ ( cd macosx && xcodebuild ) && cp -r macosx/build/HandBrake.app . ;
}
-Library core/libhb : core/Ac3Decoder.cpp core/AviMuxer.cpp
- core/Common.cpp core/DVDReader.cpp core/Fifo.cpp
- core/Manager.cpp core/Mp3Encoder.cpp
- core/Mpeg2Decoder.cpp core/Mpeg4Encoder.cpp
- core/MpegDemux.cpp core/Resizer.cpp
- core/Scanner.cpp core/Thread.cpp core/Worker.cpp ;
+Library core/libhb : core/Ac3Dec.c core/AviMux.c
+ core/Utils.c core/DVDRead.c core/Fifo.c
+ core/HandBrake.c core/Mp3Enc.c
+ core/Mpeg2Dec.c core/FfmpegEnc.c
+ core/MadDec.c core/Scale.c
+ core/Scan.c core/Thread.c core/Work.c
+ core/XvidEnc.c ;
LinkLibraries HBTest : core/libhb.a ;
-Main HBTest : test/Test.cpp ;
+Main HBTest : test/test.c ;
if $(OS) = BEOS
{
LinkLibraries HandBrake : core/libhb.a ;
- Main HandBrake : beos/HandBrake.cpp beos/MainWindow.cpp
+ Main HandBrake : beos/HBApp.cpp beos/MainWindow.cpp
beos/PictureWin.cpp beos/ScanView.cpp
- beos/RipView.cpp ;
+ beos/RipView.cpp ;
}
if $(OS) = MACOSX
diff --git a/NEWS b/NEWS
index b3bc5cb27..f89ef3da2 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,8 @@
-$Id: NEWS,v 1.11 2003/10/13 15:35:38 titer Exp $
+$Id: NEWS,v 1.3 2003/11/07 21:52:56 titer Exp $
+
+Changes between 0.4 and 0.5
+ - Bugfixes, rewrite of large parts of the core
+ - XviD encoding (1-pass only)
Changes between 0.3 and 0.4
- Better multithreading
diff --git a/TODO b/TODO
index 127cc12a6..080df3253 100644
--- a/TODO
+++ b/TODO
@@ -1,8 +1,17 @@
-- General
- + Use the DVD name in popup and for the name of the created file
- + Show the current pass
+- Core
+ Should be able to boost the audio volume
+ + Allow the intf to preview the latest encoded picture
+ + Finish and test the MPEG audio decoder
+ + More encoding options: B-frames, type of estimation,
+ type of scaling, etc
+ + Subtitle support
+ + Finish xvid encoding support (2-pass, more tests)
+ + Allow the user to split the file in x parts
+ + AAC & vorbis encoding support
+ + mp4 & mkv muxing support
+
+- All interfaces
+ + Use the DVD name in popup and for the name of the created file
-- OSX port
- + Preview in a drawer
- + Prompt before overwriting a file
+- BeOS interface
+ + Redo the picture panel
diff --git a/beos/HandBrake.cpp b/beos/HBApp.cpp
index b5f13196b..52afce815 100644
--- a/beos/HandBrake.cpp
+++ b/beos/HBApp.cpp
@@ -1,12 +1,12 @@
-/* $Id: HandBrake.cpp,v 1.8 2003/10/13 22:23:02 titer Exp $
+/* $Id: HBApp.cpp,v 1.1.1.1 2003/11/03 12:03:51 titer Exp $
This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
+ Homepage: <http://handbrake.m0k.org/>.
It may be used under the terms of the GNU General Public License. */
#include <signal.h>
-#include "HandBrake.h"
+#include "HBApp.h"
#include "MainWindow.h"
void SigHandler( int signal )
diff --git a/beos/HandBrake.h b/beos/HBApp.h
index 7035b5487..fb5c41c38 100644
--- a/beos/HandBrake.h
+++ b/beos/HBApp.h
@@ -1,11 +1,11 @@
-/* $Id: HandBrake.h,v 1.7 2003/10/13 22:23:02 titer Exp $
+/* $Id: HBApp.h,v 1.1.1.1 2003/11/03 12:03:51 titer Exp $
This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
+ 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
+#ifndef HB_HB_APP_H
+#define HB_HB_APP_H
#include <Application.h>
diff --git a/beos/MainWindow.cpp b/beos/MainWindow.cpp
index 613cf21df..bf52caa84 100644
--- a/beos/MainWindow.cpp
+++ b/beos/MainWindow.cpp
@@ -1,14 +1,13 @@
-/* $Id: MainWindow.cpp,v 1.19 2003/10/13 22:23:02 titer Exp $
+/* $Id: MainWindow.cpp,v 1.3 2003/11/07 21:52:56 titer Exp $
This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
+ Homepage: <http://handbrake.m0k.org/>.
It may be used under the terms of the GNU General Public License. */
#include <Alert.h>
#include <Application.h>
#include <Screen.h>
-#include "Manager.h"
#include "MainWindow.h"
#include "ScanView.h"
#include "RipView.h"
@@ -17,17 +16,16 @@ MainWindow::MainWindow()
: BWindow( BRect( 0,0,10,10 ), "HandBrake " VERSION, B_TITLED_WINDOW,
B_NOT_RESIZABLE | B_NOT_ZOOMABLE )
{
- /* Init libhb & launch the manager thread */
- fManager = new HBManager( true );
+ fHandle = HBInit( 1, 0 );
/* Add the scan view */
- fScanView = new ScanView( fManager );
- fRipView = new RipView( fManager );
+ fScanView = new ScanView( fHandle );
+ fRipView = new RipView( fHandle );
AddChild( fScanView );
/* Resize to fit */
ResizeTo( fScanView->Bounds().Width(), fScanView->Bounds().Height() );
-
+
BScreen screen;
MoveTo( ( screen.Frame().Width() - fRipView->Bounds().Width() ) / 2,
( screen.Frame().Height() - fRipView->Bounds().Height() ) / 2 );
@@ -45,7 +43,7 @@ bool MainWindow::QuitRequested()
fDie = true;
long exit_value;
wait_for_thread( fUpdateThread, &exit_value );
- delete fManager;
+ HBClose( &fHandle );
/* Stop the application */
be_app->PostMessage( B_QUIT_REQUESTED );
@@ -62,7 +60,7 @@ void MainWindow::MessageReceived( BMessage * message )
alert = new BAlert( "About HandBrake",
"HandBrake " VERSION "\n\n"
"by Eric Petit <[email protected]>\n"
- "Homepage : <http://beos.titer.org/handbrake/>\n\n"
+ "Homepage : <http://handbrake.m0k.org/>\n\n"
"No, you don't want to know where this stupid app "
"name comes from.\n\n"
"Thanks to BGA for pointing out very cool bugs ;)",
@@ -80,6 +78,7 @@ void MainWindow::MessageReceived( BMessage * message )
case B_SAVE_REQUESTED:
case RIP_TITLE_POPUP:
+ case RIP_VIDEO_CODEC_POPUP:
case RIP_BITRATE_RADIO:
case RIP_TARGET_CONTROL:
case RIP_CROP_BUTTON:
@@ -88,7 +87,7 @@ void MainWindow::MessageReceived( BMessage * message )
case RIP_RIP_BUTTON:
fRipView->MessageReceived( message );
break;
-
+
default:
BWindow::MessageReceived( message );
break;
@@ -98,56 +97,64 @@ void MainWindow::MessageReceived( BMessage * message )
void MainWindow::UpdateInterface( MainWindow * _this )
{
uint64_t time;
+ int64_t wait;
while( !_this->fDie )
{
/* Update every 0.1 sec */
time = system_time();
+
_this->_UpdateInterface();
- snooze( 100000 - ( system_time() - time ) );
+
+ wait = 100000 - ( system_time() - time );
+ if( wait > 0 )
+ {
+ snooze( wait );
+ }
}
}
void MainWindow::_UpdateInterface()
{
- if( !fManager->NeedUpdate() )
- {
- return;
- }
-
- HBStatus status = fManager->GetStatus();
-
if( !Lock() )
{
fprintf( stderr, "Lock() failed\n" );
return;
}
+
+ int modeChanged;
+ HBStatus status;
+
+ modeChanged = HBGetStatus( fHandle, &status );
- switch( status.fMode )
+ switch( status.mode )
{
case HB_MODE_UNDEF:
- case HB_MODE_NEED_VOLUME:
+ case HB_MODE_NEED_DEVICE:
break;
-
+
case HB_MODE_SCANNING:
- case HB_MODE_INVALID_VOLUME:
- fScanView->UpdateIntf( status );
+ case HB_MODE_INVALID_DEVICE:
+ fScanView->UpdateIntf( status, modeChanged );
break;
case HB_MODE_READY_TO_RIP:
+ if( !modeChanged )
+ break;
+
RemoveChild( fScanView );
ResizeTo( fRipView->Bounds().Width(),
fRipView->Bounds().Height() );
AddChild( fRipView );
- fRipView->UpdateIntf( status );
+ fRipView->UpdateIntf( status, modeChanged );
break;
case HB_MODE_ENCODING:
- case HB_MODE_SUSPENDED:
+ case HB_MODE_PAUSED:
case HB_MODE_DONE:
case HB_MODE_CANCELED:
case HB_MODE_ERROR:
- fRipView->UpdateIntf( status );
+ fRipView->UpdateIntf( status, modeChanged );
break;
default:
diff --git a/beos/MainWindow.h b/beos/MainWindow.h
index c4c32a711..5e50775bc 100644
--- a/beos/MainWindow.h
+++ b/beos/MainWindow.h
@@ -1,7 +1,7 @@
-/* $Id: MainWindow.h,v 1.10 2003/10/10 01:08:42 titer Exp $
+/* $Id: MainWindow.h,v 1.1.1.1 2003/11/03 12:03:51 titer Exp $
This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
+ Homepage: <http://handbrake.m0k.org/>.
It may be used under the terms of the GNU General Public License. */
@@ -12,7 +12,7 @@
class ScanView;
class RipView;
-#include "Common.h"
+#include "HandBrake.h"
class MainWindow : public BWindow
{
@@ -25,7 +25,7 @@ class MainWindow : public BWindow
static void UpdateInterface( MainWindow * _this );
void _UpdateInterface();
- HBManager * fManager;
+ HBHandle * fHandle;
int fUpdateThread;
volatile bool fDie;
diff --git a/beos/PictureWin.cpp b/beos/PictureWin.cpp
index 23aabe7c6..5667dbc3e 100644
--- a/beos/PictureWin.cpp
+++ b/beos/PictureWin.cpp
@@ -1,7 +1,7 @@
-/* $Id: PictureWin.cpp,v 1.5 2003/09/30 14:38:15 titer Exp $
+/* $Id: PictureWin.cpp,v 1.2 2003/11/06 14:36:54 titer Exp $
This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
+ Homepage: <http://handbrake.m0k.org/>.
It may be used under the terms of the GNU General Public License. */
#include <Bitmap.h>
@@ -12,24 +12,23 @@
#include <Slider.h>
#include "PictureWin.h"
-#include "Manager.h"
#define UPDATE_BITMAP 'upbi'
/* Handy way to access HBTitle members */
-#define fInWidth fTitle->fInWidth
-#define fInHeight fTitle->fInHeight
-#define fPixelWidth fTitle->fPixelWidth
-#define fPixelHeight fTitle->fPixelHeight
-#define fDeinterlace fTitle->fDeinterlace
-#define fOutWidth fTitle->fOutWidth
-#define fOutHeight fTitle->fOutHeight
-#define fOutWidthMax fTitle->fOutWidthMax
-#define fOutHeightMax fTitle->fOutHeightMax
-#define fTopCrop fTitle->fTopCrop
-#define fBottomCrop fTitle->fBottomCrop
-#define fLeftCrop fTitle->fLeftCrop
-#define fRightCrop fTitle->fRightCrop
+#define fInWidth fTitle->inWidth
+#define fInHeight fTitle->inHeight
+#define fPixelWidth fTitle->pixelWidth
+#define fPixelHeight fTitle->pixelHeight
+#define fDeinterlace fTitle->deinterlace
+#define fOutWidth fTitle->outWidth
+#define fOutHeight fTitle->outHeight
+#define fOutWidthMax fTitle->outWidthMax
+#define fOutHeightMax fTitle->outHeightMax
+#define fTopCrop fTitle->topCrop
+#define fBottomCrop fTitle->bottomCrop
+#define fLeftCrop fTitle->leftCrop
+#define fRightCrop fTitle->rightCrop
HBPictureView::HBPictureView( BRect rect, BBitmap * bitmap )
: BView( rect, NULL, B_FOLLOW_ALL, B_WILL_DRAW )
@@ -46,7 +45,7 @@ void HBPictureView::Draw( BRect rect )
}
else
{
- Log( "HBPictureView::Draw() : LockLooper() failed" );
+ fprintf( stderr, "LockLooper() failed\n" );
}
BView::Draw( rect );
@@ -54,12 +53,12 @@ void HBPictureView::Draw( BRect rect )
/* Constructor */
-HBPictureWin::HBPictureWin( HBManager * manager, HBTitle * title )
+HBPictureWin::HBPictureWin( HBHandle * handle, HBTitle * title )
: BWindow( BRect( 0, 0, 0, 0 ), "Picture settings",
B_FLOATING_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL,
B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_NOT_CLOSABLE )
{
- fManager = manager;
+ fHandle = handle;
fTitle = title;
/* Resize & center */
@@ -101,7 +100,7 @@ HBPictureWin::HBPictureWin( HBManager * manager, HBTitle * title )
view->AddChild( pictureBox );
- /* Second box : resize & crop settings */
+ /* Second box : scale & crop settings */
r = BRect( 10, fOutHeightMax + 75, fOutWidthMax + 31,
fOutHeightMax + 235 );
BBox * settingsBox;
@@ -189,8 +188,8 @@ void HBPictureWin::UpdateBitmap( int image )
fRightCrop = 2 * fRightCropSlider->Value();
fDeinterlace = ( fDeinterlaceCheck->Value() != 0 );
- uint8_t * preview = fManager->GetPreview( fTitle, image );
- for( uint32_t i = 0; i < fOutHeightMax + 2; i++ )
+ uint8_t * preview = HBGetPreview( fHandle, fTitle, image );
+ for( int i = 0; i < fOutHeightMax + 2; i++ )
{
memcpy( ((uint8_t*) fBitmap->Bits()) +
i * fBitmap->BytesPerRow(),
@@ -201,7 +200,7 @@ void HBPictureWin::UpdateBitmap( int image )
if( !Lock() )
{
- Log( "HBPictureWin::UpdateBitmap() : cannot Lock()" );
+ fprintf( stderr, "Lock() failed\n" );
return;
}
diff --git a/beos/PictureWin.h b/beos/PictureWin.h
index 909e8ea51..265eb8ad0 100644
--- a/beos/PictureWin.h
+++ b/beos/PictureWin.h
@@ -1,7 +1,7 @@
-/* $Id: PictureWin.h,v 1.3 2003/09/30 14:38:15 titer Exp $
+/* $Id: PictureWin.h,v 1.1.1.1 2003/11/03 12:03:51 titer Exp $
This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
+ Homepage: <http://handbrake.m0k.org/>.
It may be used under the terms of the GNU General Public License. */
#ifndef HB_PICTURE_WIN_H
@@ -12,8 +12,7 @@
class BSlider;
class BCheckBox;
-/* libhb headers */
-#include "Common.h"
+#include "HandBrake.h"
class HBPictureView : public BView
{
@@ -28,14 +27,14 @@ class HBPictureView : public BView
class HBPictureWin : public BWindow
{
public:
- HBPictureWin( HBManager * manager, HBTitle * title );
+ HBPictureWin( HBHandle * handle, HBTitle * title );
virtual void MessageReceived( BMessage * message );
void UpdateBitmap( int which );
private:
- HBManager * fManager;
+ HBHandle * fHandle;
HBTitle * fTitle;
/* GUI */
diff --git a/beos/RipView.cpp b/beos/RipView.cpp
index 180ba23ff..756090510 100644
--- a/beos/RipView.cpp
+++ b/beos/RipView.cpp
@@ -1,7 +1,7 @@
-/* $Id: RipView.cpp,v 1.6 2003/10/13 23:42:03 titer Exp $
+/* $Id: RipView.cpp,v 1.3 2003/11/07 21:52:56 titer Exp $
This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
+ Homepage: <http://handbrake.m0k.org/>.
It may be used under the terms of the GNU General Public License. */
#include <Box.h>
@@ -19,14 +19,13 @@
#include "RipView.h"
#include "PictureWin.h"
-#include "Manager.h"
#define DEFAULT_FILE "/boot/home/Desktop/Movie.avi"
-RipView::RipView( HBManager * manager )
+RipView::RipView( HBHandle * handle )
: BView( BRect( 0,0,400,480 ), NULL, B_FOLLOW_ALL, B_WILL_DRAW )
{
- fManager = manager;
+ fHandle = handle;
BRect r;
SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) );
@@ -85,7 +84,7 @@ RipView::RipView( HBManager * manager )
/* Crop */
r = BRect( fVideoBox->Bounds().Width() - 120, 120,
fVideoBox->Bounds().Width() - 10, 140 );
- fCropButton = new BButton( r, NULL, "Crop & Resize...",
+ fCropButton = new BButton( r, NULL, "Crop & Scale...",
new BMessage( RIP_CROP_BUTTON ) );
fVideoBox->AddChild( fCropButton );
@@ -172,7 +171,10 @@ RipView::RipView( HBManager * manager )
AddChild( fStartButton );
/* Fill popups */
- fVideoCodecPopUp->AddItem( new BMenuItem( "MPEG-4", NULL ) );
+ fVideoCodecPopUp->AddItem( new BMenuItem( "MPEG-4 (Ffmpeg)",
+ new BMessage( RIP_VIDEO_CODEC_POPUP ) ) );
+ fVideoCodecPopUp->AddItem( new BMenuItem( "MPEG-4 (XviD)",
+ new BMessage( RIP_VIDEO_CODEC_POPUP ) ) );
fVideoCodecPopUp->ItemAt( 0 )->SetMarked( true );
fAudioCodecPopUp->AddItem( new BMenuItem( "MP3", NULL ) );
fAudioCodecPopUp->ItemAt( 0 )->SetMarked( true );
@@ -208,7 +210,7 @@ void RipView::MessageReceived( BMessage * message )
case RIP_TITLE_POPUP:
{
int index = fTitlePopUp->IndexOf( fTitlePopUp->FindMarked() );
- HBTitle * title = (HBTitle*) fTitleList->ItemAt( index );
+ HBTitle * title = (HBTitle*) HBListItemAt( fTitleList, index );
/* Empty current popups */
BMenuItem * item;
@@ -225,13 +227,13 @@ void RipView::MessageReceived( BMessage * message )
/* Show new languages */
HBAudio * audio;
- for( uint32_t i = 0; i < title->fAudioList->CountItems(); i++ )
+ for( int i = 0; i < HBListCountItems( title->audioList ); i++ )
{
- audio = (HBAudio*) title->fAudioList->ItemAt( i );
+ audio = (HBAudio*) HBListItemAt( title->audioList, i );
fLanguagePopUp->AddItem(
- new BMenuItem( audio->fDescription, NULL ) );
+ new BMenuItem( audio->language, NULL ) );
fSecondaryLanguagePopUp->AddItem(
- new BMenuItem( audio->fDescription,
+ new BMenuItem( audio->language,
new BMessage( RIP_TARGET_CONTROL ) ) );
}
fLanguagePopUp->ItemAt( 0 )->SetMarked( true );
@@ -241,11 +243,25 @@ void RipView::MessageReceived( BMessage * message )
fSecondaryLanguagePopUp->CountItems() - 1 )->SetMarked( true );
fSecondaryLanguageField->SetEnabled(
- ( title->fAudioList->CountItems() > 1 ) );
+ ( HBListCountItems( title->audioList ) > 1 ) );
break;
}
+ case RIP_VIDEO_CODEC_POPUP:
+ {
+ if( fVideoCodecPopUp->IndexOf( fVideoCodecPopUp->FindMarked() ) )
+ {
+ fTwoPassCheck->SetValue( 0 );
+ fTwoPassCheck->SetEnabled( false );
+ }
+ else
+ {
+ fTwoPassCheck->SetEnabled( true );
+ }
+ break;
+ }
+
case RIP_BITRATE_RADIO:
{
if( fCustomBitrateRadio->Value() )
@@ -271,7 +287,7 @@ void RipView::MessageReceived( BMessage * message )
int64_t available;
int index = fTitlePopUp->IndexOf( fTitlePopUp->FindMarked() );
- HBTitle * title = (HBTitle*) fTitleList->ItemAt( index );
+ HBTitle * title = (HBTitle*) HBListItemAt( fTitleList, index );
available = (int64_t) 1024 * 1024 *
atoi( fTargetSizeControl->Text() );
@@ -281,16 +297,16 @@ void RipView::MessageReceived( BMessage * message )
/* Video chunk headers (8 bytes / frame) and
and index (16 bytes / frame) */
- available -= 24 * title->fLength * title->fRate /
- title->fScale;
+ available -= 24 * title->length * title->rate /
+ title->rateBase;
/* Audio tracks */
available -=
( strcmp( fSecondaryLanguagePopUp->FindMarked()->Label(),
"None" ) ? 2 : 1 ) *
- ( title->fLength *
+ ( title->length *
atoi( fAudioBitratePopUp->FindMarked()->Label() ) * 128 +
- 24 * title->fLength * 44100 / 1152 );
+ 24 * title->length * 44100 / 1152 );
char string[1024]; memset( string, 0, 1024 );
if( available < 0 )
@@ -300,7 +316,7 @@ void RipView::MessageReceived( BMessage * message )
else
{
sprintf( string, "%lld", available /
- ( 128 * title->fLength ) );
+ ( 128 * title->length ) );
}
fCustomBitrateControl->SetText( string );
break;
@@ -309,10 +325,10 @@ void RipView::MessageReceived( BMessage * message )
case RIP_CROP_BUTTON:
{
int index = fTitlePopUp->IndexOf( fTitlePopUp->FindMarked() );
- HBTitle * title = (HBTitle*) fTitleList->ItemAt( index );
+ HBTitle * title = (HBTitle*) HBListItemAt( fTitleList, index );
HBPictureWin * win;
- win = new HBPictureWin( fManager, title );
+ win = new HBPictureWin( fHandle, title );
win->Show();
break;
}
@@ -341,11 +357,11 @@ void RipView::MessageReceived( BMessage * message )
{
if( strcmp( fSuspendButton->Label(), "Suspend" ) )
{
- fManager->ResumeRip();
+ HBResumeRip( fHandle );
}
else
{
- fManager->SuspendRip();
+ HBPauseRip( fHandle );
}
break;
@@ -355,7 +371,7 @@ void RipView::MessageReceived( BMessage * message )
{
if( strcmp( fStartButton->Label(), "Rip !" ) )
{
- fManager->StopRip();
+ HBStopRip( fHandle );
}
else
{
@@ -363,29 +379,32 @@ void RipView::MessageReceived( BMessage * message )
/* Get asked title & languages */
index = fTitlePopUp->IndexOf( fTitlePopUp->FindMarked() );
- HBTitle * title = (HBTitle*) fTitleList->ItemAt( index );
+ HBTitle * title = (HBTitle*) HBListItemAt( fTitleList, index );
index = fLanguagePopUp->IndexOf( fLanguagePopUp->FindMarked() );
HBAudio * audio1 =
- (HBAudio*) title->fAudioList->ItemAt( index );
+ (HBAudio*) HBListItemAt( title->audioList, index );
index = fSecondaryLanguagePopUp->IndexOf(
fSecondaryLanguagePopUp->FindMarked() );
HBAudio * audio2 =
- (HBAudio*) title->fAudioList->ItemAt( index );
+ (HBAudio*) HBListItemAt( title->audioList, index );
/* Use user settings */
- title->fBitrate = atoi( fCustomBitrateControl->Text() );
- title->fTwoPass = ( fTwoPassCheck->Value() != 0 );
- audio1->fOutBitrate =
+ title->file = strdup( fFileControl->Text() );
+ title->bitrate = atoi( fCustomBitrateControl->Text() );
+ title->twoPass = ( fTwoPassCheck->Value() != 0 );
+ title->codec = fVideoCodecPopUp->IndexOf(
+ fVideoCodecPopUp->FindMarked() ) ? HB_CODEC_XVID :
+ HB_CODEC_FFMPEG;
+ audio1->outBitrate =
atoi( fAudioBitratePopUp->FindMarked()->Label() );
if( audio2 )
{
- audio2->fOutBitrate =
+ audio2->outBitrate =
atoi( fAudioBitratePopUp->FindMarked()->Label() );
}
/* Let libhb do the job */
- fManager->StartRip( title, audio1, audio2,
- (char*) fFileControl->Text() );
+ HBStartRip( fHandle, title, audio1, audio2 );
}
break;
}
@@ -396,23 +415,26 @@ void RipView::MessageReceived( BMessage * message )
}
}
-void RipView::UpdateIntf( HBStatus status )
+void RipView::UpdateIntf( HBStatus status, int modeChanged )
{
- switch( status.fMode )
+ switch( status.mode )
{
case HB_MODE_READY_TO_RIP:
{
- fTitleList = status.fTitleList;
+ if( !modeChanged )
+ break;
+
+ fTitleList = status.titleList;
HBTitle * title;
- for( uint32_t i = 0; i < fTitleList->CountItems(); i++ )
+ for( int i = 0; i < HBListCountItems( fTitleList ); i++ )
{
- title = (HBTitle*) fTitleList->ItemAt( i );
+ title = (HBTitle*) HBListItemAt( fTitleList, i );
char string[1024]; memset( string, 0, 1024 );
- sprintf( string, "%d (%02lld:%02lld:%02lld)",
- title->fIndex, title->fLength / 3600,
- ( title->fLength % 3600 ) / 60,
- title->fLength % 60 );
+ sprintf( string, "%d (%02d:%02d:%02d)",
+ title->index, title->length / 3600,
+ ( title->length % 3600 ) / 60,
+ title->length % 60 );
fTitlePopUp->AddItem(
new BMenuItem( string, new BMessage( RIP_TITLE_POPUP ) ) );
}
@@ -423,23 +445,30 @@ void RipView::UpdateIntf( HBStatus status )
case HB_MODE_ENCODING:
{
- fTitleField->SetEnabled( false );
- fVideoCodecField->SetEnabled( false );
- fCustomBitrateRadio->SetEnabled( false );
- fCustomBitrateControl->SetEnabled( false );
- fTargetSizeRadio->SetEnabled( false );
- fTargetSizeControl->SetEnabled( false );
- fTwoPassCheck->SetEnabled( false );
- fCropButton->SetEnabled( false );
- fLanguageField->SetEnabled( false );
- fSecondaryLanguageField->SetEnabled( false );
- fAudioCodecField->SetEnabled( false );
- fAudioBitrateField->SetEnabled( false );
- fFileFormatField->SetEnabled( false );
- fFileControl->SetEnabled( false );
- fFileButton->SetEnabled( false );
-
- if( !status.fPosition )
+ if( modeChanged )
+ {
+ fTitleField->SetEnabled( false );
+ fVideoCodecField->SetEnabled( false );
+ fCustomBitrateRadio->SetEnabled( false );
+ fCustomBitrateControl->SetEnabled( false );
+ fTargetSizeRadio->SetEnabled( false );
+ fTargetSizeControl->SetEnabled( false );
+ fTwoPassCheck->SetEnabled( false );
+ fCropButton->SetEnabled( false );
+ fLanguageField->SetEnabled( false );
+ fSecondaryLanguageField->SetEnabled( false );
+ fAudioCodecField->SetEnabled( false );
+ fAudioBitrateField->SetEnabled( false );
+ fFileFormatField->SetEnabled( false );
+ fFileControl->SetEnabled( false );
+ fFileButton->SetEnabled( false );
+ fSuspendButton->SetLabel( "Suspend" );
+ fSuspendButton->SetEnabled( true );
+ fStartButton->SetLabel( "Cancel" );
+ fStartButton->SetEnabled( true );
+ }
+
+ if( !status.position )
{
fStatusBar->Update( - fStatusBar->CurrentValue(),
"Starting..." );
@@ -449,163 +478,175 @@ void RipView::UpdateIntf( HBStatus status )
char string[1024]; memset( string, 0, 1024 );
sprintf( string, "Encoding: %.2f %% (%.2f fps, "
"%02d:%02d:%02d remaining)",
- 100 * status.fPosition,
- status.fFrameRate,
- status.fRemainingTime / 3600,
- ( status.fRemainingTime % 3600 ) / 60,
- status.fRemainingTime % 60 );
- fStatusBar->Update( 100 * status.fPosition -
+ 100 * status.position,
+ status.frameRate,
+ status.remainingTime / 3600,
+ ( status.remainingTime % 3600 ) / 60,
+ status.remainingTime % 60 );
+ fStatusBar->Update( 100 * status.position -
fStatusBar->CurrentValue(),
string );
}
-
- fSuspendButton->SetLabel( "Suspend" );
- fSuspendButton->SetEnabled( true );
- fStartButton->SetLabel( "Cancel" );
- fStartButton->SetEnabled( true );
break;
}
- case HB_MODE_SUSPENDED:
+ case HB_MODE_PAUSED:
{
- fTitleField->SetEnabled( false );
- fVideoCodecField->SetEnabled( false );
- fCustomBitrateRadio->SetEnabled( false );
- fCustomBitrateControl->SetEnabled( false );
- fTargetSizeRadio->SetEnabled( false );
- fTargetSizeControl->SetEnabled( false );
- fTwoPassCheck->SetEnabled( false );
- fCropButton->SetEnabled( false );
- fLanguageField->SetEnabled( false );
- fSecondaryLanguageField->SetEnabled( false );
- fAudioCodecField->SetEnabled( false );
- fAudioBitrateField->SetEnabled( false );
- fFileFormatField->SetEnabled( false );
- fFileControl->SetEnabled( false );
- fFileButton->SetEnabled( false );
-
- fStatusBar->Update( 100 * status.fPosition -
- fStatusBar->CurrentValue(), "Suspended" );
+ if( modeChanged )
+ {
+ fTitleField->SetEnabled( false );
+ fVideoCodecField->SetEnabled( false );
+ fCustomBitrateRadio->SetEnabled( false );
+ fCustomBitrateControl->SetEnabled( false );
+ fTargetSizeRadio->SetEnabled( false );
+ fTargetSizeControl->SetEnabled( false );
+ fTwoPassCheck->SetEnabled( false );
+ fCropButton->SetEnabled( false );
+ fLanguageField->SetEnabled( false );
+ fSecondaryLanguageField->SetEnabled( false );
+ fAudioCodecField->SetEnabled( false );
+ fAudioBitrateField->SetEnabled( false );
+ fFileFormatField->SetEnabled( false );
+ fFileControl->SetEnabled( false );
+ fFileButton->SetEnabled( false );
+ fSuspendButton->SetLabel( "Resume" );
+ fSuspendButton->SetEnabled( true );
+ fStartButton->SetLabel( "Cancel" );
+ fStartButton->SetEnabled( true );
+ }
- fSuspendButton->SetLabel( "Resume" );
- fSuspendButton->SetEnabled( true );
- fStartButton->SetLabel( "Cancel" );
- fStartButton->SetEnabled( true );
+ fStatusBar->Update( 100 * status.position -
+ fStatusBar->CurrentValue(), "Suspended" );
break;
}
case HB_MODE_STOPPING:
{
- fTitleField->SetEnabled( false );
- fVideoCodecField->SetEnabled( false );
- fCustomBitrateRadio->SetEnabled( false );
- fCustomBitrateControl->SetEnabled( false );
- fTargetSizeRadio->SetEnabled( false );
- fTargetSizeControl->SetEnabled( false );
- fTwoPassCheck->SetEnabled( false );
- fCropButton->SetEnabled( false );
- fLanguageField->SetEnabled( false );
- fSecondaryLanguageField->SetEnabled( false );
- fAudioCodecField->SetEnabled( false );
- fAudioBitrateField->SetEnabled( false );
- fFileFormatField->SetEnabled( false );
- fFileControl->SetEnabled( false );
- fFileButton->SetEnabled( false );
+ if( modeChanged )
+ {
+ fTitleField->SetEnabled( false );
+ fVideoCodecField->SetEnabled( false );
+ fCustomBitrateRadio->SetEnabled( false );
+ fCustomBitrateControl->SetEnabled( false );
+ fTargetSizeRadio->SetEnabled( false );
+ fTargetSizeControl->SetEnabled( false );
+ fTwoPassCheck->SetEnabled( false );
+ fCropButton->SetEnabled( false );
+ fLanguageField->SetEnabled( false );
+ fSecondaryLanguageField->SetEnabled( false );
+ fAudioCodecField->SetEnabled( false );
+ fAudioBitrateField->SetEnabled( false );
+ fFileFormatField->SetEnabled( false );
+ fFileControl->SetEnabled( false );
+ fFileButton->SetEnabled( false );
+ fSuspendButton->SetLabel( "Suspend" );
+ fSuspendButton->SetEnabled( false );
+ fStartButton->SetLabel( "Cancel" );
+ fStartButton->SetEnabled( false );
+ }
fStatusBar->Update( - fStatusBar->CurrentValue(),
"Stopping..." );
-
- fSuspendButton->SetLabel( "Suspend" );
- fSuspendButton->SetEnabled( false );
- fStartButton->SetLabel( "Cancel" );
- fStartButton->SetEnabled( false );
break;
}
case HB_MODE_DONE:
{
- fTitleField->SetEnabled( true );
- fVideoCodecField->SetEnabled( true );
- fCustomBitrateRadio->SetEnabled( true );
- fCustomBitrateControl->SetEnabled( fCustomBitrateRadio->Value() );
- fTargetSizeRadio->SetEnabled( true );
- fTargetSizeControl->SetEnabled( fTargetSizeRadio->Value() );
- fTwoPassCheck->SetEnabled( true );
- fCropButton->SetEnabled( true );
- fLanguageField->SetEnabled( true );
- fSecondaryLanguageField->SetEnabled(
- ( fSecondaryLanguagePopUp->CountItems() > 2 ) );
- fAudioCodecField->SetEnabled( true );
- fAudioBitrateField->SetEnabled( true );
- fFileFormatField->SetEnabled( true );
- fFileControl->SetEnabled( true );
- fFileButton->SetEnabled( true );
+ if( modeChanged )
+ {
+ fTitleField->SetEnabled( true );
+ fVideoCodecField->SetEnabled( true );
+ fCustomBitrateRadio->SetEnabled( true );
+ fCustomBitrateControl->SetEnabled(
+ fCustomBitrateRadio->Value() );
+ fTargetSizeRadio->SetEnabled( true );
+ fTargetSizeControl->SetEnabled( fTargetSizeRadio->Value() );
+ fTwoPassCheck->SetEnabled( true );
+ fCropButton->SetEnabled( true );
+ fLanguageField->SetEnabled( true );
+ fSecondaryLanguageField->SetEnabled(
+ ( fSecondaryLanguagePopUp->CountItems() > 2 ) );
+ fAudioCodecField->SetEnabled( true );
+ fAudioBitrateField->SetEnabled( true );
+ fFileFormatField->SetEnabled( true );
+ fFileControl->SetEnabled( true );
+ fFileButton->SetEnabled( true );
+
+ fSuspendButton->SetLabel( "Suspend" );
+ fSuspendButton->SetEnabled( false );
+ fStartButton->SetLabel( "Rip !" );
+ fStartButton->SetEnabled( true );
+ MessageReceived( new BMessage( RIP_VIDEO_CODEC_POPUP ) );
+ }
fStatusBar->Update( 100.0 - fStatusBar->CurrentValue(),
"Done." );
-
- fSuspendButton->SetLabel( "Suspend" );
- fSuspendButton->SetEnabled( false );
- fStartButton->SetLabel( "Rip !" );
- fStartButton->SetEnabled( true );
break;
}
case HB_MODE_CANCELED:
{
- fTitleField->SetEnabled( true );
- fVideoCodecField->SetEnabled( true );
- fCustomBitrateRadio->SetEnabled( true );
- fCustomBitrateControl->SetEnabled( fCustomBitrateRadio->Value() );
- fTargetSizeRadio->SetEnabled( true );
- fTargetSizeControl->SetEnabled( fTargetSizeRadio->Value() );
- fTwoPassCheck->SetEnabled( true );
- fCropButton->SetEnabled( true );
- fLanguageField->SetEnabled( true );
- fSecondaryLanguageField->SetEnabled(
- ( fSecondaryLanguagePopUp->CountItems() > 2 ) );
- fAudioCodecField->SetEnabled( true );
- fAudioBitrateField->SetEnabled( true );
- fFileFormatField->SetEnabled( true );
- fFileControl->SetEnabled( true );
- fFileButton->SetEnabled( true );
+ if( modeChanged )
+ {
+ fTitleField->SetEnabled( true );
+ fVideoCodecField->SetEnabled( true );
+ fCustomBitrateRadio->SetEnabled( true );
+ fCustomBitrateControl->SetEnabled(
+ fCustomBitrateRadio->Value() );
+ fTargetSizeRadio->SetEnabled( true );
+ fTargetSizeControl->SetEnabled( fTargetSizeRadio->Value() );
+ fTwoPassCheck->SetEnabled( true );
+ fCropButton->SetEnabled( true );
+ fLanguageField->SetEnabled( true );
+ fSecondaryLanguageField->SetEnabled(
+ ( fSecondaryLanguagePopUp->CountItems() > 2 ) );
+ fAudioCodecField->SetEnabled( true );
+ fAudioBitrateField->SetEnabled( true );
+ fFileFormatField->SetEnabled( true );
+ fFileControl->SetEnabled( true );
+ fFileButton->SetEnabled( true );
+ fSuspendButton->SetLabel( "Suspend" );
+ fSuspendButton->SetEnabled( false );
+ fStartButton->SetLabel( "Rip !" );
+ fStartButton->SetEnabled( true );
+ MessageReceived( new BMessage( RIP_VIDEO_CODEC_POPUP ) );
+ }
fStatusBar->Update( - fStatusBar->CurrentValue(),
"Canceled." );
-
- fSuspendButton->SetLabel( "Suspend" );
- fSuspendButton->SetEnabled( false );
- fStartButton->SetLabel( "Rip !" );
- fStartButton->SetEnabled( true );
break;
}
case HB_MODE_ERROR:
{
- fTitleField->SetEnabled( true );
- fVideoCodecField->SetEnabled( true );
- fCustomBitrateRadio->SetEnabled( true );
- fCustomBitrateControl->SetEnabled( fCustomBitrateRadio->Value() );
- fTargetSizeRadio->SetEnabled( true );
- fTargetSizeControl->SetEnabled( fTargetSizeRadio->Value() );
- fTwoPassCheck->SetEnabled( true );
- fCropButton->SetEnabled( true );
- fLanguageField->SetEnabled( true );
- fSecondaryLanguageField->SetEnabled(
- ( fSecondaryLanguagePopUp->CountItems() > 2 ) );
- fAudioCodecField->SetEnabled( true );
- fAudioBitrateField->SetEnabled( true );
- fFileFormatField->SetEnabled( true );
- fFileControl->SetEnabled( true );
- fFileButton->SetEnabled( true );
+ if( modeChanged )
+ {
+ fTitleField->SetEnabled( true );
+ fVideoCodecField->SetEnabled( true );
+ fCustomBitrateRadio->SetEnabled( true );
+ fCustomBitrateControl->SetEnabled(
+ fCustomBitrateRadio->Value() );
+ fTargetSizeRadio->SetEnabled( true );
+ fTargetSizeControl->SetEnabled( fTargetSizeRadio->Value() );
+ fTwoPassCheck->SetEnabled( true );
+ fCropButton->SetEnabled( true );
+ fLanguageField->SetEnabled( true );
+ fSecondaryLanguageField->SetEnabled(
+ ( fSecondaryLanguagePopUp->CountItems() > 2 ) );
+ fAudioCodecField->SetEnabled( true );
+ fAudioBitrateField->SetEnabled( true );
+ fFileFormatField->SetEnabled( true );
+ fFileControl->SetEnabled( true );
+ fFileButton->SetEnabled( true );
+ fSuspendButton->SetLabel( "Suspend" );
+ fSuspendButton->SetEnabled( false );
+ fStartButton->SetLabel( "Rip !" );
+ fStartButton->SetEnabled( true );
+ MessageReceived( new BMessage( RIP_VIDEO_CODEC_POPUP ) );
+ }
fStatusBar->Update( - fStatusBar->CurrentValue(),
"Error." );
-
- fSuspendButton->SetLabel( "Suspend" );
- fSuspendButton->SetEnabled( false );
- fStartButton->SetLabel( "Rip !" );
- fStartButton->SetEnabled( true );
break;
}
diff --git a/beos/RipView.h b/beos/RipView.h
index d487b2b99..27d9831a0 100644
--- a/beos/RipView.h
+++ b/beos/RipView.h
@@ -1,7 +1,7 @@
-/* $Id: RipView.h,v 1.5 2003/10/13 22:23:02 titer Exp $
+/* $Id: RipView.h,v 1.3 2003/11/07 21:52:56 titer Exp $
This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
+ Homepage: <http://handbrake.m0k.org/>.
It may be used under the terms of the GNU General Public License. */
@@ -19,25 +19,26 @@ class BRadioButton;
class BStatusBar;
class BTextControl;
-#include "Common.h"
+#include "HandBrake.h"
-#define RIP_TITLE_POPUP 'rtip'
-#define RIP_BITRATE_RADIO 'rbir'
-#define RIP_TARGET_CONTROL 'rtac'
-#define RIP_CROP_BUTTON 'rcrb'
-#define RIP_BROWSE_BUTTON 'rbrb'
-#define RIP_SUSPEND_BUTTON 'rsub'
-#define RIP_RIP_BUTTON 'rrib'
+#define RIP_TITLE_POPUP 'rtip'
+#define RIP_VIDEO_CODEC_POPUP 'rvcp'
+#define RIP_BITRATE_RADIO 'rbir'
+#define RIP_TARGET_CONTROL 'rtac'
+#define RIP_CROP_BUTTON 'rcrb'
+#define RIP_BROWSE_BUTTON 'rbrb'
+#define RIP_SUSPEND_BUTTON 'rsub'
+#define RIP_RIP_BUTTON 'rrib'
class RipView : public BView
{
public:
- RipView( HBManager * manager );
+ RipView( HBHandle * handle );
void MessageReceived( BMessage * message );
- void UpdateIntf( HBStatus status );
+ void UpdateIntf( HBStatus status, int modeChanged );
private:
- HBManager * fManager;
+ HBHandle * fHandle;
HBList * fTitleList;
BBox * fVideoBox;
diff --git a/beos/ScanView.cpp b/beos/ScanView.cpp
index fb5d722e8..24c66db7f 100644
--- a/beos/ScanView.cpp
+++ b/beos/ScanView.cpp
@@ -1,7 +1,7 @@
-/* $Id: ScanView.cpp,v 1.4 2003/10/13 23:42:03 titer Exp $
+/* $Id: ScanView.cpp,v 1.2 2003/11/06 14:36:54 titer Exp $
This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
+ Homepage: <http://handbrake.m0k.org/>.
It may be used under the terms of the GNU General Public License. */
#include <fs_info.h>
@@ -21,13 +21,12 @@
#include <TextControl.h>
#include <VolumeRoster.h>
-#include "Manager.h"
#include "ScanView.h"
-ScanView::ScanView( HBManager * manager )
+ScanView::ScanView( HBHandle * handle )
: BView( BRect( 0,0,400,190 ), NULL, B_FOLLOW_ALL, B_WILL_DRAW )
{
- fManager = manager;
+ fHandle = handle;
BRect r;
SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) );
@@ -125,12 +124,14 @@ void ScanView::MessageReceived( BMessage * message )
{
if( fRadioDetected->Value() )
{
- fManager->ScanVolumes( (char*)
- fPopUp->FindMarked()->Label() );
+ HBScanDevice( fHandle,
+ (char*) fPopUp->FindMarked()->Label(),
+ 0 );
}
else
{
- fManager->ScanVolumes( (char*) fFolderControl->Text() );
+ HBScanDevice( fHandle,
+ (char*) fFolderControl->Text(), 0 );
}
break;
}
@@ -140,36 +141,41 @@ void ScanView::MessageReceived( BMessage * message )
}
}
-void ScanView::UpdateIntf( HBStatus status )
+void ScanView::UpdateIntf( HBStatus status, int modeChanged )
{
- switch( status.fMode )
+ switch( status.mode )
{
case HB_MODE_SCANNING:
{
- fRadioDetected->SetEnabled( false );
- fRadioFolder->SetEnabled( false );
- fField->SetEnabled( false );
- fFolderControl->SetEnabled( false );
- fBrowseButton->SetEnabled( false );
- fOpenButton->SetEnabled( false );
+ if( modeChanged )
+ {
+ fRadioDetected->SetEnabled( false );
+ fRadioFolder->SetEnabled( false );
+ fField->SetEnabled( false );
+ fFolderControl->SetEnabled( false );
+ fBrowseButton->SetEnabled( false );
+ fOpenButton->SetEnabled( false );
+ }
char string[1024]; memset( string, 0, 1024 );
- if( !status.fScannedTitle )
+ if( !status.scannedTitle )
{
- sprintf( string, "Opening %s...",
- status.fScannedVolume );
+ sprintf( string, "Opening device..." );
}
else
{
- sprintf( string, "Scanning %s, title %d...",
- status.fScannedVolume, status.fScannedTitle );
+ sprintf( string, "Scanning title %d...",
+ status.scannedTitle );
}
fStatusString->SetText( string );
break;
}
- case HB_MODE_INVALID_VOLUME:
+ case HB_MODE_INVALID_DEVICE:
{
+ if( !modeChanged )
+ break;
+
fRadioDetected->SetEnabled( true );
fRadioFolder->SetEnabled( true );
diff --git a/beos/ScanView.h b/beos/ScanView.h
index 5e2514b54..11ed342cc 100644
--- a/beos/ScanView.h
+++ b/beos/ScanView.h
@@ -1,7 +1,7 @@
-/* $Id: ScanView.h,v 1.2 2003/10/13 22:23:02 titer Exp $
+/* $Id: ScanView.h,v 1.2 2003/11/06 14:36:54 titer Exp $
This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
+ Homepage: <http://handbrake.m0k.org/>.
It may be used under the terms of the GNU General Public License. */
#ifndef HB_SCAN_VIEW_H
@@ -16,7 +16,7 @@ class BRadioButton;
class BStringView;
class BTextControl;
-#include "Common.h"
+#include "HandBrake.h"
#define SCAN_RADIO 'scra'
#define SCAN_BROWSE_BUTTON 'sbrb'
@@ -25,14 +25,14 @@ class BTextControl;
class ScanView : public BView
{
public:
- ScanView( HBManager * manager );
+ ScanView( HBHandle * handle );
void MessageReceived( BMessage * message );
- void UpdateIntf( HBStatus status );
+ void UpdateIntf( HBStatus status, int modeChanged );
private:
void DetectVolumes();
- HBManager * fManager;
+ HBHandle * fHandle;
BRadioButton * fRadioDetected;
BRadioButton * fRadioFolder;
diff --git a/core/Ac3Dec.c b/core/Ac3Dec.c
new file mode 100644
index 000000000..d5430d49e
--- /dev/null
+++ b/core/Ac3Dec.c
@@ -0,0 +1,219 @@
+/* $Id: Ac3Dec.c,v 1.4 2003/11/04 20:16: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 "Ac3Dec.h"
+#include "Fifo.h"
+#include "Work.h"
+
+#include <a52dec/a52.h>
+
+/* Local prototypes */
+static int Ac3DecWork( HBWork * );
+static int GetBytes( HBAc3Dec *, int );
+
+struct HBAc3Dec
+{
+ 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 ac3FrameSize; /* In bytes */
+ HBBuffer * ac3Buffer;
+ int ac3BufferPos; /* In bytes */
+ int nextFrameSize; /* In bytes */
+ float position;
+ HBBuffer * rawBuffer;
+};
+
+HBAc3Dec * HBAc3DecInit( HBHandle * handle, HBAudio * audio )
+{
+ HBAc3Dec * a;
+ if( !( a = malloc( sizeof( HBAc3Dec ) ) ) )
+ {
+ HBLog( "HBAc3DecInit: malloc() failed, gonna crash" );
+ return NULL;
+ }
+
+ a->name = strdup( "Ac3Dec" );
+ a->work = Ac3DecWork;
+
+ a->handle = handle;
+ a->audio = audio;
+
+ /* Init liba52 */
+ a->state = a52_init( 0 );
+ a->inFlags = 0;
+
+ /* Let it do the downmixing */
+ a->outFlags = A52_STEREO;
+
+ /* Lame wants samples from -32768 to 32768 */
+ a->sampleLevel = 32768.0;
+
+ a->ac3FrameSize = 0;
+ a->ac3Buffer = NULL;
+ a->ac3BufferPos = 0;
+ a->nextFrameSize = 0;
+ a->position = 0.0;
+ a->rawBuffer = NULL;
+
+ return a;
+}
+
+void HBAc3DecClose( HBAc3Dec ** _a )
+{
+ HBAc3Dec * a = *_a;
+
+ if( a->ac3Buffer ) HBBufferClose( &a->ac3Buffer );
+ if( a->rawBuffer ) HBBufferClose( &a->rawBuffer );
+ a52_free( a->state );
+ free( a->name );
+ free( a );
+
+ *_a = NULL;
+}
+
+static int Ac3DecWork( HBWork * w )
+{
+ HBAc3Dec * a = (HBAc3Dec*) w;
+ HBAudio * audio = a->audio;
+
+ int didSomething = 0;
+
+ /* Push decoded buffer */
+ if( a->rawBuffer )
+ {
+ if( HBFifoPush( audio->rawFifo, &a->rawBuffer ) )
+ {
+ didSomething = 1;
+ }
+ else
+ {
+ return didSomething;
+ }
+ }
+
+ /* Get a frame header (7 bytes) */
+ if( a->ac3FrameSize < 7 )
+ {
+ if( GetBytes( a, 7 ) )
+ {
+ didSomething = 1;
+ }
+ else
+ {
+ return didSomething;
+ }
+
+ a->nextFrameSize = a52_syncinfo( a->ac3Frame, &a->inFlags,
+ &audio->inSampleRate,
+ &audio->inBitrate );
+
+ if( !a->nextFrameSize )
+ {
+ HBLog( "HBAc3Dec: a52_syncinfo() failed" );
+ HBErrorOccured( a->handle, HB_ERROR_A52_SYNC );
+ return didSomething;
+ }
+ }
+
+ /* Get the whole frame */
+ if( a->ac3FrameSize >= 7 )
+ {
+ sample_t * samples;
+ HBBuffer * rawBuffer;
+ int i;
+
+ if( GetBytes( a, a->nextFrameSize ) )
+ {
+ didSomething = 1;
+ }
+ else
+ {
+ return didSomething;
+ }
+
+ /* Feed liba52 */
+ a52_frame( a->state, a->ac3Frame, &a->outFlags,
+ &a->sampleLevel, 0 );
+ a->ac3FrameSize = 0;
+
+ /* 6 blocks per frame, 256 samples per block, 2 channels */
+ rawBuffer = HBBufferInit( 12 * 256 * sizeof( float ) );
+ rawBuffer->position = a->position;
+
+ for( i = 0; i < 6; i++ )
+ {
+ /* Decode a block */
+ a52_block( a->state );
+
+ /* Get a pointer to the raw data */
+ samples = a52_samples( a->state );
+
+ /* Copy left channel data */
+ memcpy( rawBuffer->data + i * 256 * sizeof( float ),
+ samples,
+ 256 * sizeof( float ) );
+
+ /* Copy right channel data */
+ memcpy( rawBuffer->data + ( 6 + i ) * 256 * sizeof( float ),
+ samples + 256,
+ 256 * sizeof( float ) );
+ }
+
+ a->rawBuffer = rawBuffer;
+ }
+
+ return didSomething;
+}
+
+static int GetBytes( HBAc3Dec * a, int size )
+{
+ int i;
+
+ while( a->ac3FrameSize < size )
+ {
+ if( !a->ac3Buffer )
+ {
+ if( !( a->ac3Buffer = HBFifoPop( a->audio->ac3Fifo ) ) )
+ {
+ return 0;
+ }
+ a->ac3BufferPos = 0;
+ a->position = a->ac3Buffer->position;
+
+ if( a->ac3Buffer->last )
+ {
+ HBDone( a->handle );
+ }
+ }
+
+ i = MIN( size - a->ac3FrameSize,
+ a->ac3Buffer->size - a->ac3BufferPos );
+ memcpy( a->ac3Frame + a->ac3FrameSize,
+ a->ac3Buffer->data + a->ac3BufferPos,
+ i );
+ a->ac3FrameSize += i;
+ a->ac3BufferPos += i;
+
+ if( a->ac3BufferPos == a->ac3Buffer->size )
+ {
+ HBBufferClose( &a->ac3Buffer );
+ }
+ }
+
+ return 1;
+}
+
diff --git a/core/Ac3Dec.h b/core/Ac3Dec.h
new file mode 100644
index 000000000..a1ecaff66
--- /dev/null
+++ b/core/Ac3Dec.h
@@ -0,0 +1,15 @@
+/* $Id: Ac3Dec.h,v 1.1 2003/11/03 12:08: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_AC3_DEC_H
+#define HB_AC3_DEC_H
+
+#include "HandBrakeInternal.h"
+
+HBAc3Dec * HBAc3DecInit( HBHandle *, HBAudio * );
+void HBAc3DecClose( HBAc3Dec ** );
+
+#endif
diff --git a/core/Ac3Decoder.cpp b/core/Ac3Decoder.cpp
deleted file mode 100644
index 663184e40..000000000
--- a/core/Ac3Decoder.cpp
+++ /dev/null
@@ -1,204 +0,0 @@
-/* $Id: Ac3Decoder.cpp,v 1.21 2003/10/14 14:35:20 titer Exp $
-
- This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
- It may be used under the terms of the GNU General Public License. */
-
-#include "Ac3Decoder.h"
-#include "Fifo.h"
-#include "Manager.h"
-
-extern "C" {
-#include <a52dec/a52.h>
-}
-
-HBAc3Decoder::HBAc3Decoder( HBManager * manager, HBAudio * audio )
-{
- fManager = manager;
- fAudio = audio;
-
- fLock = new HBLock();
- fUsed = false;
-
- /* Init liba52 */
- fState = a52_init( 0 );
- fInFlags = 0;
- fOutFlags = A52_STEREO;
-
- /* Lame wants samples from -32768 to 32768 */
- fSampleLevel = 32768.0;
-
- /* Max size for a A52 frame is 3840 bytes */
- fAc3Frame = new HBBuffer( 3840 );
- fAc3Frame->fSize = 0;
- fAc3Buffer = NULL;
- fPosInAc3Buffer = 0;
- fRawBuffer = NULL;
-}
-
-HBAc3Decoder::~HBAc3Decoder()
-{
- if( fRawBuffer ) delete fRawBuffer;
- if( fAc3Buffer ) delete fAc3Buffer;
- delete fAc3Frame;
- a52_free( fState );
- delete fLock;
-}
-
-bool HBAc3Decoder::Work()
-{
- if( !Lock() )
- {
- return false;
- }
-
- /* Push the latest decoded buffer */
- if( fRawBuffer )
- {
- if( fAudio->fRawFifo->Push( fRawBuffer ) )
- {
- fRawBuffer = NULL;
- }
- else
- {
- Unlock();
- return false;
- }
- }
-
- /* Get a frame header (7 bytes) */
- if( fAc3Frame->fSize < 7 )
- {
- if( GetBytes( 7 ) )
- {
- /* Get the size of the coming frame */
- fFrameSize = a52_syncinfo( fAc3Frame->fData, &fInFlags,
- &fAudio->fInSampleRate,
- &fAudio->fInBitrate );
- if( !fFrameSize )
- {
- Log( "HBAc3Decoder: a52_syncinfo failed" );
- fManager->Error( HB_ERROR_A52_SYNC );
- return false;
- }
- }
- else
- {
- Unlock();
- return false;
- }
- }
-
- /* In case the audio should start later than the video,
- insert some silence */
- if( fAudio->fDelay > 3 * 256 * 1000 / fAudio->fInSampleRate )
- {
- fRawBuffer = new HBBuffer( 12 * 256 * sizeof( float ) );
- for( uint32_t i = 0; i < 12 * 256; i++ )
- {
- ((float*)fRawBuffer->fData)[i] = 0;
- }
- fAudio->fDelay -= 6 * 256 * 1000 / fAudio->fInSampleRate;
-
- Unlock();
- return true;
- }
-
- if( fAc3Frame->fSize >= 7 )
- {
- /* Get the whole frame */
- if( GetBytes( (uint32_t) fFrameSize ) )
- {
- /* Feed liba52 */
- a52_frame( fState, fAc3Frame->fData, &fOutFlags,
- &fSampleLevel, 0 );
- fAc3Frame->fSize = 0;
-
- /* 6 blocks per frame, 256 samples per block */
- fRawBuffer = new HBBuffer( 12 * 256 * sizeof( float ) );
- fRawBuffer->fPosition = fPosition;
-
- sample_t * samples;
- for( int i = 0; i < 6; i++ )
- {
- /* Decode a block */
- a52_block( fState );
-
- /* Get a pointer to the raw data */
- samples = a52_samples( fState );
-
- /* Copy left channel data */
- memcpy( (float*) fRawBuffer->fData + i * 256,
- samples,
- 256 * sizeof( float ) );
-
- /* Copy right channel data */
- memcpy( (float*) fRawBuffer->fData + ( 6 + i ) * 256,
- samples + 256,
- 256 * sizeof( float ) );
- }
- }
- else
- {
- Unlock();
- return false;
- }
- }
-
- Unlock();
- return true;
-}
-
-bool HBAc3Decoder::Lock()
-{
- fLock->Lock();
- if( fUsed )
- {
- fLock->Unlock();
- return false;
- }
- fUsed = true;
- fLock->Unlock();
- return true;
-}
-
-void HBAc3Decoder::Unlock()
-{
- fLock->Lock();
- fUsed = false;
- fLock->Unlock();
-}
-
-/* GetBytes() : pops buffers from the AC3 fifo until fAc3Frame
- contains <size> bytes */
-bool HBAc3Decoder::GetBytes( uint32_t size )
-{
- while( fAc3Frame->fSize < size )
- {
- if( !fAc3Buffer )
- {
- if( !( fAc3Buffer = fAudio->fAc3Fifo->Pop() ) )
- {
- return false;
- }
- fPosInAc3Buffer = 0;
- fPosition = fAc3Buffer->fPosition;
- }
-
- int willCopy = MIN( size - fAc3Frame->fSize,
- fAc3Buffer->fSize - fPosInAc3Buffer );
- memcpy( fAc3Frame->fData + fAc3Frame->fSize,
- fAc3Buffer->fData + fPosInAc3Buffer,
- willCopy );
- fAc3Frame->fSize += willCopy;
- fPosInAc3Buffer += willCopy;
-
- if( fAc3Buffer->fSize == fPosInAc3Buffer )
- {
- delete fAc3Buffer;
- fAc3Buffer = NULL;
- }
- }
-
- return true;
-}
diff --git a/core/Ac3Decoder.h b/core/Ac3Decoder.h
deleted file mode 100644
index f63206b12..000000000
--- a/core/Ac3Decoder.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* $Id: Ac3Decoder.h,v 1.11 2003/10/14 14:35:20 titer Exp $
-
- This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
- It may be used under the terms of the GNU General Public License. */
-
-#ifndef HB_AC3_DECODER_H
-#define HB_AC3_DECODER_H
-
-#include "Common.h"
-
-class HBAc3Decoder
-{
- public:
- HBAc3Decoder( HBManager * manager,
- HBAudio * audio );
- ~HBAc3Decoder();
- bool Work();
-
- private:
- bool Lock();
- void Unlock();
- bool GetBytes( uint32_t size );
-
- HBManager * fManager;
- HBAudio * fAudio;
-
- HBLock * fLock;
- bool fUsed;
-
- /* liba52 */
- a52_state_t * fState;
- int fInFlags;
- int fOutFlags;
- float fSampleLevel;
-
- /* buffers */
- HBBuffer * fAc3Frame;
- HBBuffer * fAc3Buffer;
- uint32_t fPosInAc3Buffer;
- HBBuffer * fRawBuffer;
-
- float fPosition;
- int fFrameSize;
-};
-
-#endif
diff --git a/core/AviMux.c b/core/AviMux.c
new file mode 100644
index 000000000..bd0551217
--- /dev/null
+++ b/core/AviMux.c
@@ -0,0 +1,640 @@
+/* $Id: AviMux.c,v 1.5 2003/11/06 18:35:53 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 "AviMux.h"
+#include "Fifo.h"
+#include "Thread.h"
+
+/* Local structures */
+typedef struct AviMainHeader AviMainHeader;
+typedef struct AviStreamHeader AviStreamHeader;
+typedef struct BitmapInfo BitmapInfo;
+typedef struct WaveFormatEx WaveFormatEx;
+
+/* Local prototypes */
+static void AviMuxThread( void * );
+static void InitAviHeaders( HBAviMux * );
+static void AddChunk( HBAviMux *, HBBuffer **, uint32_t,
+ AviStreamHeader * );
+static void AddIndex( HBAviMux * );
+static void WriteInt8( FILE *, uint8_t );
+static void WriteInt16( FILE *, uint16_t );
+static void WriteInt32( FILE *, uint32_t );
+static void WriteBuffer( FILE *, HBBuffer * );
+static void WriteMainHeader( FILE *, AviMainHeader * );
+static void WriteStreamHeader( FILE *, AviStreamHeader * );
+static void WriteBitmapInfo( FILE *, BitmapInfo * );
+static void WriteWaveFormatEx( FILE *, WaveFormatEx * );
+static void IndexAddInt32( HBBuffer * buffer, uint32_t );
+static HBBuffer * Pop( HBAviMux *, HBFifo * );
+
+#define AVIF_HASINDEX 0x10
+#define AVIIF_KEYFRAME 0x10
+#define FOURCC(a) ((a[3]<<24)|(a[2]<<16)|(a[1]<<8)|a[0])
+
+/* Structures definitions */
+struct __attribute__((__packed__)) AviMainHeader
+{
+ 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];
+};
+
+struct __attribute__((__packed__)) AviStreamHeader
+{
+ 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;
+};
+
+struct __attribute__((__packed__)) BitmapInfo
+{
+ 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;
+ uint8_t Blue;
+ uint8_t Green;
+ uint8_t Red;
+ uint8_t Reserved;
+};
+
+struct __attribute__((__packed__)) WaveFormatEx
+{
+ 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;
+};
+
+struct HBAviMux
+{
+ HBHandle * handle;
+ HBTitle * title;
+ HBAudio * audio;
+ HBAudio * optAudio;
+
+ AviMainHeader mainHeader;
+ AviStreamHeader videoHeader;
+ BitmapInfo videoFormat;
+ AviStreamHeader audioHeader;
+ WaveFormatEx audioFormat;
+ AviStreamHeader optAudioHeader;
+ WaveFormatEx optAudioFormat;
+
+ /* Data size in bytes, not including headers */
+ unsigned size;
+ FILE * file;
+ HBBuffer * index;
+
+ int die;
+ HBThread * thread;
+};
+
+HBAviMux * HBAviMuxInit( HBHandle * handle, HBTitle * title,
+ HBAudio * audio, HBAudio * optAudio )
+{
+ HBAviMux * a;
+ if( !( a = malloc( sizeof( HBAviMux ) ) ) )
+ {
+ HBLog( "HBAviMuxInit: malloc() failed, gonna crash" );
+ return NULL;
+ }
+
+ a->handle = handle;
+ a->title = title;
+ a->audio = audio;
+ a->optAudio = optAudio;
+
+ a->size = 0;
+ a->file = NULL;
+ a->index = HBBufferInit( 1024 * 1024 );
+ a->index->size = 0;
+
+ a->die = 0;
+ a->thread = HBThreadInit( "avi muxer", AviMuxThread, a,
+ HB_NORMAL_PRIORITY );
+ return a;
+}
+
+void HBAviMuxClose( HBAviMux ** _a )
+{
+ HBAviMux * a = *_a;
+
+ a->die = 1;
+ HBThreadClose( &a->thread );
+ free( a );
+
+ *_a = NULL;
+}
+
+static void AviMuxThread( void * _a )
+{
+ HBAviMux * a = (HBAviMux*) _a;
+ HBTitle * title = a->title;
+ HBAudio * audio = a->audio;
+ HBAudio * optAudio = a->optAudio;
+
+ HBBuffer * videoBuffer = NULL;
+ HBBuffer * audioBuffer = NULL;
+ HBBuffer * optAudioBuffer = NULL;
+
+ /* Open destination file */
+ HBLog( "HBAviMux: opening %s", title->file );
+ if( !( a->file = fopen( title->file, "w" ) ) )
+ {
+ HBLog( "HBAviMux: fopen() failed" );
+ HBErrorOccured( a->handle, HB_ERROR_AVI_WRITE );
+ return;
+ }
+
+ /* Get a buffer for each track */
+ videoBuffer = Pop( a, title->mpeg4Fifo );
+ audioBuffer = Pop( a, audio->mp3Fifo );
+ if( optAudio )
+ {
+ optAudioBuffer = Pop( a, optAudio->mp3Fifo );
+ }
+
+ /* Failed ? Then forget it */
+ if( !videoBuffer || !audioBuffer ||
+ ( optAudio && !optAudioBuffer ) )
+ {
+ fclose( a->file );
+ a->file = NULL;
+
+ HBLog( "HBAviMux: deleting %s", title->file );
+ unlink( title->file );
+ return;
+ }
+
+ InitAviHeaders( a );
+
+ for( ;; )
+ {
+ /* Get a buffer for each track */
+ if( !videoBuffer )
+ {
+ videoBuffer = Pop( a, title->mpeg4Fifo );
+ }
+ if( !audioBuffer )
+ {
+ audioBuffer = Pop( a, audio->mp3Fifo );
+ }
+ if( optAudio && !optAudioBuffer )
+ {
+ optAudioBuffer = Pop( a, optAudio->mp3Fifo );
+ }
+
+ if( !videoBuffer && !audioBuffer && !optAudioBuffer )
+ {
+ /* Couldn't get anything -> must exit NOW */
+ break;
+ }
+
+ /* Interleave frames in the same order than they were in the
+ original MPEG stream */
+ if( videoBuffer &&
+ ( !audioBuffer ||
+ videoBuffer->position < audioBuffer->position ) &&
+ ( !optAudioBuffer ||
+ videoBuffer->position < optAudioBuffer->position ) )
+ {
+ AddChunk( a, &videoBuffer, FOURCC( "00dc" ),
+ &a->videoHeader );
+ }
+ else if( audioBuffer &&
+ ( !optAudioBuffer ||
+ audioBuffer->position < optAudioBuffer->position ) )
+ {
+ AddChunk( a, &audioBuffer, FOURCC( "01wb" ),
+ &a->audioHeader );
+ }
+ else
+ {
+ AddChunk( a, &optAudioBuffer, FOURCC( "02wb" ),
+ &a->optAudioHeader );
+ }
+ }
+
+ AddIndex( a );
+
+ HBLog( "HBAviMux: closing %s", title->file );
+ fclose( a->file );
+}
+
+static void InitAviHeaders( HBAviMux * a )
+{
+ HBTitle * title = a->title;
+ HBAudio * audio = a->audio;
+ HBAudio * optAudio = a->optAudio;
+ AviMainHeader * mainHeader = &a->mainHeader;
+ AviStreamHeader * videoHeader = &a->videoHeader;
+ BitmapInfo * videoFormat = &a->videoFormat;
+ AviStreamHeader * audioHeader = &a->audioHeader;
+ WaveFormatEx * audioFormat = &a->audioFormat;
+ AviStreamHeader * optAudioHeader = &a->optAudioHeader;
+ WaveFormatEx * optAudioFormat = &a->optAudioFormat;
+ FILE * file = a->file;
+ int hdrlBytes;
+ int i;
+
+ /* AVI main header */
+ memset( mainHeader, 0, sizeof( AviMainHeader ) );
+ mainHeader->FourCC = FOURCC( "avih" );
+ mainHeader->BytesCount = sizeof( AviMainHeader ) - 8;
+ mainHeader->MicroSecPerFrame = (uint64_t) 1000000 *
+ title->rateBase / title->rate;
+ mainHeader->Streams = optAudio ? 3 : 2;
+ mainHeader->Width = title->outWidth;
+ mainHeader->Height = title->outHeight;
+
+ /* Video stream header */
+ memset( videoHeader, 0, sizeof( AviStreamHeader ) );
+ videoHeader->FourCC = FOURCC( "strh" );
+ videoHeader->BytesCount = sizeof( AviStreamHeader ) - 8;
+ videoHeader->Type = FOURCC( "vids" );
+
+ if( title->codec == HB_CODEC_FFMPEG )
+ videoHeader->Handler = FOURCC( "divx" );
+ else if( title->codec == HB_CODEC_XVID )
+ videoHeader->Handler = FOURCC( "xvid" );
+
+ videoHeader->Scale = title->rateBase;
+ videoHeader->Rate = title->rate;
+
+ /* Video stream format */
+ memset( videoFormat, 0, sizeof( BitmapInfo ) );
+ videoFormat->FourCC = FOURCC( "strf" );
+ videoFormat->BytesCount = sizeof( BitmapInfo ) - 8;
+ videoFormat->Size = sizeof( BitmapInfo ) - 8;
+ videoFormat->Width = title->outWidth;
+ videoFormat->Height = title->outHeight;
+ videoFormat->Planes = 1;
+ videoFormat->BitCount = 24;
+ if( title->codec == HB_CODEC_FFMPEG )
+ videoFormat->Compression = FOURCC( "DX50" );
+ else if( title->codec == HB_CODEC_XVID )
+ videoFormat->Compression = FOURCC( "XVID" );
+
+ /* Audio stream header */
+ memset( audioHeader, 0, sizeof( AviStreamHeader ) );
+ audioHeader->FourCC = FOURCC( "strh" );
+ audioHeader->BytesCount = sizeof( AviStreamHeader ) - 8;
+ audioHeader->Type = FOURCC( "auds" );
+ audioHeader->InitialFrames = 1;
+ audioHeader->Scale = 1152;
+ audioHeader->Rate = audio->outSampleRate;
+ audioHeader->Quality = 0xFFFFFFFF;
+
+ /* Audio stream format */
+ memset( audioFormat, 0, sizeof( WaveFormatEx ) );
+ audioFormat->FourCC = FOURCC( "strf" );
+ audioFormat->BytesCount = sizeof( WaveFormatEx ) - 8;
+ audioFormat->FormatTag = 0x55;
+ audioFormat->Channels = 2;
+ audioFormat->SamplesPerSec = audio->outSampleRate;
+ audioFormat->AvgBytesPerSec = audio->outBitrate * 1024 / 8;
+ audioFormat->BlockAlign = 1152;
+ audioFormat->Size = 12;
+ audioFormat->Id = 1;
+ audioFormat->Flags = 2;
+ audioFormat->BlockSize = 1152;
+ audioFormat->FramesPerBlock = 1;
+ audioFormat->CodecDelay = 1393;
+
+ if( optAudio )
+ {
+ /* optAudio stream header */
+ memset( optAudioHeader, 0, sizeof( AviStreamHeader ) );
+ optAudioHeader->FourCC = FOURCC( "strh" );
+ optAudioHeader->BytesCount = sizeof( AviStreamHeader ) - 8;
+ optAudioHeader->Type = FOURCC( "auds" );
+ optAudioHeader->InitialFrames = 1;
+ optAudioHeader->Scale = 1152;
+ optAudioHeader->Rate = optAudio->outSampleRate;
+ optAudioHeader->Quality = 0xFFFFFFFF;
+
+ /* optAudio stream format */
+ memset( optAudioFormat, 0, sizeof( WaveFormatEx ) );
+ optAudioFormat->FourCC = FOURCC( "strf" );
+ optAudioFormat->BytesCount = sizeof( WaveFormatEx ) - 8;
+ optAudioFormat->FormatTag = 0x55;
+ optAudioFormat->Channels = 2;
+ optAudioFormat->SamplesPerSec = optAudio->outSampleRate;
+ optAudioFormat->AvgBytesPerSec = optAudio->outBitrate * 1024 / 8;
+ optAudioFormat->BlockAlign = 1152;
+ optAudioFormat->Size = 12;
+ optAudioFormat->Id = 1;
+ optAudioFormat->Flags = 2;
+ optAudioFormat->BlockSize = 1152;
+ optAudioFormat->FramesPerBlock = 1;
+ optAudioFormat->CodecDelay = 1393;
+ }
+
+ hdrlBytes = 4 + sizeof( AviMainHeader ) +
+ ( optAudio ? 3 : 2 ) * ( 12 + sizeof( AviStreamHeader ) ) +
+ sizeof( BitmapInfo ) +
+ ( optAudio ? 2 : 1 ) * sizeof( WaveFormatEx );
+
+ /* Here we really start to write into the file */
+
+ WriteInt32( file, FOURCC( "RIFF" ) );
+ WriteInt32( file, 2040 );
+ WriteInt32( file, FOURCC( "AVI " ) );
+ WriteInt32( file, FOURCC( "LIST" ) );
+ WriteInt32( file, hdrlBytes );
+ WriteInt32( file, FOURCC( "hdrl" ) );
+ WriteMainHeader( file, mainHeader );
+ WriteInt32( file, FOURCC( "LIST" ) );
+ WriteInt32( file, 4 + sizeof( AviStreamHeader ) +
+ sizeof( BitmapInfo ) );
+ WriteInt32( file, FOURCC( "strl" ) );
+ WriteStreamHeader( file, videoHeader );
+ WriteBitmapInfo( file, videoFormat );
+ WriteInt32( file, FOURCC( "LIST" ) );
+ WriteInt32( file, 4 + sizeof( AviStreamHeader ) +
+ sizeof( WaveFormatEx ) );
+ WriteInt32( file, FOURCC( "strl" ) );
+ WriteStreamHeader( file, audioHeader );
+ WriteWaveFormatEx( file, audioFormat );
+ if( optAudio )
+ {
+ WriteInt32( file, FOURCC( "LIST" ) );
+ WriteInt32( file, 4 + sizeof( AviStreamHeader ) +
+ sizeof( WaveFormatEx ) );
+ WriteInt32( file, FOURCC( "strl" ) );
+ WriteStreamHeader( file, optAudioHeader );
+ WriteWaveFormatEx( file, optAudioFormat );
+ }
+ WriteInt32( file, FOURCC( "JUNK" ) );
+ WriteInt32( file, 2008 - hdrlBytes );
+ for( i = 0; i < 2008 - hdrlBytes; i++ )
+ {
+ WriteInt8( file, 0 );
+ }
+ WriteInt32( file, FOURCC( "LIST" ) );
+ WriteInt32( file, 4 );
+ WriteInt32( file, FOURCC( "movi" ) );
+}
+
+static void AddChunk( HBAviMux * a, HBBuffer ** _buffer,
+ uint32_t fourCC, AviStreamHeader * header )
+{
+ HBBuffer * buffer = *_buffer;
+
+ /* Update index */
+ IndexAddInt32( a->index, fourCC );
+ IndexAddInt32( a->index, buffer->keyFrame ? AVIIF_KEYFRAME : 0 );
+ IndexAddInt32( a->index, 4 + a->size );
+ IndexAddInt32( a->index, buffer->size );
+
+ /* Write the chunk to the file */
+ fseek( a->file, 0, SEEK_END );
+ WriteInt32( a->file, fourCC );
+ WriteInt32( a->file, buffer->size );
+ WriteBuffer( a->file, buffer );
+
+ /* Chunks must be 2-bytes aligned */
+ if( buffer->size & 1 )
+ {
+ WriteInt8( a->file, 0 );
+ }
+
+ /* Update headers */
+ a->size += 8 + EVEN( buffer->size );
+ header->Length++;
+
+ /* RIFF size */
+ fseek( a->file, 4, SEEK_SET );
+ WriteInt32( a->file, 2040 + a->size );
+
+ /* AviStreamHeader's length */
+ fseek( a->file, 140, SEEK_SET );
+ WriteInt32( a->file, a->videoHeader.Length );
+ fseek( a->file, 268, SEEK_SET );
+ WriteInt32( a->file, a->audioHeader.Length );
+ if( a->optAudio )
+ {
+ fseek( a->file, 382, SEEK_SET );
+ WriteInt32( a->file, a->optAudioHeader.Length );
+ }
+
+ /* movi size */
+ fseek( a->file, 2040, SEEK_SET );
+ WriteInt32( a->file, 4 + a->size );
+
+ HBBufferClose( _buffer );
+}
+
+static void AddIndex( HBAviMux * a )
+{
+ fseek( a->file, 0, SEEK_END );
+
+ WriteInt32( a->file, FOURCC( "idx1" ) );
+ WriteInt32( a->file, a->index->size );
+ WriteBuffer( a->file, a->index );
+
+ a->size += 8 + a->index->size;
+ fseek( a->file, 4, SEEK_SET );
+ WriteInt32( a->file, 2040 + a->size );
+ a->mainHeader.Flags |= AVIF_HASINDEX;
+ fseek( a->file, 24, SEEK_SET );
+ WriteMainHeader( a->file, &a->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 WriteBitmapInfo( FILE * file, BitmapInfo * 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 );
+ WriteInt8( file, bitmapInfo->Blue );
+ WriteInt8( file, bitmapInfo->Green );
+ WriteInt8( file, bitmapInfo->Red );
+ WriteInt8( file, bitmapInfo->Reserved );
+}
+
+static void WriteWaveFormatEx( FILE * file, WaveFormatEx * 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, AviMainHeader * 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, AviStreamHeader * 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;
+}
+
+static HBBuffer * Pop( HBAviMux * a, HBFifo * fifo )
+{
+ HBBuffer * buffer;
+
+ for( ;; )
+ {
+ HBCheckPaused( a->handle );
+
+ if( ( buffer = HBFifoPop( fifo ) ) )
+ {
+ return buffer;
+ }
+
+ if( a->die )
+ {
+ break;
+ }
+
+ HBSnooze( 10000 );
+ }
+
+ return NULL;
+}
+
diff --git a/core/AviMux.h b/core/AviMux.h
new file mode 100644
index 000000000..1fccbe971
--- /dev/null
+++ b/core/AviMux.h
@@ -0,0 +1,15 @@
+/* $Id: AviMux.h,v 1.1 2003/11/03 12:08: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_AVI_MUX_H
+#define HB_AVI_MUX_H
+
+#include "HandBrakeInternal.h"
+
+HBAviMux * HBAviMuxInit( HBHandle *, HBTitle *, HBAudio *, HBAudio * );
+void HBAviMuxClose( HBAviMux ** );
+
+#endif
diff --git a/core/AviMuxer.cpp b/core/AviMuxer.cpp
deleted file mode 100644
index 4a84fe8b8..000000000
--- a/core/AviMuxer.cpp
+++ /dev/null
@@ -1,481 +0,0 @@
-/* $Id: AviMuxer.cpp,v 1.17 2003/10/09 23:33:36 titer Exp $
-
- This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
- It may be used under the terms of the GNU General Public License. */
-
-#include "AviMuxer.h"
-#include "Manager.h"
-
-#define AVIF_HASINDEX 0x10
-#define AVIIF_KEYFRAME 0x10
-
-#define FOURCC(a) ( ( a[3] << 24 ) | ( a[2] << 16 ) | ( a[1] << 8 ) | a[0] )
-
-/* TODO : check return values from fputc/fwrite in case disk is full
- or something */
-
-void WriteInt8( FILE * file, uint8_t val )
-{
- fputc( val, file );
-}
-
-void WriteInt16( FILE * file, uint16_t val )
-{
- fputc( val & 0xFF, file );
- fputc( val >> 8, file );
-}
-
-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 );
-}
-
-void WriteBuffer( FILE * file, HBBuffer * buffer )
-{
- fwrite( buffer->fData, buffer->fSize, 1, file );
-}
-
-void WriteBitmapInfo( FILE * file, BitmapInfo * 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 );
- WriteInt8( file, bitmapInfo->Blue );
- WriteInt8( file, bitmapInfo->Green );
- WriteInt8( file, bitmapInfo->Red );
- WriteInt8( file, bitmapInfo->Reserved );
-}
-
-void WriteWaveFormatEx( FILE * file, WaveFormatEx * 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 );
-}
-
-void WriteMainHeader( FILE * file, AviMainHeader * 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] );
-}
-
-void WriteStreamHeader( FILE * file, AviStreamHeader * 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 );
-}
-
-HBAviIndex::HBAviIndex( uint32_t size )
- : HBBuffer( size )
-{
- fSize = 0;
-}
-
-void HBAviIndex::WriteInt32( uint32_t val )
-{
- if( fSize + 16 > fAllocSize )
- {
- /* Realloc if needed */
- Log( "HBAviIndex::WriteInt32() : reallocing index (%d -> %d MB)",
- fAllocSize / ( 1024 * 1024 ),
- 1 + fAllocSize / ( 1024 * 1024 ) );
- ReAlloc( fAllocSize + 1024 * 1024 );
- }
-
- fData[fSize] = val & 0xFF;
- fData[fSize + 1] = ( val >> 8 ) & 0xFF;
- fData[fSize + 2] = ( val >> 16 ) & 0xFF;
- fData[fSize + 3] = val >> 24;
-
- fSize += 4;
-}
-
-HBAviMuxer::HBAviMuxer( HBManager * manager, HBTitle * title,
- HBAudio * audio1, HBAudio * audio2,
- char * fileName )
- : HBThread( "avimuxer", HB_NORMAL_PRIORITY )
-{
- fManager = manager;
- fTitle = title;
- fAudio1 = audio1;
- fAudio2 = audio2;
- fFileName = strdup( fileName );
-
- fVideoBuffer = NULL;
- fAudio1Buffer = NULL;
- fAudio2Buffer = NULL;
-
- fRiffBytesCount = 2040;
- fMoviBytesCount = 4;
-
- Run();
-}
-
-void HBAviMuxer::DoWork()
-{
- /* Open the destination file */
- if( !( fFile = fopen( fFileName, "w" ) ) )
- {
- Log( "HBAviMuxer: fopen failed" );
- fManager->Error( HB_ERROR_AVI_WRITE );
- return;
- }
-
- /* Initializations */
- memset( &fMainHeader, 0, sizeof( AviMainHeader ) );
- memset( &fVideoStreamHeader, 0, sizeof( AviStreamHeader ) );
- memset( &fAudio1StreamHeader, 0, sizeof( AviStreamHeader ) );
- memset( &fAudio2StreamHeader, 0, sizeof( AviStreamHeader ) );
- memset( &fVideoStreamFormat, 0, sizeof( BitmapInfo ) );
- memset( &fAudio1StreamFormat, 0, sizeof( WaveFormatEx ) );
- memset( &fAudio2StreamFormat, 0, sizeof( WaveFormatEx ) );
-
- /* Alloc an 1 MB index (to be realloced later if needed) */
- fIndex = new HBAviIndex( 1024 * 1024 );
-
- /* Main loop */
- for( ;; )
- {
- while( fSuspend )
- {
- Snooze( 10000 );
- }
-
- if( !fVideoBuffer )
- {
- fVideoBuffer = Pop( fTitle->fMpeg4Fifo );
- }
- if( fAudio1 && !fAudio1Buffer )
- {
- fAudio1Buffer = Pop( fAudio1->fMp3Fifo );
- }
- if( fAudio2 && !fAudio2Buffer )
- {
- fAudio2Buffer = Pop( fAudio2->fMp3Fifo );
- }
-
- if( !fVideoBuffer && !fAudio1Buffer && !fAudio2Buffer )
- {
- break;
- }
-
- if( fVideoBuffer &&
- ( !fAudio1Buffer ||
- fVideoBuffer->fPosition < fAudio1Buffer->fPosition ) &&
- ( !fAudio2Buffer ||
- fVideoBuffer->fPosition < fAudio2Buffer->fPosition ) )
- {
- AddVideoChunk();
- }
- else if( fAudio1Buffer &&
- ( !fAudio2Buffer ||
- fAudio1Buffer->fPosition < fAudio2Buffer->fPosition ) )
- {
- AddAudioChunk( 1 );
- }
- else
- {
- AddAudioChunk( 2 );
- }
- }
-
- /* Write the index */
- fseek( fFile, 0, SEEK_END );
- WriteInt32( fFile, FOURCC( "idx1" ) );
- WriteInt32( fFile, fIndex->fSize );
- WriteBuffer( fFile, fIndex );
-
- /* Update the headers */
- fRiffBytesCount += 8 + fIndex->fSize;
- fMainHeader.Flags |= AVIF_HASINDEX;
- UpdateMainHeader();
-
- delete fIndex;
-
- fclose( fFile );
-}
-
-bool HBAviMuxer::AddVideoChunk()
-{
- fRiffBytesCount += 8 + EVEN( fVideoBuffer->fSize );
- fMoviBytesCount += 8 + EVEN( fVideoBuffer->fSize );
-
- fMainHeader.MicroSecPerFrame = 1000000 * (uint64_t) fTitle->fScale /
- fTitle->fRate;
- fMainHeader.TotalFrames++;
- fMainHeader.Width = fTitle->fOutWidth;
- fMainHeader.Height = fTitle->fOutHeight;
-
- fVideoStreamHeader.FourCC = FOURCC( "strh" );
- fVideoStreamHeader.BytesCount = AVI_STREAM_HEADER_SIZE - 8;
- fVideoStreamHeader.Type = FOURCC( "vids" );
- fVideoStreamHeader.Handler = FOURCC( "DIVX" );
- fVideoStreamHeader.Scale = fTitle->fScale;
- fVideoStreamHeader.Rate = fTitle->fRate;
- fVideoStreamHeader.Length++;
-
- fVideoStreamFormat.FourCC = FOURCC( "strf" );
- fVideoStreamFormat.BytesCount = BITMAP_INFO_SIZE - 8;
- fVideoStreamFormat.Size = BITMAP_INFO_SIZE - 8;
- fVideoStreamFormat.Width = fTitle->fOutWidth;
- fVideoStreamFormat.Height = fTitle->fOutHeight;
- fVideoStreamFormat.Planes = 1;
- fVideoStreamFormat.BitCount = 24;
- fVideoStreamFormat.Compression = FOURCC( "DIVX" );;
-
- UpdateMainHeader();
-
- fseek( fFile, 0, SEEK_END );
-
- /* Update the index */
- fIndex->WriteInt32( FOURCC( "00dc" ) );
- fIndex->WriteInt32( fVideoBuffer->fKeyFrame ? AVIIF_KEYFRAME : 0 );
- fIndex->WriteInt32( ftell( fFile ) - 2044 );
- fIndex->WriteInt32( fVideoBuffer->fSize );
-
- /* Write the chunk */
- WriteInt32( fFile, FOURCC( "00dc" ) );
- WriteInt32( fFile, fVideoBuffer->fSize );
- WriteBuffer( fFile, fVideoBuffer );
-
- /* Chunks must be 2-bytes aligned */
- if( fVideoBuffer->fSize & 1 )
- {
- WriteInt8( fFile, 0 );
- }
-
- delete fVideoBuffer;
- fVideoBuffer = NULL;
-
- return true;
-}
-
-bool HBAviMuxer::AddAudioChunk( int track )
-{
- HBAudio * info;
- HBBuffer * buffer;
- AviStreamHeader * streamHeader;
- WaveFormatEx * streamFormat;
-
- if( track == 1 )
- {
- info = fAudio1;
- buffer = fAudio1Buffer;
- streamHeader = &fAudio1StreamHeader;
- streamFormat = &fAudio1StreamFormat;
- }
- else
- {
- info = fAudio2;
- buffer = fAudio2Buffer;
- streamHeader = &fAudio2StreamHeader;
- streamFormat = &fAudio2StreamFormat;
- }
-
- fRiffBytesCount += 8 + EVEN( buffer->fSize );
- fMoviBytesCount += 8 + EVEN( buffer->fSize );
-
- streamHeader->FourCC = FOURCC( "strh" );
- streamHeader->BytesCount = AVI_STREAM_HEADER_SIZE - 8;
- streamHeader->Type = FOURCC( "auds" );
- streamHeader->InitialFrames = 1;
- streamHeader->Scale = 1152;
- streamHeader->Rate = info->fOutSampleRate;
- streamHeader->Length++;
- streamHeader->Quality = 0xFFFFFFFF;
-
-
- streamFormat->FourCC = FOURCC( "strf" );
- streamFormat->BytesCount = WAVE_FORMAT_EX_SIZE - 8;
- streamFormat->FormatTag = 0x55;
- streamFormat->Channels = 2;
- streamFormat->SamplesPerSec = info->fOutSampleRate;
- streamFormat->AvgBytesPerSec = info->fOutBitrate * 1024 / 8;
- streamFormat->BlockAlign = 1152;
-
- /* stolen from libavformat/wav.c */
- streamFormat->Size = 12;
- streamFormat->Id = 1;
- streamFormat->Flags = 2;
- streamFormat->BlockSize = 1152;
- streamFormat->FramesPerBlock = 1;
- streamFormat->CodecDelay = 1393;
-
- UpdateMainHeader();
-
- fseek( fFile, 0, SEEK_END );
-
- /* Update the index */
- if( track == 1 )
- {
- fIndex->WriteInt32( FOURCC( "01wb" ) );
- }
- else
- {
- fIndex->WriteInt32( FOURCC( "02wb" ) );
- }
- fIndex->WriteInt32( buffer->fKeyFrame ? AVIIF_KEYFRAME : 0 );
- fIndex->WriteInt32( ftell( fFile ) - 2044 );
- fIndex->WriteInt32( buffer->fSize );
-
- /* Write the chunk */
- WriteInt32( fFile,
- ( track == 1 ) ? FOURCC( "01wb" ) : FOURCC( "02wb" ) );
- WriteInt32( fFile, buffer->fSize );
- WriteBuffer( fFile, buffer );
-
- /* Chunks must be 2-bytes aligned */
- if( buffer->fSize & 1 )
- {
- WriteInt8( fFile, 0 );
- }
-
- delete buffer;
- if( track == 1 )
- {
- fAudio1Buffer = NULL;
- }
- else
- {
- fAudio2Buffer = NULL;
- }
-
- return true;
-}
-
-void HBAviMuxer::UpdateMainHeader()
-{
- fMainHeader.FourCC = FOURCC( "avih" );
- fMainHeader.BytesCount = AVI_MAIN_HEADER_SIZE - 8;
- fMainHeader.Streams = 1 + ( fAudio1 ? 1 : 0 ) +
- ( fAudio2 ? 1 : 0 );
-
- fHdrlBytesCount = 4 + AVI_MAIN_HEADER_SIZE + 12 +
- AVI_STREAM_HEADER_SIZE + BITMAP_INFO_SIZE;
-
- if( fAudio1 )
- {
- fHdrlBytesCount += 12 + AVI_STREAM_HEADER_SIZE +
- WAVE_FORMAT_EX_SIZE;
- }
- if( fAudio2 )
- {
- fHdrlBytesCount += 12 + AVI_STREAM_HEADER_SIZE +
- WAVE_FORMAT_EX_SIZE;
- }
-
- fseek( fFile, 0, SEEK_SET );
- WriteInt32( fFile, FOURCC( "RIFF" ) );
- WriteInt32( fFile, fRiffBytesCount );
- WriteInt32( fFile, FOURCC( "AVI " ) );
- WriteInt32( fFile, FOURCC( "LIST" ) );
- WriteInt32( fFile, fHdrlBytesCount );
- WriteInt32( fFile, FOURCC( "hdrl" ) );
-
- WriteMainHeader( fFile, &fMainHeader );
-
- int strlSize;
- strlSize = 4 + AVI_STREAM_HEADER_SIZE + BITMAP_INFO_SIZE;
- WriteInt32( fFile, FOURCC( "LIST" ) );
- WriteInt32( fFile, strlSize );
- WriteInt32( fFile, FOURCC( "strl" ) );
-
- WriteStreamHeader( fFile, &fVideoStreamHeader );
- WriteBitmapInfo( fFile, &fVideoStreamFormat );
-
- if( fAudio1 )
- {
- strlSize = 4 + AVI_STREAM_HEADER_SIZE + WAVE_FORMAT_EX_SIZE;
- WriteInt32( fFile, FOURCC( "LIST" ) );
- WriteInt32( fFile, strlSize );
- WriteInt32( fFile, FOURCC( "strl" ) );
- WriteStreamHeader( fFile, &fAudio1StreamHeader );
- WriteWaveFormatEx( fFile, &fAudio1StreamFormat );
- }
-
- if( fAudio2 )
- {
- strlSize = 4 + AVI_STREAM_HEADER_SIZE + WAVE_FORMAT_EX_SIZE;
- WriteInt32( fFile, FOURCC( "LIST" ) );
- WriteInt32( fFile, strlSize );
- WriteInt32( fFile, FOURCC( "strl" ) );
- WriteStreamHeader( fFile, &fAudio2StreamHeader );
- WriteWaveFormatEx( fFile, &fAudio2StreamFormat );
- }
-
- /* a JUNK chunk to fill the free space.
- size = 2048 -/
- 12 ("RIFFxxxxAVI ") -
- 8 (hdrl's "LIS1Txxxx") -
- fHdrlBytesCount -
- 8 ("JUNKxxxx") -
- 12 ("LISTxxxxmovi) */
- int junkSize = 2008 - fHdrlBytesCount;
- WriteInt32( fFile, FOURCC( "JUNK" ) );
- WriteInt32( fFile, junkSize );
- for( uint32_t i = 0; i < 2008 - fHdrlBytesCount; i++ )
- {
- WriteInt8( fFile, 0 );
- }
-
- /* movi list */
- WriteInt32( fFile, FOURCC( "LIST" ) );
- WriteInt32( fFile, fMoviBytesCount );
- WriteInt32( fFile, FOURCC( "movi" ) );
-}
diff --git a/core/AviMuxer.h b/core/AviMuxer.h
deleted file mode 100644
index 842f7a87a..000000000
--- a/core/AviMuxer.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/* $Id: AviMuxer.h,v 1.10 2003/09/30 14:38:15 titer Exp $
-
- This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
- It may be used under the terms of the GNU General Public License. */
-
-#ifndef HB_AVI_MUXER_H
-#define HB_AVI_MUXER_H
-
-#include "Common.h"
-#include "Fifo.h"
-#include "Thread.h"
-
-/* Misc structures used in AVI headers */
-#define BITMAP_INFO_SIZE 52
-typedef struct BitmapInfo
-{
- 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;
- uint8_t Blue;
- uint8_t Green;
- uint8_t Red;
- uint8_t Reserved;
-} BitmapInfo;
-
-#define WAVE_FORMAT_EX_SIZE 38
-typedef struct WaveFormatEx
-{
- 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;
-} WaveFormatEx;
-
-#define AVI_STREAM_HEADER_SIZE 64
-typedef struct AviStreamHeader
-{
- 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;
-} AviStreamHeader;
-
-#define AVI_MAIN_HEADER_SIZE 64
-typedef struct AviMainHeader
-{
- 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];
-} AviMainHeader;
-
-class HBAviIndex : public HBBuffer
-{
- public:
- HBAviIndex( uint32_t size );
- void WriteInt32( uint32_t val );
-};
-
-class HBAviMuxer : public HBThread
-{
- public:
- HBAviMuxer( HBManager * manager,
- HBTitle * title, HBAudio * audio1,
- HBAudio * audio2,
- char * fileName );
-
- private:
- void DoWork();
- bool AddVideoChunk();
- bool AddAudioChunk( int track );
- void UpdateMainHeader();
-
- HBManager * fManager;
- HBTitle * fTitle;
- HBAudio * fAudio1;
- HBAudio * fAudio2;
- char * fFileName;
-
- FILE * fFile;
- HBBuffer * fVideoBuffer;
- HBBuffer * fAudio1Buffer;
- HBBuffer * fAudio2Buffer;
-
- /* The main header */
- AviMainHeader fMainHeader;
-
- /* The video track */
- AviStreamHeader fVideoStreamHeader;
- BitmapInfo fVideoStreamFormat;
-
- /* The audio tracks */
- AviStreamHeader fAudio1StreamHeader;
- WaveFormatEx fAudio1StreamFormat;
- AviStreamHeader fAudio2StreamHeader;
- WaveFormatEx fAudio2StreamFormat;
-
- uint32_t fRiffBytesCount;
- uint32_t fHdrlBytesCount;
- uint32_t fMoviBytesCount;
-
- HBAviIndex * fIndex;
-
-};
-
-#endif
diff --git a/core/Common.cpp b/core/Common.cpp
deleted file mode 100644
index 4087a001d..000000000
--- a/core/Common.cpp
+++ /dev/null
@@ -1,288 +0,0 @@
-/* $Id: Common.cpp,v 1.31 2003/10/07 22:48:31 titer Exp $
-
- This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
- It may be used under the terms of the GNU General Public License. */
-
-#if defined( SYS_BEOS )
-# include <OS.h>
-#endif
-
-#include "Common.h"
-#include "Fifo.h"
-#include "MpegDemux.h"
-#include "Languages.h"
-
-#include <stdarg.h>
-#include <time.h>
-#include <sys/time.h>
-#include <dvdread/ifo_types.h>
-#include <dvdplay/dvdplay.h>
-#include <dvdplay/info.h>
-#include <dvdplay/state.h>
-#include <dvdplay/nav.h>
-
-extern "C" {
-#include <mpeg2dec/mpeg2.h>
-}
-
-void Snooze( uint64_t time )
-{
-#if defined( SYS_BEOS )
- snooze( time );
-#elif defined( SYS_MACOSX ) || defined( SYS_LINUX )
- usleep( time );
-#endif
-}
-
-void Log( char * log, ... )
-{
- if( !getenv( "HB_DEBUG" ) )
- {
- return;
- }
-
- char string[1024];
-
- /* Show the time */
- time_t _now = time( NULL );
- struct tm * now = localtime( &_now );
- sprintf( string, "[%02d:%02d:%02d] ",
- now->tm_hour, now->tm_min, now->tm_sec );
-
- /* Convert the message to a string */
- va_list args;
- va_start( args, log );
- int ret = vsnprintf( string + 11, 1011, log, args );
- va_end( args );
-
- /* Add the end of line */
- string[ret+11] = '\n';
- string[ret+12] = '\0';
-
- /* Print it */
- fprintf( stderr, "%s", string );
-}
-
-char * LanguageForCode( int code )
-{
- char codeString[2];
- codeString[0] = ( code >> 8 ) & 0xFF;
- codeString[1] = code & 0xFF;
-
- iso639_lang_t * lang;
- for( lang = languages; lang->engName; lang++ )
- {
- if( !strncmp( lang->iso639_1, codeString, 2 ) )
- {
- if( *lang->nativeName )
- return lang->nativeName;
-
- return lang->engName;
- }
- }
-
- return "Unknown";
-}
-
-uint64_t GetDate()
-{
- struct timeval tv;
- gettimeofday( &tv, NULL );
- return( (uint64_t) tv.tv_sec * 1000000 + (uint64_t) tv.tv_usec );
-}
-
-int GetCPUCount()
-{
- int CPUCount = 1;
-
-#if defined( SYS_BEOS )
- system_info info;
- get_system_info( &info );
- CPUCount = info.cpu_count;
-
-#elif defined( SYS_MACOSX )
- FILE * info;
- char buffer[256];
-
- if( ( info = popen( "/usr/sbin/sysctl hw.ncpu", "r" ) ) )
- {
- if( fgets( buffer, 256, info ) )
- {
- int count;
- if( sscanf( buffer, "hw.ncpu: %d", &count ) == 1 )
- {
- CPUCount = count;
- }
- else
- {
- Log( "GetCPUCount: sscanf() failed" );
- }
- }
- else
- {
- Log( "GetCPUCount: fgets() failed" );
- }
- fclose( info );
- }
- else
- {
- Log( "GetCPUCount: popen() failed" );
- }
-
-#elif defined( SYS_LINUX )
- FILE * info;
- char buffer[256];
-
- if( ( info = fopen( "/proc/cpuinfo", "r" ) ) )
- {
- int count = 0;
- while( fgets( buffer, 256, info ) )
- {
- if( !memcmp( buffer, "processor",
- sizeof( "processor" ) - 1 ) )
- {
- count++;
- }
- }
- CPUCount = count;
- fclose( info );
- }
- else
- {
- Log( "GetCPUCount: fopen() failed" );
- }
-
-#endif
- CPUCount = MAX( 1, CPUCount );
- CPUCount = MIN( CPUCount, 8 );
-
- return CPUCount;
-}
-
-#define HBLIST_DEFAULT_SIZE 20
-
-HBList::HBList()
-{
- fItems = (void**) malloc( HBLIST_DEFAULT_SIZE * sizeof( void* ) );
- fAllocItems = HBLIST_DEFAULT_SIZE;
- fNbItems = 0;
-}
-
-HBList::~HBList()
-{
- free( fItems );
-}
-
-uint32_t HBList::CountItems()
-{
- return fNbItems;
-}
-
-void HBList::AddItem( void * item )
-{
- if( !item )
- {
- return;
- }
-
- if( fNbItems == fAllocItems )
- {
- fAllocItems += HBLIST_DEFAULT_SIZE;
- fItems = (void**) realloc( fItems, fAllocItems * sizeof( void* ) );
- }
-
- fItems[fNbItems] = item;
-
- fNbItems++;
-}
-
-void HBList::RemoveItem( void * item )
-{
- if( !item || !fNbItems )
- {
- return;
- }
-
- uint32_t i;
- for( i = 0; i < fNbItems; i++ )
- {
- if( fItems[i] == item )
- {
- break;
- }
- }
-
- if( fItems[i] != item )
- {
- Log( "HBList::RemoveItem() : item not in the list" );
- return;
- }
-
- for( ; i < fNbItems - 1; i++ )
- {
- fItems[i] = fItems[i+1];
- }
-
- fNbItems--;
-}
-
-void * HBList::ItemAt( uint32_t index )
-{
- if( index < fNbItems )
- {
- return fItems[index];
- }
-
- return NULL;
-}
-
-HBTitle::HBTitle( char * device, int index )
-{
- fDevice = strdup( device );
- fIndex = index;
-
- fAudioList = new HBList();
- fPSFifo = NULL;
- fMpeg2Fifo = NULL;
- fRawFifo = NULL;
- fMpeg4Fifo = NULL;
-
- fTopCrop = 0;
- fBottomCrop = 0;
- fLeftCrop = 0;
- fRightCrop = 0;
- fBitrate = 1024;
- fDeinterlace = false;
- fTwoPass = false;
-}
-
-HBTitle::~HBTitle()
-{
- HBAudio * audio;
-
- while( ( audio = (HBAudio*) fAudioList->ItemAt( 0 ) ) )
- {
- fAudioList->RemoveItem( audio );
- delete audio;
- }
- delete fAudioList;
-}
-
-/* Audio track */
-HBAudio::HBAudio( int id, char * description )
-{
- fId = id;
- fDescription = strdup( description );
- fOutSampleRate = 44100;
- fOutBitrate = 128;
-
- fAc3Fifo = NULL;
- fRawFifo = NULL;
- fMp3Fifo = NULL;
-}
-
-HBAudio::~HBAudio()
-{
- free( fDescription );
-}
diff --git a/core/Common.h b/core/Common.h
deleted file mode 100644
index 3c138e2a1..000000000
--- a/core/Common.h
+++ /dev/null
@@ -1,215 +0,0 @@
-/* $Id: Common.h,v 1.34 2003/10/13 17:49:58 titer Exp $
-
- This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
- It may be used under the terms of the GNU General Public License. */
-
-#ifndef HB_COMMON_H
-#define HB_COMMON_H
-
-/* Standard headers */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <inttypes.h>
-typedef uint8_t byte_t;
-
-/* Misc structures */
-typedef struct a52_state_s a52_state_t;
-typedef struct lame_global_struct lame_global_flags;
-typedef struct dvdplay_s * dvdplay_ptr;
-typedef struct mpeg2dec_s mpeg2dec_t;
-typedef struct AVPicture AVPicture;
-typedef struct AVFrame AVFrame;
-typedef struct AVCodecContext AVCodecContext;
-typedef struct ImgReSampleContext ImgReSampleContext;
-
-/* Classes */
-class HBAc3Decoder;
-class HBAudio;
-class HBAviIndex;
-class HBAviMuxer;
-class HBBuffer;
-class HBDVDReader;
-class HBFifo;
-class HBList;
-class HBLock;
-class HBManager;
-class HBMp3Encoder;
-class HBMpeg2Decoder;
-class HBMpeg4Encoder;
-class HBMpegDemux;
-class HBResizer;
-class HBScanner;
-class HBStatus;
-class HBThread;
-class HBTitle;
-class HBWorker;
-
-/* Handy macros */
-#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) & 0x1 ) ? ( (a) + 1 ) : (a) )
-#define MULTIPLE_16( a ) ( 16 * ( ( (a) + 8 ) / 16 ) )
-
-#define VOUT_ASPECT_FACTOR 432000
-
-/* Global prototypes */
-void Snooze( uint64_t time );
-void Log( char * log, ... );
-char * LanguageForCode( int code );
-uint64_t GetDate();
-int GetCPUCount();
-
-/* Possible states */
-typedef enum
-{
- HB_MODE_UNDEF = 00000,
- HB_MODE_NEED_VOLUME = 00001,
- HB_MODE_SCANNING = 00002,
- HB_MODE_INVALID_VOLUME = 00004,
- HB_MODE_READY_TO_RIP = 00010,
- HB_MODE_ENCODING = 00020,
- HB_MODE_SUSPENDED = 00040,
- HB_MODE_STOPPING = 00100,
- HB_MODE_DONE = 00200,
- HB_MODE_CANCELED = 00400,
- HB_MODE_ERROR = 01000
-} HBMode;
-
-/* Possible errors */
-typedef enum
-{
- HB_ERROR_A52_SYNC = 0,
- HB_ERROR_AVI_WRITE,
- HB_ERROR_DVD_OPEN,
- HB_ERROR_DVD_READ,
- HB_ERROR_MP3_INIT,
- HB_ERROR_MP3_ENCODE,
- HB_ERROR_MPEG4_INIT
-} HBError;
-
-class HBStatus
-{
- public:
- HBMode fMode;
-
- /* HB_MODE_SCANNING */
- char * fScannedVolume;
- int fScannedTitle;
-
- /* HB_MODE_SCANDONE */
- HBList * fTitleList;
-
- /* HB_MODE_ENCODING || HB_MODE_SUSPENDED */
- float fPosition;
- float fFrameRate;
- uint32_t fFrames;
- uint64_t fStartDate;
- uint32_t fRemainingTime; /* in seconds */
- uint64_t fSuspendDate;
-
- /* HB_MODE_ERROR */
- HBError fError;
-};
-
-class HBList
-{
- public:
- HBList();
- ~HBList();
- uint32_t CountItems();
- void AddItem( void * item );
- void RemoveItem( void * item );
- void * ItemAt( uint32_t index );
-
- private:
- void ** fItems;
- uint32_t fAllocItems;
- uint32_t fNbItems;
-};
-
-class HBAudio
-{
- public:
- HBAudio( int id, char * description );
- ~HBAudio();
-
- /* Ident */
- uint32_t fId;
- char * fDescription;
-
- /* Settings */
- int fInSampleRate;
- int fOutSampleRate;
- int fInBitrate;
- int fOutBitrate;
-
- int64_t fDelay; /* in ms */
-
- /* Fifos */
- HBFifo * fAc3Fifo;
- HBFifo * fRawFifo;
- HBFifo * fMp3Fifo;
-
- /* Threads */
- HBAc3Decoder * fAc3Decoder;
- HBMp3Encoder * fMp3Encoder;
-};
-
-class HBTitle
-{
- public:
- HBTitle( char * device, int index );
- ~HBTitle();
-
- char * fDevice;
- int fIndex;
- uint64_t fLength;
-
- /* Video input */
- uint32_t fInWidth;
- uint32_t fInHeight;
- uint32_t fAspect;
- uint32_t fRate;
- uint32_t fScale;
-
- /* Video output */
- bool fDeinterlace;
- uint32_t fOutWidth;
- uint32_t fOutHeight;
- uint32_t fOutWidthMax;
- uint32_t fOutHeightMax;
- uint32_t fTopCrop;
- uint32_t fBottomCrop;
- uint32_t fLeftCrop;
- uint32_t fRightCrop;
- uint32_t fBitrate;
- bool fTwoPass;
-
- /* Audio infos */
- HBList * fAudioList;
-
- /* Fifos */
- HBFifo * fPSFifo;
- HBFifo * fMpeg2Fifo;
- HBFifo * fRawFifo;
- HBFifo * fResizedFifo;
- HBFifo * fMpeg4Fifo;
-
- /* Threads */
- HBDVDReader * fDVDReader;
- HBMpegDemux * fMpegDemux;
- HBMpeg2Decoder * fMpeg2Decoder;
- HBResizer * fResizer;
- HBMpeg4Encoder * fMpeg4Encoder;
- HBAviMuxer * fAviMuxer;
- HBWorker * fWorkers[4];
-};
-
-#endif
diff --git a/core/DVDRead.c b/core/DVDRead.c
new file mode 100644
index 000000000..58e8f1031
--- /dev/null
+++ b/core/DVDRead.c
@@ -0,0 +1,328 @@
+/* $Id: DVDRead.c,v 1.4 2003/11/06 13:03: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 "DVDRead.h"
+#include "Fifo.h"
+#include "Thread.h"
+
+#include <dvdread/ifo_types.h>
+#include <dvdplay/dvdplay.h>
+#include <dvdplay/info.h>
+#include <dvdplay/state.h>
+#include <dvdplay/nav.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;
+
+ dvdplay_ptr vmg;
+ HBTitle * title;
+ HBAudio * audio;
+ HBAudio * optAudio;
+ int beginPosition;
+ int endPosition;
+ int pass;
+ HBBuffer * psBuffer;
+ HBList * esBufferList;
+ HBBuffer * videoBuf;
+ HBBuffer * audioBuf;
+ HBBuffer * optAudioBuf;
+ int videoStart;
+ int audioStart;
+ int optAudioStart;
+
+ int die;
+ HBThread * thread;
+};
+
+HBDVDRead * HBDVDReadInit( HBHandle * handle, HBTitle * t,
+ HBAudio * a1, HBAudio * a2 )
+{
+ HBDVDRead * d;
+ if( !( d = malloc( sizeof( HBDVDRead ) ) ) )
+ {
+ HBLog( "HBDVDReadInit: malloc() failed, gonna crash" );
+ return NULL;
+ }
+
+ /* Initializations */
+ d->handle = handle;
+ d->vmg = NULL;
+ d->title = t;
+ d->audio = a1;
+ d->optAudio = a2;
+ d->beginPosition = 0;
+ d->endPosition = 0;
+ d->pass = 0;
+ d->psBuffer = NULL;
+ d->esBufferList = HBListInit();
+ d->videoBuf = NULL;
+ d->audioBuf = NULL;
+ d->optAudioBuf = NULL;
+ d->videoStart = -1;
+ d->audioStart = -1;
+ d->optAudioStart = -1;
+
+ /* 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;
+ uint8_t dummy[DVD_VIDEO_LB_LEN];
+ int i;
+
+ /* Open the device */
+ d->vmg = dvdplay_open( d->title->device, NULL, NULL );
+ if( !d->vmg )
+ {
+ HBLog( "HBDVDRead: dvdplay_open() failed" );
+ HBErrorOccured( d->handle, HB_ERROR_DVD_OPEN );
+ return;
+ }
+
+ /* Open the title */
+ dvdplay_start( d->vmg, d->title->index );
+ d->beginPosition = dvdplay_title_first( d->vmg );
+ d->endPosition = dvdplay_title_end( d->vmg );
+
+ HBLog( "HBDVDRead: starting, blocks: %d to %d",
+ d->beginPosition, d->endPosition );
+
+ /* Lalala */
+ dvdplay_read( d->vmg, dummy, 1 );
+
+ /* Do the job */
+ for( i = 0; i < ( d->title->twoPass ? 2 : 1 ); i++ )
+ {
+ dvdplay_seek( d->vmg, 0 );
+
+ HBLog( "HBDVDRead: starting pass %d of %d", i + 1,
+ d->title->twoPass ? 2 : 1 );
+
+ d->pass = d->title->twoPass ? ( i + 1 ) : 0;
+
+ if( !DoPass( d ) )
+ {
+ break;
+ }
+ }
+
+ /* Flag the latest buffers so we know when we're done */
+ if( !d->die )
+ {
+ HBLog( "HBDVDRead: done" );
+
+ if( d->videoBuf )
+ {
+ d->videoBuf->last = 1;
+ Push( d, d->title->mpeg2Fifo, &d->videoBuf );
+ }
+ if( d->audioBuf )
+ {
+ d->audioBuf->last = 1;
+ Push( d, d->audio->ac3Fifo, &d->audioBuf );
+ }
+ if( d->optAudioBuf )
+ {
+ d->optAudioBuf->last = 1;
+ Push( d, d->optAudio->ac3Fifo, &d->optAudioBuf );
+ }
+ }
+
+ /* Clean up */
+ dvdplay_close( d->vmg );
+}
+
+
+static int DoPass( HBDVDRead * d )
+{
+ int i;
+
+ for( i = 0; i < d->endPosition - d->beginPosition; i++ )
+ {
+ d->psBuffer = HBBufferInit( DVD_VIDEO_LB_LEN );
+ d->psBuffer->position =
+ (float) i / ( d->endPosition - d->beginPosition );
+
+ if( d->pass )
+ {
+ d->psBuffer->position /= 2;
+
+ if( d->pass == 2 )
+ {
+ d->psBuffer->position += 0.5;
+ }
+ }
+ d->psBuffer->pass = d->pass;
+
+ if( dvdplay_read( d->vmg, d->psBuffer->data, 1 ) < 0 )
+ {
+ HBLog( "HBDVDRead: dvdplay_read() 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 )
+{
+ HBBuffer * esBuffer;
+
+ /* 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;
+ }
+
+ if( esBuffer->streamId == 0xE0 )
+ {
+ if( d->videoStart < 0 )
+ {
+ d->videoStart = esBuffer->pts / 90;
+ HBLog( "HBDVDRead: got first 0xE0 packet (%d)",
+ d->videoStart );
+ }
+
+ if( d->videoBuf )
+ {
+ d->videoBuf->last = 0;
+ if( !Push( d, d->title->mpeg2Fifo, &d->videoBuf ) )
+ {
+ return 0;
+ }
+ }
+
+ HBListRemove( d->esBufferList, esBuffer );
+ d->videoBuf = esBuffer;
+ }
+ else if( esBuffer->streamId == d->audio->id )
+ {
+ if( d->audioStart < 0 )
+ {
+ d->audioStart = esBuffer->pts / 90;
+ HBLog( "HBDVDRead: got first 0x%x packet (%d)",
+ d->audio->id, d->audioStart );
+
+ d->audio->delay = d->audioStart - d->videoStart;
+ }
+
+ if( d->audioBuf )
+ {
+ d->audioBuf->last = 0;
+ if( !Push( d, d->audio->ac3Fifo, &d->audioBuf ) )
+ {
+ return 0;
+ }
+ }
+
+ HBListRemove( d->esBufferList, esBuffer );
+ d->audioBuf = esBuffer;
+ }
+ else if( d->optAudio && esBuffer->streamId == d->optAudio->id )
+ {
+ if( d->optAudioStart < 0 )
+ {
+ d->optAudioStart = esBuffer->pts / 90;
+ HBLog( "HBDVDRead: got first 0x%x packet (%d)",
+ d->optAudio->id, d->optAudioStart );
+
+ d->optAudio->delay = d->optAudioStart - d->videoStart;
+ }
+
+ if( d->optAudioBuf )
+ {
+ d->optAudioBuf->last = 0;
+ if( !Push( d, d->optAudio->ac3Fifo, &d->optAudioBuf ) )
+ {
+ return 0;
+ }
+ }
+
+ HBListRemove( d->esBufferList, esBuffer );
+ d->optAudioBuf = esBuffer;
+ }
+ else
+ {
+ HBListRemove( d->esBufferList, esBuffer );
+ HBBufferClose( &esBuffer );
+ }
+ }
+
+ return 1;
+}
+
+static int Push( HBDVDRead * d, HBFifo * fifo, HBBuffer ** buffer )
+{
+ for( ;; )
+ {
+ HBCheckPaused( d->handle );
+
+ if( HBFifoPush( fifo, buffer ) )
+ {
+ return 1;
+ }
+
+ if( d->die )
+ {
+ break;
+ }
+
+ HBSnooze( 10000 );
+ }
+
+ return 0;
+}
+
diff --git a/core/DVDRead.h b/core/DVDRead.h
new file mode 100644
index 000000000..7a9aa7e21
--- /dev/null
+++ b/core/DVDRead.h
@@ -0,0 +1,16 @@
+/* $Id: DVDRead.h,v 1.1 2003/11/03 12:08: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_DVD_READ_H
+#define HB_DVD_READ_H
+
+#include "HandBrakeInternal.h"
+
+HBDVDRead * HBDVDReadInit( HBHandle *, HBTitle *,
+ HBAudio *, HBAudio * );
+void HBDVDReadClose( HBDVDRead ** );
+
+#endif
diff --git a/core/DVDReader.cpp b/core/DVDReader.cpp
deleted file mode 100644
index c3c0e6f3e..000000000
--- a/core/DVDReader.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-/* $Id: DVDReader.cpp,v 1.18 2003/10/16 13:39:13 titer Exp $
-
- This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
- It may be used under the terms of the GNU General Public License. */
-
-#include "DVDReader.h"
-#include "Manager.h"
-#include "Fifo.h"
-
-#include <dvdread/ifo_types.h>
-#include <dvdplay/dvdplay.h>
-#include <dvdplay/info.h>
-#include <dvdplay/state.h>
-#include <dvdplay/nav.h>
-
-HBDVDReader::HBDVDReader( HBManager * manager, HBTitle * title )
- : HBThread( "dvdreader", HB_NORMAL_PRIORITY )
-{
- fManager = manager;
- fTitle = title;
-
- Run();
-}
-
-void HBDVDReader::DoWork()
-{
- /* Open the device */
- dvdplay_ptr vmg;
- vmg = dvdplay_open( fTitle->fDevice, NULL, NULL );
- if( !vmg )
- {
- Log( "HBDVDReader: dvdplay_open() failed" );
- fManager->Error( HB_ERROR_DVD_OPEN );
- return;
- }
-
- bool die = false;
- for( int i = 0; i < ( fTitle->fTwoPass ? 2 : 1 ); i++ )
- {
- /* Open the title */
- dvdplay_start( vmg, fTitle->fIndex );
-
- /* Read */
- HBBuffer * dvdBuffer;
- int beginPosition = dvdplay_position( vmg );
- int endPosition = dvdplay_title_end( vmg );
-
- while( dvdplay_position( vmg ) < endPosition )
- {
- while( fSuspend )
- {
- Snooze( 10000 );
- }
-
- dvdBuffer = new HBBuffer( DVD_VIDEO_LB_LEN );
- dvdBuffer->fPosition = (float) ( dvdplay_position( vmg )
- - beginPosition ) /
- (float) ( endPosition - beginPosition ) ;
- if( fTitle->fTwoPass )
- {
- dvdBuffer->fPosition /= 2;
- if( i == 1 )
- {
- dvdBuffer->fPosition += 0.5;
- }
- }
- dvdBuffer->fPass = fTitle->fTwoPass ? ( i + 1 ) : 0;
-
- if( dvdplay_read( vmg, dvdBuffer->fData, 1 ) < 0 )
- {
- Log( "HBDVDReader: dvdplay_read() failed" );
- delete dvdBuffer;
- fManager->Error( HB_ERROR_DVD_READ );
- die = true;
- break;
- }
-
- if( !Push( fTitle->fPSFifo, dvdBuffer ) )
- {
- die = true;
- break;
- }
- }
-
- if( die )
- {
- break;
- }
- }
-
- if( !die )
- {
- fManager->Done();
- }
-
- /* Clean up */
- dvdplay_close( vmg );
-}
diff --git a/core/DVDReader.h b/core/DVDReader.h
deleted file mode 100644
index b76f57566..000000000
--- a/core/DVDReader.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* $Id: DVDReader.h,v 1.5 2003/09/30 14:38:15 titer Exp $
-
- This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
- It may be used under the terms of the GNU General Public License. */
-
-#ifndef HB_DVD_READER_H
-#define HB_DVD_READER_H
-
-#include "Common.h"
-#include "Thread.h"
-
-class HBDVDReader : public HBThread
-{
- public:
- HBDVDReader( HBManager * manager, HBTitle * title );
-
- private:
- void DoWork();
-
- HBManager * fManager;
- HBTitle * fTitle;
-};
-
-#endif
diff --git a/core/FfmpegEnc.c b/core/FfmpegEnc.c
new file mode 100644
index 000000000..2118c29d6
--- /dev/null
+++ b/core/FfmpegEnc.c
@@ -0,0 +1,230 @@
+/* $Id: FfmpegEnc.c,v 1.5 2003/11/06 13:03: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 "FfmpegEnc.h"
+#include "Fifo.h"
+#include "Work.h"
+
+#include <ffmpeg/avcodec.h>
+
+/* Extern functions */
+void HBSetPosition( HBHandle *, float );
+
+/* Local prototypes */
+static int FfmpegEncWork( HBWork * );
+
+struct HBFfmpegEnc
+{
+ HB_WORK_COMMON_MEMBERS
+
+ HBHandle * handle;
+ HBTitle * title;
+
+ HBBuffer * mpeg4Buffer;
+ int pass;
+ AVCodecContext * context;
+ FILE * file;
+};
+
+HBFfmpegEnc * HBFfmpegEncInit( HBHandle * handle, HBTitle * title )
+{
+ HBFfmpegEnc * f;
+ if( !( f = malloc( sizeof( HBFfmpegEnc ) ) ) )
+ {
+ HBLog( "HBFfmpegEncInit: malloc() failed, gonna crash" );
+ return NULL;
+ }
+
+ f->name = strdup( "FfmpegEnc" );
+ f->work = FfmpegEncWork;
+
+ f->handle = handle;
+ f->title = title;
+
+ f->mpeg4Buffer = NULL;
+ f->pass = 42;
+ f->context = NULL;
+ f->file = NULL;
+
+ return f;
+}
+
+void HBFfmpegEncClose( HBFfmpegEnc ** _f )
+{
+ HBFfmpegEnc * f = *_f;
+
+ if( f->context )
+ {
+ HBLog( "HBFfmpegEnc: closing libavcodec (pass %d)",
+ f->pass );
+
+ avcodec_close( f->context );
+ if( f->file )
+ {
+ fclose( f->file );
+ f->file = NULL;
+ }
+ }
+ free( f->name );
+ free( f );
+
+ *_f = NULL;
+}
+
+static int FfmpegEncWork( HBWork * w )
+{
+ HBFfmpegEnc * f = (HBFfmpegEnc*) w;
+ HBTitle * title = f->title;
+
+ HBBuffer * scaledBuffer;
+ HBBuffer * mpeg4Buffer;
+ AVFrame * frame;
+
+ int didSomething = 0;
+
+ if( f->mpeg4Buffer )
+ {
+ if( HBFifoPush( title->mpeg4Fifo, &f->mpeg4Buffer ) )
+ {
+ didSomething = 1;
+ }
+ else
+ {
+ return didSomething;
+ }
+ }
+
+ if( ( scaledBuffer = HBFifoPop( title->scaledFifo ) ) )
+ {
+ didSomething = 1;
+ }
+ else
+ {
+ return didSomething;
+ }
+
+ /* Init or re-init if needed */
+ if( scaledBuffer->pass != f->pass )
+ {
+ AVCodec * codec;
+ AVCodecContext * context;
+
+ if( f->context )
+ {
+ HBLog( "HBFfmpegEnc: closing libavcodec (pass %d)",
+ f->pass );
+
+ avcodec_close( f->context );
+ if( f->file )
+ {
+ fclose( f->file );
+ f->file = NULL;
+ }
+ }
+
+ f->pass = scaledBuffer->pass;
+
+ HBLog( "HBFfmpegEnc: opening libavcodec (pass %d)", f->pass );
+ codec = avcodec_find_encoder( CODEC_ID_MPEG4 );
+ if( !codec )
+ {
+ HBLog( "HBFfmpegEnc: avcodec_find_encoder() failed" );
+ HBErrorOccured( f->handle, HB_ERROR_MPEG4_INIT );
+ return didSomething;
+ }
+
+ context = avcodec_alloc_context();
+ context->bit_rate = 1024 * title->bitrate;
+ context->bit_rate_tolerance = 10240 * title->bitrate;
+ 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( f->pass )
+ {
+ char fileName[1024]; memset( fileName, 0, 1024 );
+ sprintf( fileName, "/tmp/HB.%d.ffmpeg.log",
+ HBGetPid( f->handle ) );
+
+ if( f->pass == 1 )
+ {
+ f->file = fopen( fileName, "w" );
+
+ context->flags |= CODEC_FLAG_PASS1;
+ }
+ else
+ {
+ FILE * file;
+ int size;
+ char * log;
+
+ file = fopen( fileName, "r" );
+ 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;
+ }
+ }
+
+ if( avcodec_open( context, codec ) < 0 )
+ {
+ HBLog( "HBFfmpegEnc: avcodec_open() failed" );
+ HBErrorOccured( f->handle, HB_ERROR_MPEG4_INIT );
+ return didSomething;
+ }
+
+ f->context = context;
+ }
+
+ 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( f->context, mpeg4Buffer->data,
+ mpeg4Buffer->alloc, frame );
+ mpeg4Buffer->keyFrame = f->context->coded_frame->key_frame;
+
+ /* Inform the GUI about the current position */
+ HBPosition( f->handle, scaledBuffer->position );
+
+ if( f->pass == 1 )
+ {
+ if( f->context->stats_out )
+ {
+ fprintf( f->file, "%s", f->context->stats_out );
+ }
+ HBBufferClose( &mpeg4Buffer );
+ }
+
+ HBBufferClose( &scaledBuffer );
+ free( frame );
+
+ f->mpeg4Buffer = mpeg4Buffer;
+
+ return didSomething;
+}
diff --git a/core/FfmpegEnc.h b/core/FfmpegEnc.h
new file mode 100644
index 000000000..8ab622011
--- /dev/null
+++ b/core/FfmpegEnc.h
@@ -0,0 +1,15 @@
+/* $Id: FfmpegEnc.h,v 1.1 2003/11/03 12:08: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. */
+
+#ifndef HB_FFMPEG_ENC_H
+#define HB_FFMPEG_ENC_H
+
+#include "HandBrakeInternal.h"
+
+HBFfmpegEnc * HBFfmpegEncInit( HBHandle *, HBTitle * );
+void HBFfmpegEncClose( HBFfmpegEnc ** );
+
+#endif
diff --git a/core/Fifo.c b/core/Fifo.c
new file mode 100644
index 000000000..a8f6034c0
--- /dev/null
+++ b/core/Fifo.c
@@ -0,0 +1,105 @@
+/* $Id: Fifo.c,v 1.2 2003/11/05 19:14:37 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"
+
+HBBuffer * HBBufferInit( int size )
+{
+ HBBuffer * b;
+ if( !( b = malloc( sizeof( HBBuffer ) ) ) )
+ {
+ HBLog( "HBBufferInit: malloc() failed, gonna crash" );
+ return NULL;
+ }
+
+ b->alloc = size;
+ b->size = size;
+
+ if( !( b->data = malloc( size ) ) )
+ {
+ HBLog( "HBBufferInit: malloc() failed, gonna crash" );
+ free( b );
+ return NULL;
+ }
+
+ b->position = 0.0;
+ b->streamId = 0;
+ b->keyFrame = 0;
+ b->pts = 0;
+ b->pass = 0;
+ b->last = 0;
+
+ return b;
+}
+
+void HBBufferReAlloc( HBBuffer * b, int size )
+{
+ b->alloc = size;
+ b->data = realloc( b->data, size );
+
+ if( !b->data )
+ {
+ HBLog( "HBBufferReAlloc: realloc() failed, gonna crash soon" );
+ }
+}
+
+void HBBufferClose( HBBuffer ** b )
+{
+ free( (*b)->data );
+ (*b) = NULL;
+}
+
+HBFifo * HBFifoInit( int capacity )
+{
+ HBFifo * f;
+ if( !( f = malloc( sizeof( HBFifo ) ) ) )
+ {
+ HBLog( "HBFifoInit: malloc() failed, gonna crash" );
+ return NULL;
+ }
+
+ f->capacity = capacity;
+ f->whereToPush = 0;
+ f->whereToPop = 0;
+
+ if( !( f->buffers = malloc( ( capacity + 1 ) * sizeof( void* ) ) ) )
+ {
+ HBLog( "HBFifoInit: malloc() failed, gonna crash" );
+ free( f );
+ return NULL;
+ }
+
+ f->lock = HBLockInit();
+
+ return f;
+}
+
+int HBFifoSize( HBFifo * f )
+{
+ return ( f->capacity + 1 + f->whereToPush - f->whereToPop ) %
+ ( f->capacity + 1 );
+}
+
+void HBFifoClose( HBFifo ** _f )
+{
+ HBFifo * f = (*_f);
+
+ HBLog( "HBFifoClose: 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 );
+ free( f->buffers );
+ free( f );
+ (*_f) = NULL;
+}
+
diff --git a/core/Fifo.cpp b/core/Fifo.cpp
deleted file mode 100644
index d1d051c33..000000000
--- a/core/Fifo.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-/* $Id: Fifo.cpp,v 1.15 2003/10/13 14:12:18 titer Exp $
-
- This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
- It may be used under the terms of the GNU General Public License. */
-
-#include "Fifo.h"
-#include "Thread.h"
-
-HBBuffer::HBBuffer( uint32_t size )
-{
- fAllocSize = size;
- fSize = size;
- fKeyFrame = false;
- fData = (uint8_t*) malloc( size );
- fPosition = 0;
-
- if( !fData )
- {
- Log( "HBBuffer::HBBuffer() : malloc() failed, gonna crash soon" );
- }
-}
-
-HBBuffer::~HBBuffer()
-{
- free( fData );
-}
-
-void HBBuffer::ReAlloc( uint32_t size )
-{
- fData = (uint8_t*) realloc( fData, size );
-
- if( !fData )
- {
- Log( "HBBuffer::ReAlloc() : realloc() failed, gonna crash soon" );
- }
-
- fAllocSize = size;
-}
-
-/* Constructor */
-HBFifo::HBFifo( int capacity )
-{
- fCapacity = capacity;
-
- fWhereToPush = 0;
- fWhereToPop = 0;
- fBuffers = (HBBuffer**) malloc( ( fCapacity + 1 ) * sizeof( void* ) );
- fLock = new HBLock();
-}
-
-HBFifo::~HBFifo()
-{
- Log( "HBFifo::~HBFifo: trashing %d buffer%s",
- Size(), Size() ? "s" : "" );
-
- /* Empty the fifo */
- while( fWhereToPush != fWhereToPop )
- {
- HBBuffer * buffer = fBuffers[fWhereToPop];
- fWhereToPop++;
- fWhereToPop %= ( fCapacity + 1 );
- delete buffer;
- }
-
- /* Cleaning */
- free( fBuffers );
-
- delete fLock;
-}
-
-/* Size() : returns how much the fifo is currently filled */
-int HBFifo::Size()
-{
- return ( fCapacity + 1 + fWhereToPush - fWhereToPop ) %
- ( fCapacity + 1 );
-}
-
-/* Capacity() : simply returns the fifo capacity... */
-int HBFifo::Capacity()
-{
- return fCapacity;
-}
-
-/* Push() - returns immediatly (true if successful, false otherwise ) */
-bool HBFifo::Push( HBBuffer * buffer )
-{
- fLock->Lock();
-
- if( Size() < fCapacity )
- {
- fBuffers[fWhereToPush] = buffer;
- fWhereToPush++;
- fWhereToPush %= ( fCapacity + 1 );
- fLock->Unlock();
- return true;
- }
-
- fLock->Unlock();
- return false;
-}
-
-/* Pop() - returns immediatly (a pointer to a buffer if successful,
- NULL otherwise ) */
-HBBuffer * HBFifo::Pop()
-{
- fLock->Lock();
-
- if( fWhereToPush != fWhereToPop )
- {
- HBBuffer * buffer = fBuffers[fWhereToPop];
- fWhereToPop++;
- fWhereToPop %= ( fCapacity + 1 );
- fLock->Unlock();
- return buffer;
- }
-
- fLock->Unlock();
- return NULL;
-}
diff --git a/core/Fifo.h b/core/Fifo.h
index 69200d30c..758125ebd 100644
--- a/core/Fifo.h
+++ b/core/Fifo.h
@@ -1,49 +1,81 @@
-/* $Id: Fifo.h,v 1.11 2003/09/30 14:38:15 titer Exp $
+/* $Id: Fifo.h,v 1.3 2003/11/06 13:07:52 titer Exp $
This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
+ 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 "Common.h"
+#include "Utils.h"
+#include "Thread.h"
-class HBBuffer
+struct HBBuffer
{
- public:
- HBBuffer( uint32_t size );
- ~HBBuffer();
- void ReAlloc( uint32_t size );
-
- uint32_t fAllocSize;
- uint32_t fSize;
- uint8_t * fData;
-
- float fPosition;
- uint32_t fStreamId;
- bool fKeyFrame;
- uint64_t fPTS;
- uint32_t fPass;
+ int alloc;
+ int size;
+ uint8_t * data;
+
+ float position;
+ int streamId;
+ int keyFrame;
+ uint64_t pts;
+ int pass;
+ int last;
};
-class HBFifo
+HBBuffer * HBBufferInit( int size );
+void HBBufferReAlloc( HBBuffer *, int size );
+void HBBufferClose( HBBuffer ** );
+
+struct HBFifo
{
- public:
- HBFifo( int capacity = 32 );
- ~HBFifo();
-
- int Size();
- int Capacity();
- bool Push( HBBuffer * buffer );
- HBBuffer * Pop();
-
- private:
- int fCapacity;
- int fWhereToPush;
- int fWhereToPop;
- HBBuffer ** fBuffers;
- HBLock * fLock;
+ int capacity;
+ int whereToPush;
+ int whereToPop;
+ HBBuffer ** buffers;
+ HBLock * lock;
};
+HBFifo * HBFifoInit( int capacity );
+int HBFifoSize( HBFifo * );
+static inline int HBFifoPush( HBFifo *, HBBuffer ** );
+static inline HBBuffer * HBFifoPop( HBFifo * );
+void HBFifoClose( HBFifo ** );
+
+static inline int HBFifoPush( HBFifo * f, HBBuffer ** b )
+{
+ HBLockLock( f->lock );
+
+ if( HBFifoSize( f ) < 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;
+}
+
#endif
diff --git a/core/HandBrake.c b/core/HandBrake.c
new file mode 100644
index 000000000..3f84a5757
--- /dev/null
+++ b/core/HandBrake.c
@@ -0,0 +1,767 @@
+/* $Id: HandBrake.c,v 1.15 2003/11/07 21:52: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 "HandBrakeInternal.h"
+
+#include <ffmpeg/avcodec.h>
+
+#include "Ac3Dec.h"
+#include "AviMux.h"
+#include "DVDRead.h"
+#include "FfmpegEnc.h"
+#include "Fifo.h"
+#include "Mp3Enc.h"
+#include "Mpeg2Dec.h"
+#include "Scale.h"
+#include "Scan.h"
+#include "Thread.h"
+#include "Work.h"
+#include "XvidEnc.h"
+
+/* Local prototypes */
+static void HandBrakeThread( void * );
+static void _StopRip( HBHandle * );
+static void FixPictureSettings( HBTitle * );
+static int GetCPUCount();
+
+struct HBHandle
+{
+ HBThread * thread;
+ int die;
+ int pid;
+
+ int cpuCount;
+
+ int stopScan;
+ int stopRip;
+ int ripDone;
+ int error;
+
+ HBScan * scan;
+
+ HBLock * lock;
+ HBStatus status;
+ int modeChanged;
+ HBTitle * curTitle;
+ HBAudio * curAudio;
+ HBAudio * curOptAudio;
+
+ int frames;
+ uint64_t beginDate;
+ int framesSinceFpsUpdate;
+ uint64_t lastFpsUpdate;
+ uint64_t pauseDate;
+
+ HBLock * pauseLock;
+};
+
+HBHandle * HBInit( int debug, int cpuCount )
+{
+ HBHandle * h;
+ if( !( h = malloc( sizeof( HBHandle ) ) ) )
+ {
+ HBLog( "HBInit: malloc() failed, gonna crash" );
+ return NULL;
+ }
+
+ /* See HBLog() in Utils.cpp */
+ if( debug )
+ {
+ putenv( "HB_DEBUG=1" );
+ }
+
+ /* Init libavcodec */
+ avcodec_init();
+ register_avcodec( &mpeg4_encoder );
+
+ /* 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;
+ }
+ }
+
+ /* Initializations */
+ h->stopScan = 0;
+ h->stopRip = 0;
+ h->ripDone = 0;
+ h->error = 0;
+
+ h->scan = NULL;
+
+ h->lock = HBLockInit();
+ h->modeChanged = 1;
+ h->status.mode = HB_MODE_NEED_DEVICE;
+ h->curTitle = NULL;
+ h->curAudio = NULL;
+ h->curOptAudio = NULL;
+
+ h->pauseLock = HBLockInit();
+
+ h->die = 0;
+ h->thread = HBThreadInit( "libhb", HandBrakeThread, h,
+ HB_NORMAL_PRIORITY );
+
+ return h;
+}
+
+int HBGetStatus( HBHandle * h, HBStatus * status )
+{
+ HBLockLock( h->lock );
+ memcpy( status, &h->status, sizeof( HBStatus ) );
+
+ if( !h->modeChanged )
+ {
+ HBLockUnlock( h->lock );
+ return 0;
+ }
+
+ h->modeChanged = 0;
+ HBLockUnlock( h->lock );
+ return 1;
+}
+
+void HBScanDevice( HBHandle * h, char * device, int title )
+{
+ if( !( h->status.mode & ( HB_MODE_NEED_DEVICE |
+ HB_MODE_INVALID_DEVICE ) ) )
+ {
+ HBLog( "HBScanDevice: current mode is %d, aborting",
+ h->status.mode );
+ return;
+ }
+
+ HBLockLock( h->lock );
+ h->modeChanged = 1;
+ h->status.mode = HB_MODE_SCANNING;
+ h->status.scannedTitle = 0;
+ HBLockUnlock( h->lock );
+
+ h->scan = HBScanInit( h, device, title );
+}
+
+void HBStartRip( HBHandle * h, HBTitle * t,
+ HBAudio * a1, HBAudio * a2 )
+{
+ int i;
+
+ if( !( h->status.mode & ( HB_MODE_READY_TO_RIP | HB_MODE_DONE |
+ HB_MODE_CANCELED | HB_MODE_ERROR ) ) )
+ {
+ HBLog( "HBStartRip: current mode is %d, aborting",
+ h->status.mode );
+ return;
+ }
+
+ HBLockLock( h->lock );
+ h->modeChanged = 1;
+ h->status.mode = HB_MODE_ENCODING;
+ h->status.position = 0.0;
+ h->status.pass = 1;
+ h->status.passCount = t->twoPass ? 2 : 1;
+ h->frames = 0;
+ h->framesSinceFpsUpdate = 0;
+ HBLockUnlock( h->lock );
+
+ FixPictureSettings( t );
+
+ /* Create fifos */
+ t->mpeg2Fifo = HBFifoInit( 512 );
+ t->rawFifo = HBFifoInit( 1 );
+ t->scaledFifo = HBFifoInit( 1 );
+ t->mpeg4Fifo = HBFifoInit( 1 );
+ a1->ac3Fifo = HBFifoInit( 512 );
+ a1->rawFifo = HBFifoInit( 1 );
+ a1->mp3Fifo = HBFifoInit( 1 );
+ if( a2 )
+ {
+ a2->ac3Fifo = HBFifoInit( 512 );
+ a2->rawFifo = HBFifoInit( 1 );
+ a2->mp3Fifo = HBFifoInit( 1 );
+ }
+
+ /* Create work objects */
+ t->mpeg2Dec = HBMpeg2DecInit( h, t );
+ t->scale = HBScaleInit( h, t );
+
+ if( t->codec == HB_CODEC_FFMPEG )
+ t->ffmpegEnc = HBFfmpegEncInit( h, t );
+ else if( t->codec == HB_CODEC_XVID )
+ t->xvidEnc = HBXvidEncInit( h, t );
+
+ a1->ac3Dec = HBAc3DecInit( h, a1 );
+ a1->mp3Enc = HBMp3EncInit( h, a1 );
+ if( a2 )
+ {
+ a2->ac3Dec = HBAc3DecInit( h, a2 );
+ a2->mp3Enc = HBMp3EncInit( h, a2 );
+ }
+
+ /* Create threads */
+ t->dvdRead = HBDVDReadInit( h, t, a1, a2 );
+ t->aviMux = HBAviMuxInit( h, t, a1, a2 );
+ for( i = 0; i < h->cpuCount; i++ )
+ {
+ t->workThreads[i] = HBWorkThreadInit( h, t, a1, a2, i ? 0 : 1 );
+ }
+
+ h->curTitle = t;
+ h->curAudio = a1;
+ h->curOptAudio = a2;
+}
+
+void HBPauseRip( HBHandle * h )
+{
+ if( h->status.mode != HB_MODE_ENCODING )
+ {
+ HBLog( "HBPauseRip: current mode is %d, aborting",
+ h->status.mode );
+ return;
+ }
+
+ h->pauseDate = HBGetDate();
+ HBLockLock( h->pauseLock );
+ HBLockLock( h->lock );
+ h->status.mode = HB_MODE_PAUSED;
+ h->modeChanged = 1;
+ HBLockUnlock( h->lock );
+}
+
+void HBResumeRip( HBHandle * h )
+{
+ if( h->status.mode != HB_MODE_PAUSED )
+ {
+ HBLog( "HBResumeRip: current mode is %d, aborting",
+ h->status.mode );
+ return;
+ }
+
+ h->beginDate += HBGetDate() - h->pauseDate;
+ h->lastFpsUpdate += HBGetDate() - h->pauseDate;
+ HBLockUnlock( h->pauseLock );
+ HBLockLock( h->lock );
+ h->modeChanged = 1;
+ h->status.mode = HB_MODE_ENCODING;
+ HBLockUnlock( h->lock );
+}
+
+void HBStopRip( HBHandle * h )
+{
+ if( !( h->status.mode & ( HB_MODE_ENCODING | HB_MODE_PAUSED ) ) )
+ {
+ HBLog( "HBStopRip: current mode is %d, aborting",
+ h->status.mode );
+ return;
+ }
+
+ if( h->status.mode & HB_MODE_PAUSED )
+ {
+ HBLockUnlock( h->pauseLock );
+ }
+
+ HBLockLock( h->lock );
+ h->modeChanged = 1;
+ h->status.mode = HB_MODE_STOPPING;
+ HBLockUnlock( h->lock );
+ h->stopRip = 1;
+}
+
+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->index,
+ picture );
+ file = fopen( fileName, "r" );
+ 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;
+}
+
+void HBClose( HBHandle ** _h )
+{
+ char command[1024];
+
+ HBHandle * h = *_h;
+
+ h->die = 1;
+ HBThreadClose( &h->thread );
+
+ if( h->status.mode == HB_MODE_SCANNING )
+ {
+ HBScanClose( &h->scan );
+ }
+ else if( h->status.mode == HB_MODE_PAUSED )
+ {
+ HBLockUnlock( h->pauseLock );
+ _StopRip( h );
+ }
+ else if( h->status.mode == HB_MODE_ENCODING )
+ {
+ _StopRip( h );
+ }
+
+ memset( command, 0, 1024 );
+ sprintf( command, "rm -f /tmp/HB.%d.*", h->pid );
+ system( command );
+
+ if( h->status.titleList )
+ {
+ HBTitle * title;
+ while( ( title = HBListItemAt( h->status.titleList, 0 ) ) )
+ {
+ HBListRemove( h->status.titleList, title );
+ HBTitleClose( &title );
+ }
+ HBListClose( &h->status.titleList );
+ }
+
+ 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 )
+{
+ HBLockLock( h->lock );
+ h->status.scannedTitle = title;
+ HBLockUnlock( h->lock );
+}
+
+void HBScanDone( HBHandle * h, HBList * titleList )
+{
+ h->status.titleList = titleList;
+ h->stopScan = 1;
+}
+
+int HBGetPid( HBHandle * h )
+{
+ return h->pid;
+}
+
+void HBDone( HBHandle * h )
+{
+ h->ripDone = 1;
+}
+
+void HBPosition( HBHandle * h, float position )
+{
+ if( !h->frames )
+ {
+ h->beginDate = HBGetDate();
+ h->lastFpsUpdate = h->beginDate;
+ }
+
+ h->frames++;
+ h->framesSinceFpsUpdate++;
+
+ HBLockLock( h->lock );
+ if( position - h->status.position > 0.0001 || h->frames == 2 )
+ {
+ HBLog( "Progress: %.2f %%", 100.0 * position );
+ h->status.position = position;
+
+ if( h->curTitle->twoPass )
+ h->status.pass = ( position < 0.5 ) ? 1 : 2;
+ else
+ h->status.pass = 1;
+ }
+ if( HBGetDate() - h->lastFpsUpdate > 1000000 )
+ {
+ h->status.frameRate = 1000000.0 * h->framesSinceFpsUpdate /
+ ( HBGetDate() - h->lastFpsUpdate );
+ h->status.avFrameRate = 1000000.0 * h->frames /
+ ( HBGetDate() - h->beginDate );
+ h->status.remainingTime = ( 1.0 - h->status.position ) *
+ ( HBGetDate() - h->beginDate ) /
+ h->status.position / 1000000;
+
+ HBLog( "Speed: %.2f fps (average: %.2f fps, "
+ "remaining: %02d:%02d:%02d)",
+ h->status.frameRate, h->status.avFrameRate,
+ h->status.remainingTime / 3600,
+ ( h->status.remainingTime / 60 ) % 60,
+ h->status.remainingTime % 60 );
+
+ h->lastFpsUpdate = HBGetDate();
+ h->framesSinceFpsUpdate = 0;
+ }
+ HBLockUnlock( h->lock );
+}
+
+void HBErrorOccured( HBHandle * h, HBError error )
+{
+ if( !( h->status.mode & ( HB_MODE_ENCODING | HB_MODE_PAUSED ) ) )
+ {
+ return;
+ }
+
+ h->status.error = error;
+ h->error = 1;
+}
+
+/* Local functions */
+static void HandBrakeThread( void * _h )
+{
+ HBHandle * h = (HBHandle*) _h;
+
+ h->pid = getpid();
+
+ while( !h->die )
+ {
+ if( h->stopScan )
+ {
+ HBScanClose( &h->scan );
+ HBLockLock( h->lock );
+ h->modeChanged = 1;
+ h->status.mode = HBListCountItems( h->status.titleList ) ?
+ HB_MODE_READY_TO_RIP : HB_MODE_INVALID_DEVICE;
+ HBLockUnlock( h->lock );
+ h->stopScan = 0;
+ }
+
+ if( h->stopRip )
+ {
+ _StopRip( h );
+
+ HBLockLock( h->lock );
+ h->modeChanged = 1;
+ h->status.mode = HB_MODE_CANCELED;
+ HBLockUnlock( h->lock );
+
+ h->stopRip = 0;
+ }
+
+ if( h->ripDone )
+ {
+ /* Wait a bit */
+ HBSnooze( 500000 );
+
+ _StopRip( h );
+ HBLockLock( h->lock );
+ h->modeChanged = 1;
+ h->status.mode = HB_MODE_DONE;
+ HBLockUnlock( h->lock );
+
+ h->ripDone = 0;
+ }
+
+ if( h->error )
+ {
+ _StopRip( h );
+
+ HBLockLock( h->lock );
+ h->modeChanged = 1;
+ h->status.mode = HB_MODE_ERROR;
+ HBLockUnlock( h->lock );
+
+ h->error = 0;
+ }
+
+ HBSnooze( 10000 );
+ }
+}
+
+static void _StopRip( HBHandle * h )
+{
+ int i;
+
+ /* Stop threads */
+ HBDVDReadClose( &h->curTitle->dvdRead );
+ HBAviMuxClose( &h->curTitle->aviMux );
+ for( i = 0; i < h->cpuCount; i++ )
+ {
+ HBWorkThreadClose( &h->curTitle->workThreads[h->cpuCount-i-1] );
+ }
+
+ /* Clean up */
+ HBMpeg2DecClose( &h->curTitle->mpeg2Dec );
+ HBScaleClose( &h->curTitle->scale );
+
+ if( h->curTitle->codec == HB_CODEC_FFMPEG )
+ HBFfmpegEncClose( &h->curTitle->ffmpegEnc );
+ else if( h->curTitle->codec == HB_CODEC_XVID )
+ HBXvidEncClose( &h->curTitle->xvidEnc );
+
+ HBAc3DecClose( &h->curAudio->ac3Dec );
+ HBMp3EncClose( &h->curAudio->mp3Enc );
+ if( h->curOptAudio )
+ {
+ HBAc3DecClose( &h->curOptAudio->ac3Dec );
+ HBMp3EncClose( &h->curOptAudio->mp3Enc );
+ }
+
+ /* Destroy fifos */
+ HBFifoClose( &h->curTitle->mpeg2Fifo );
+ HBFifoClose( &h->curTitle->rawFifo );
+ HBFifoClose( &h->curTitle->scaledFifo );
+ HBFifoClose( &h->curTitle->mpeg4Fifo );
+ HBFifoClose( &h->curAudio->ac3Fifo );
+ HBFifoClose( &h->curAudio->rawFifo );
+ HBFifoClose( &h->curAudio->mp3Fifo );
+ if( h->curOptAudio )
+ {
+ HBFifoClose( &h->curOptAudio->ac3Fifo );
+ HBFifoClose( &h->curOptAudio->rawFifo );
+ HBFifoClose( &h->curOptAudio->mp3Fifo );
+ }
+}
+
+static void FixPictureSettings( HBTitle * t )
+{
+ /* Sanity checks */
+ 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( SYS_BEOS )
+ system_info info;
+ get_system_info( &info );
+ CPUCount = info.cpu_count;
+
+#elif defined( SYS_MACOSX )
+ FILE * info;
+ char buffer[256];
+
+ if( ( info = popen( "/usr/sbin/sysctl hw.ncpu", "r" ) ) )
+ {
+ if( fgets( buffer, 256, info ) )
+ {
+ int count;
+ if( sscanf( buffer, "hw.ncpu: %d", &count ) == 1 )
+ {
+ CPUCount = count;
+ }
+ else
+ {
+ HBLog( "GetCPUCount: sscanf() failed" );
+ }
+ }
+ else
+ {
+ HBLog( "GetCPUCount: fgets() failed" );
+ }
+ fclose( info );
+ }
+ else
+ {
+ HBLog( "GetCPUCount: popen() failed" );
+ }
+
+#elif defined( SYS_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( SYS_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
new file mode 100644
index 000000000..35ec0fc0a
--- /dev/null
+++ b/core/HandBrake.h
@@ -0,0 +1,55 @@
+/* $Id: HandBrake.h,v 1.3 2003/11/06 13:03: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. */
+
+#ifndef HB_HANDBRAKE_H
+#define HB_HANDBRAKE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "Utils.h"
+
+/* 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 );
+
+/* Fills the HBStatus * argument with infos about the current status.
+ Returns 1 if mode has changed, 0 otherwise */
+int HBGetStatus( HBHandle *, HBStatus * );
+
+/* Launch a thread which scans the specified device and title. Use
+ title = 0 to scan all titles. Returns immediately */
+void HBScanDevice( HBHandle *, char * device, int title );
+
+/* Start ripping the specified title with specified audio tracks.
+ Returns immediatly */
+void HBStartRip( HBHandle *, HBTitle *, HBAudio *, HBAudio * );
+
+/* Suspend rip. Returns immediatly */
+void HBPauseRip( HBHandle * );
+
+/* Resume rip. Returns immediatly */
+void HBResumeRip( HBHandle * );
+
+/* Cancel rip. Returns immediatly */
+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. It includes the white border around the
+ picture, so the size of the picture is ( maxWidth + 2 ) x
+ ( maxHeight + 2 ) */
+uint8_t * HBGetPreview( HBHandle *, HBTitle *, int picture );
+
+/* Clean up things */
+void HBClose( HBHandle ** );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/core/HandBrakeInternal.h b/core/HandBrakeInternal.h
new file mode 100644
index 000000000..7c10512c9
--- /dev/null
+++ b/core/HandBrakeInternal.h
@@ -0,0 +1,35 @@
+/* $Id: HandBrakeInternal.h,v 1.2 2003/11/04 15:44: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_HANDBRAKE_INTERNAL_H
+#define HB_HANDBRAKE_INTERNAL_H
+
+#include "HandBrake.h"
+
+/* Called by HBScan to tell the GUI how far we are */
+void HBScanning( HBHandle *, int title );
+
+/* 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 if it is */
+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 ask to stop */
+void HBErrorOccured( HBHandle *, HBError );
+
+#endif
diff --git a/core/Languages.h b/core/Languages.h
index 21a5e1487..7949688c9 100644
--- a/core/Languages.h
+++ b/core/Languages.h
@@ -1,7 +1,7 @@
-/* $Id: Languages.h,v 1.2 2003/09/30 14:38:15 titer Exp $
+/* $Id: Languages.h,v 1.1 2003/11/03 12:08:01 titer Exp $
This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
+ Homepage: <http://handbrake.m0k.org/>.
It may be used under the terms of the GNU General Public License. */
#ifndef HB_LANGUAGES_H
@@ -14,7 +14,7 @@ typedef struct iso639_lang_t
char * iso639_1; /* ISO-639-1 (2 characters) code */
} iso639_lang_t;
-iso639_lang_t languages[] =
+static iso639_lang_t languages[] =
{ { "Afar", "", "aa" },
{ "Abkhazian", "", "ab" },
{ "Afrikaans", "", "af" },
diff --git a/core/MadDec.c b/core/MadDec.c
new file mode 100644
index 000000000..deecfeebd
--- /dev/null
+++ b/core/MadDec.c
@@ -0,0 +1,9 @@
+/* $Id: MadDec.c,v 1.1 2003/11/03 12:08: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 "MadDec.h"
+#include "Fifo.h"
+
diff --git a/core/MadDec.h b/core/MadDec.h
new file mode 100644
index 000000000..b1624338f
--- /dev/null
+++ b/core/MadDec.h
@@ -0,0 +1,15 @@
+/* $Id: MadDec.h,v 1.1 2003/11/03 12:08: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. */
+
+#ifndef HB_MAD_DEC_H
+#define HB_MAD_DEC_H
+
+#include "HandBrakeInternal.h"
+
+HBMadDec * HBMadDecInit( HBHandle *, HBAudio * );
+void HBMadDecClose( HBMadDec * );
+
+#endif
diff --git a/core/Manager.cpp b/core/Manager.cpp
deleted file mode 100644
index 908aa08fd..000000000
--- a/core/Manager.cpp
+++ /dev/null
@@ -1,652 +0,0 @@
-/* $Id: Manager.cpp,v 1.70 2003/10/16 13:36:17 titer Exp $
-
- This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
- It may be used under the terms of the GNU General Public License. */
-
-#include "Ac3Decoder.h"
-#include "AviMuxer.h"
-#include "DVDReader.h"
-#include "Fifo.h"
-#include "Manager.h"
-#include "Mp3Encoder.h"
-#include "Mpeg2Decoder.h"
-#include "Mpeg4Encoder.h"
-#include "MpegDemux.h"
-#include "Resizer.h"
-#include "Scanner.h"
-#include "Worker.h"
-
-#include <ffmpeg/avcodec.h>
-
-/* Public methods */
-
-HBManager::HBManager( bool debug, int cpuCount )
- : HBThread( "manager", HB_NORMAL_PRIORITY )
-{
- /* See Log() in Common.cpp */
- if( debug )
- {
- putenv( "HB_DEBUG=1" );
- }
-
- /* Check CPU count */
- if( !cpuCount )
- {
- fCPUCount = GetCPUCount();
- Log( "HBManager::HBManager: %d CPU%s detected", fCPUCount,
- ( fCPUCount > 1 ) ? "s" : "" );
- }
- else
- {
- fCPUCount = cpuCount;
- if( fCPUCount < 1 )
- {
- Log( "HBManager::HBManager: invalid CPU count (%d), "
- "using 1", fCPUCount );
- fCPUCount = 1;
- }
- else if( fCPUCount > 8 )
- {
- Log( "HBManager::HBManager: invalid CPU count (%d), "
- "using 8", fCPUCount );
- fCPUCount = 8;
- }
- Log( "HBManager::HBManager: user specified %d CPU%s",
- fCPUCount, ( fCPUCount > 1 ) ? "s" : "" );
- }
-
- /* Init ffmpeg's libavcodec */
- avcodec_init();
-// register_avcodec( &mpeg4_encoder );
- avcodec_register_all();
-
- /* Initialization */
- fStopScan = false;
- fStopRip = false;
- fRipDone = false;
- fError = false;
-
- fScanner = NULL;
-
- fStatusLock = new HBLock();
- fStatus.fMode = HB_MODE_NEED_VOLUME;
- fNeedUpdate = true;
-
- fCurTitle = NULL;
- fCurAudio1 = NULL;
- fCurAudio2 = NULL;
-
- Run();
-}
-
-HBManager::~HBManager()
-{
- /* Stop ripping if needed */
- fStatusLock->Lock();
- if( fStatus.fMode == HB_MODE_ENCODING )
- {
- fStatusLock->Unlock();
-
- StopRip();
- while( fStopRip )
- {
- Snooze( 10000 );
- }
- }
- else
- {
- fStatusLock->Unlock();
- }
-
- /* Stop scanning if needed */
- if( fScanner )
- {
- delete fScanner;
- }
-
- /* Remove temp files */
- char command[1024]; memset( command, 0, 1024 );
- sprintf( command, "rm -f /tmp/HB.%d.*", GetPid() );
- system( command );
-
- delete fStatusLock;
-}
-
-void HBManager::DoWork()
-{
- while( !fDie )
- {
- if( fStopScan )
- {
- /* Destroy the thread */
- delete fScanner;
- fScanner = NULL;
-
- /* Update interface */
- fStatusLock->Lock();
- if( fStatus.fTitleList && fStatus.fTitleList->CountItems() )
- {
- fStatus.fMode = HB_MODE_READY_TO_RIP;
- }
- else
- {
- fStatus.fMode = HB_MODE_INVALID_VOLUME;
- }
- fNeedUpdate = true;
- fStatusLock->Unlock();
-
- fStopScan = false;
- }
-
- if( fStopRip || fError || fRipDone )
- {
- if( fRipDone )
- {
- /* Wait a bit */
- while( fCurTitle->fPSFifo->Size() )
- {
- Snooze( 10000 );
- }
- while( fCurTitle->fMpeg2Fifo->Size() &&
- ( !fCurAudio1 || fCurAudio1->fAc3Fifo->Size() ) &&
- ( !fCurAudio2 || fCurAudio2->fAc3Fifo->Size() ) )
- {
- Snooze( 10000 );
- }
- Snooze( 500000 );
- }
- else
- {
- fStatusLock->Lock();
- fStatus.fMode = HB_MODE_STOPPING;
- fNeedUpdate = true;
- fStatusLock->Unlock();
- }
-
- /* Stop threads */
- delete fCurTitle->fDVDReader;
- delete fCurTitle->fAviMuxer;
- for( int i = 0; i < fCPUCount; i++ )
- {
- delete fCurTitle->fWorkers[i];
- }
-
- /* Clean up */
- delete fCurTitle->fMpegDemux;
- delete fCurTitle->fMpeg2Decoder;
- delete fCurTitle->fResizer;
- delete fCurTitle->fMpeg4Encoder;
-
- if( fCurAudio1 )
- {
- delete fCurAudio1->fAc3Decoder;
- delete fCurAudio1->fMp3Encoder;
- }
-
- if( fCurAudio2 )
- {
- delete fCurAudio2->fAc3Decoder;
- delete fCurAudio2->fMp3Encoder;
- }
-
- /* Destroy fifos */
- delete fCurTitle->fPSFifo;
- delete fCurTitle->fMpeg2Fifo;
- delete fCurTitle->fRawFifo;
- delete fCurTitle->fResizedFifo;
- delete fCurTitle->fMpeg4Fifo;
-
- if( fCurAudio1 )
- {
- delete fCurAudio1->fAc3Fifo;
- delete fCurAudio1->fRawFifo;
- delete fCurAudio1->fMp3Fifo;
- }
-
- if( fCurAudio2 )
- {
- delete fCurAudio2->fAc3Fifo;
- delete fCurAudio2->fRawFifo;
- delete fCurAudio2->fMp3Fifo;
- }
-
- /* Update interface */
- fStatusLock->Lock();
- fStatus.fMode = fStopRip ? HB_MODE_CANCELED :
- ( fError ? HB_MODE_ERROR : HB_MODE_DONE );
- fNeedUpdate = true;
- fStatusLock->Unlock();
-
- fStopRip = false;
- fError = false;
- fRipDone = false;
- }
-
- Snooze( 10000 );
- }
-}
-
-bool HBManager::NeedUpdate()
-{
- fStatusLock->Lock();
- if( fNeedUpdate )
- {
- fNeedUpdate = false;
- fStatusLock->Unlock();
- return true;
- }
- fStatusLock->Unlock();
-
- return false;
-}
-
-HBStatus HBManager::GetStatus()
-{
- fStatusLock->Lock();
- HBStatus status = fStatus;
- fStatusLock->Unlock();
-
- return status;
-}
-
-void HBManager::ScanVolumes( char * device )
-{
- if( !( fStatus.fMode &
- ( HB_MODE_NEED_VOLUME | HB_MODE_INVALID_VOLUME ) ) )
- {
- Log( "HBManager::ScanVolumes : current mode is %d, aborting",
- fStatus.fMode );
- return;
- }
-
- fScanner = new HBScanner( this, device );
-
- fStatusLock->Lock();
- fStatus.fMode = HB_MODE_SCANNING;
- fStatus.fScannedVolume = strdup( device );
- fStatus.fScannedTitle = 0;
- fNeedUpdate = true;
- fStatusLock->Unlock();
-}
-
-void HBManager::StartRip( HBTitle * title, HBAudio * audio1,
- HBAudio * audio2, char * file )
-{
- if( !title || !file )
- {
- Log( "HBManager::StartRip : error (title = %p, file = %s)",
- title, file );
- return;
- }
-
- if( !( fStatus.fMode & ( HB_MODE_READY_TO_RIP | HB_MODE_DONE |
- HB_MODE_CANCELED | HB_MODE_ERROR ) ) )
- {
- Log( "HBManager::StartRip : current mode is %d, aborting",
- fStatus.fMode );
- return;
- }
-
- FixPictureSettings( title );
-
- Log( "HBManager::StartRip:" );
- Log( "- device: %s, title: %d", title->fDevice, title->fIndex );
- Log( "- video: %dx%d->%dx%d, bitrate=%d, 2-pass=%s, deinterlace=%s",
- title->fInWidth, title->fInHeight,
- title->fOutWidth, title->fOutHeight,
- title->fBitrate, title->fTwoPass ? "yes" : "no",
- title->fDeinterlace ? "yes" : "no" );
- Log( "- cropping: top=%d, bottom=%d, left=%d, right=%d",
- title->fTopCrop, title->fBottomCrop,
- title->fLeftCrop, title->fRightCrop );
- if( audio1 )
- {
- Log( "- audio 1: lang = %s (%x), bitrate = %d",
- audio1->fDescription, audio1->fId, audio1->fOutBitrate );
- }
- if( audio2 )
- {
- Log( "- audio 2: lang = %s (%x), bitrate = %d",
- audio2->fDescription, audio2->fId, audio2->fOutBitrate );
- }
-
- /* Create fifos */
- title->fPSFifo = new HBFifo( 256 );
- title->fMpeg2Fifo = new HBFifo( 256 );
- title->fRawFifo = new HBFifo( 4 );
- title->fResizedFifo = new HBFifo( 4 );
- title->fMpeg4Fifo = new HBFifo( 4 );
- if( audio1 )
- {
- audio1->fAc3Fifo = new HBFifo( 256 );
- audio1->fRawFifo = new HBFifo( 4 );
- audio1->fMp3Fifo = new HBFifo( 4 );
- }
- if( audio2 )
- {
- audio2->fAc3Fifo = new HBFifo( 256 );
- audio2->fRawFifo = new HBFifo( 4 );
- audio2->fMp3Fifo = new HBFifo( 4 );
- }
-
- /* Create decoders & encoders objects */
- title->fMpegDemux = new HBMpegDemux( this, title, audio1,
- audio2 );
- title->fMpeg2Decoder = new HBMpeg2Decoder( this, title );
- title->fResizer = new HBResizer( this, title );
- title->fMpeg4Encoder = new HBMpeg4Encoder( this, title );
- if( audio1 )
- {
- audio1->fAc3Decoder = new HBAc3Decoder( this, audio1 );
- audio1->fMp3Encoder = new HBMp3Encoder( this, audio1 );
- }
- if( audio2 )
- {
- audio2->fAc3Decoder = new HBAc3Decoder( this, audio2 );
- audio2->fMp3Encoder = new HBMp3Encoder( this, audio2 );
- }
-
- /* Create and launch the threads */
- title->fDVDReader = new HBDVDReader( this, title );
- title->fAviMuxer = new HBAviMuxer( this, title, audio1, audio2,
- file );
- for( int i = 0; i < fCPUCount; i++ )
- {
- title->fWorkers[i] = new HBWorker( title, audio1, audio2 );
- }
-
- fCurTitle = title;
- fCurAudio1 = audio1;
- fCurAudio2 = audio2;
-
- fStatusLock->Lock();
- fStatus.fMode = HB_MODE_ENCODING;
- fStatus.fPosition = 0;
- fStatus.fFrameRate = 0;
- fStatus.fFrames = 0;
- fStatus.fStartDate = 0;
- fStatus.fRemainingTime = 0;
- fStatus.fSuspendDate = 0;
- fNeedUpdate = true;
- fStatusLock->Unlock();
-}
-
-void HBManager::SuspendRip()
-{
- if( fStatus.fMode != HB_MODE_ENCODING )
- {
- Log( "HBManager::SuspendRip : current mode is %d, aborting",
- fStatus.fMode );
- return;
- }
-
- fCurTitle->fDVDReader->Suspend();
- fCurTitle->fAviMuxer->Suspend();
- for( int i = 0; i < fCPUCount; i++ )
- {
- fCurTitle->fWorkers[i]->Suspend();
- }
-
- fStatusLock->Lock();
- fStatus.fMode = HB_MODE_SUSPENDED;
- fStatus.fSuspendDate = GetDate();
- fNeedUpdate = true;
- fStatusLock->Unlock();
-}
-
-void HBManager::ResumeRip()
-{
- if( fStatus.fMode != HB_MODE_SUSPENDED )
- {
- Log( "HBManager::ResumeRip : current mode is %d, aborting",
- fStatus.fMode );
- return;
- }
-
- fCurTitle->fDVDReader->Resume();
- fCurTitle->fAviMuxer->Resume();
- for( int i = 0; i < fCPUCount; i++ )
- {
- fCurTitle->fWorkers[i]->Resume();
- }
-
- fStatusLock->Lock();
- fStatus.fMode = HB_MODE_ENCODING;
- fStatus.fStartDate += GetDate() - fStatus.fSuspendDate;
- fNeedUpdate = true;
- fStatusLock->Unlock();
-}
-
-void HBManager::StopRip()
-{
- if( !( fStatus.fMode & ( HB_MODE_ENCODING | HB_MODE_SUSPENDED ) ) )
- {
- Log( "HBManager::StopRip : current mode is %d, aborting",
- fStatus.fMode );
- return;
- }
-
- /* Stop the threads */
- fStopRip = true;
-}
-
-#define fInWidth title->fInWidth
-#define fInHeight title->fInHeight
-#define fAspect title->fAspect
-#define fDeinterlace title->fDeinterlace
-#define fOutWidth title->fOutWidth
-#define fOutHeight title->fOutHeight
-#define fOutWidthMax title->fOutWidthMax
-#define fOutHeightMax title->fOutHeightMax
-#define fTopCrop title->fTopCrop
-#define fBottomCrop title->fBottomCrop
-#define fLeftCrop title->fLeftCrop
-#define fRightCrop title->fRightCrop
-
-void HBManager::FixPictureSettings( HBTitle * title )
-{
- /* Sanity checks */
- fTopCrop = EVEN( fTopCrop );
- fBottomCrop = EVEN( fBottomCrop );
- fLeftCrop = EVEN( fLeftCrop );
- fRightCrop = EVEN( fRightCrop );
-
- fOutWidth = MIN( fOutWidth, fOutWidthMax );
- fOutWidth = MAX( 16, fOutWidth );
-
- fOutHeight = MULTIPLE_16( (uint64_t) fOutWidth * fInWidth *
- ( fInHeight - fTopCrop - fBottomCrop ) *
- VOUT_ASPECT_FACTOR /
- ( (uint64_t) fInHeight *
- ( fInWidth - fLeftCrop - fRightCrop ) *
- fAspect ) );
- fOutHeight = MAX( 16, fOutHeight );
-
- if( fOutHeight > fOutHeightMax )
- {
- fOutHeight = fOutHeightMax;
- fOutWidth = MULTIPLE_16( (uint64_t) fOutHeight * fInHeight *
- ( fInWidth - fLeftCrop - fRightCrop ) *
- fAspect /
- ( (uint64_t) fInWidth *
- ( fInHeight - fTopCrop - fBottomCrop ) *
- VOUT_ASPECT_FACTOR ) );
- fOutWidth = MIN( fOutWidth, fOutWidthMax );
- fOutWidth = MAX( 16, fOutWidth );
- }
-}
-
-uint8_t * HBManager::GetPreview( HBTitle * title, uint32_t image )
-{
- FixPictureSettings( title );
-
- AVPicture pic1, pic2, pic3, pic4;
- uint8_t * buf1, * buf2, * buf3, * buf4;
-
- /* Original YUV picture */
- buf1 = (uint8_t*) malloc( 3 * fInWidth * fInHeight / 2 );
- avpicture_fill( &pic1, buf1, PIX_FMT_YUV420P, fInWidth,
- fInHeight );
-
- /* Deinterlaced YUV picture */
- buf2 = (uint8_t*) malloc( 3 * fInWidth * fInHeight / 2 );
- avpicture_fill( &pic2, buf2, PIX_FMT_YUV420P,
- fInWidth, fInHeight );
-
- /* Resized YUV picture */
- buf3 = (uint8_t*) malloc( 3 * fOutWidth * fOutHeight / 2 );
- avpicture_fill( &pic3, buf3, PIX_FMT_YUV420P, fOutWidth,
- fOutHeight );
-
- /* Resized RGB picture ) */
- buf4 = (uint8_t*) malloc( 4 * fOutWidth * fOutHeight );
- avpicture_fill( &pic4, buf4, PIX_FMT_RGBA32, fOutWidth,
- fOutHeight );
-
- /* Get the original image from the temp file */
- char fileName[1024]; memset( fileName, 0, 1024 );
- sprintf( fileName, "/tmp/HB.%d.%x.%d", GetPid(), (uint32_t) title,
- image);
- FILE * file = fopen( fileName, "r" );
- fread( buf1, 3 * fInWidth * fInHeight / 2, 1, file );
- fclose( file );
-
- /* Deinterlace if needed, and resize */
- ImgReSampleContext * resampleContext =
- img_resample_full_init( fOutWidth, fOutHeight,
- fInWidth, fInHeight,
- fTopCrop, fBottomCrop,
- fLeftCrop, fRightCrop );
- if( fDeinterlace )
- {
- avpicture_deinterlace( &pic2, &pic1, PIX_FMT_YUV420P,
- fInWidth, fInHeight );
- img_resample( resampleContext, &pic3, &pic2 );
- }
- else
- {
- img_resample( resampleContext, &pic3, &pic1 );
- }
-
- /* Convert to RGB */
- img_convert( &pic4, PIX_FMT_RGBA32, &pic3, PIX_FMT_YUV420P,
- fOutWidth, fOutHeight );
-
- /* Create the final preview */
- uint8_t * preview = (uint8_t*) malloc( 4 * ( fOutWidthMax + 2 ) *
- ( fOutHeightMax + 2 ) );
-
- /* Blank it */
- memset( preview, 0,
- 4 * ( fOutWidthMax + 2 ) * ( fOutHeightMax + 2 ) );
-
- /* Draw the picture (centered) and draw the cropping zone */
- uint32_t leftOffset = 1 + ( fOutWidthMax - fOutWidth ) / 2;
- uint32_t topOffset = 1 + ( fOutHeightMax - fOutHeight ) / 2;
-
- memset( preview + 4 * ( ( fOutWidthMax + 2 ) * ( topOffset - 1 ) +
- leftOffset - 1 ),
- 0xFF, 4 * ( fOutWidth + 2 ) );
-
- for( uint32_t i = 0; i < fOutHeight; i++ )
- {
- memset( preview + 4 * ( ( fOutWidthMax + 2 ) *
- ( i + topOffset ) + leftOffset - 1 ),
- 0xFF, 4 );
- memcpy( preview + 4 * ( ( fOutWidthMax + 2 ) *
- ( i + topOffset ) + leftOffset ),
- buf4 + 4 * fOutWidth * i,
- 4 * fOutWidth );
- memset( preview + 4 * ( ( fOutWidthMax + 2 ) *
- ( i + topOffset ) + leftOffset +
- fOutWidth ),
- 0xFF, 4 );
- }
-
- memset( preview + 4 * ( ( fOutWidthMax + 2 ) *
- ( topOffset + fOutHeight ) +
- leftOffset - 1 ),
- 0xFF, 4 * ( fOutWidth + 2 ) );
-
- /* Free memory */
- free( buf1 );
- free( buf2 );
- free( buf3 );
- free( buf4 );
-
- return preview;
-}
-
-#undef fInWidth
-#undef fInHeight
-#undef fAspect
-#undef fDeinterlace
-#undef fOutWidth
-#undef fOutHeight
-#undef fOutWidthMax
-#undef fOutHeightMax
-#undef fTopCrop
-#undef fBottomCrop
-#undef fLeftCrop
-#undef fRightCrop
-
-void HBManager::Scanning( char * volume, int title )
-{
- fStatusLock->Lock();
- fStatus.fMode = HB_MODE_SCANNING;
- fStatus.fScannedVolume = volume;
- fStatus.fScannedTitle = title;
- fNeedUpdate = true;
- fStatusLock->Unlock();
-}
-
-void HBManager::ScanDone( HBList * titleList )
-{
- fStatus.fTitleList = titleList;;
- fStopScan = true;
-}
-
-/* Called by the DVD reader */
-void HBManager::Done()
-{
- fRipDone = true;
-}
-
-void HBManager::Error( HBError error )
-{
- if( fStatus.fMode != HB_MODE_ENCODING )
- {
- return;
- }
-
- fStatus.fError = error;
- fError = true;
-}
-
-void HBManager::SetPosition( float pos )
-{
- if( !fStatus.fStartDate )
- {
- fStatus.fStartDate = GetDate();
- }
-
- fStatus.fFrames++;
-
- if( ( pos - fStatus.fPosition ) * 10000 < 1 )
- {
- return;
- }
-
- fStatusLock->Lock();
- fStatus.fPosition = pos;
- fStatus.fFrameRate = (float) fStatus.fFrames /
- ( ( (float) ( GetDate() - fStatus.fStartDate ) ) / 1000000 ) ;
- fStatus.fRemainingTime =
- (uint32_t) ( (float) ( GetDate() - fStatus.fStartDate ) *
- ( 1 - fStatus.fPosition ) /
- ( 1000000 * fStatus.fPosition ) );
- fNeedUpdate = true;
- fStatusLock->Unlock();
-}
-
diff --git a/core/Manager.h b/core/Manager.h
deleted file mode 100644
index dc885e5f5..000000000
--- a/core/Manager.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* $Id: Manager.h,v 1.32 2003/10/08 22:20:36 titer Exp $
-
- This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
- It may be used under the terms of the GNU General Public License. */
-
-#ifndef HB_MANAGER_H
-#define HB_MANAGER_H
-
-#include "Common.h"
-#include "Thread.h"
-
-class HBManager : public HBThread
-{
- public:
- HBManager( bool debug = false,
- int cpuCount = 0 );
- ~HBManager();
- void DoWork();
-
- /* Methods called by the interface */
- bool NeedUpdate();
- HBStatus GetStatus();
- void ScanVolumes( char * device );
- void StartRip( HBTitle * title, HBAudio * audio1,
- HBAudio * audio2, char * file );
- void SuspendRip();
- void ResumeRip();
- void StopRip();
- uint8_t * GetPreview( HBTitle * title, uint32_t image );
-
- /* Methods called by the working threads */
- void Scanning( char * volume, int title );
- void ScanDone( HBList * titleList );
- void Done();
- void Error( HBError error );
- void SetPosition( float pos );
-
- private:
- void FixPictureSettings( HBTitle * title );
-
- int fPid;
- int fCPUCount;
-
- /* Booleans used in DoWork() */
- bool fStopScan;
- volatile bool fStopRip;
- bool fRipDone;
- bool fError;
-
- /* Scanner thread */
- HBScanner * fScanner;
-
- /* Status infos */
- HBLock * fStatusLock;
- bool fNeedUpdate;
- HBStatus fStatus;
-
- HBTitle * fCurTitle;
- HBAudio * fCurAudio1;
- HBAudio * fCurAudio2;
-};
-
-#endif
diff --git a/core/Mp3Enc.c b/core/Mp3Enc.c
new file mode 100644
index 000000000..70693467f
--- /dev/null
+++ b/core/Mp3Enc.c
@@ -0,0 +1,281 @@
+/* $Id: Mp3Enc.c,v 1.5 2003/11/07 21:52: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 "Fifo.h"
+#include "Mp3Enc.h"
+#include "Work.h"
+
+#include <lame/lame.h>
+
+/* Local prototypes */
+static int Mp3EncWork( HBWork * );
+static int GetBytes( HBMp3Enc * );
+
+struct HBMp3Enc
+{
+ HB_WORK_COMMON_MEMBERS
+
+ HBHandle * handle;
+ HBAudio * audio;
+ lame_global_flags * globalFlags;
+ HBBuffer * rawBuffer;
+ int rawBufferPos;
+ float position;
+ int samplesNeeded;
+ int samplesGot;
+ float * left;
+ float * right;
+ HBBuffer * mp3Buffer;
+};
+
+HBMp3Enc * HBMp3EncInit( HBHandle * handle, HBAudio * audio )
+{
+ HBMp3Enc * m;
+ if( !( m = malloc( sizeof( HBMp3Enc ) ) ) )
+ {
+ HBLog( "HBMp3EncInit: malloc() failed, gonna crash" );
+ return NULL;
+ }
+
+ m->name = strdup( "Mp3Enc" );
+ m->work = Mp3EncWork;
+
+ m->handle = handle;
+ m->audio = audio;
+ m->globalFlags = NULL;
+ m->rawBuffer = NULL;
+ m->rawBufferPos = 0;
+ m->position = 0.0;
+ m->samplesNeeded = 0;
+ m->samplesGot = 0;
+ m->left = NULL;
+ m->right = NULL;
+ m->mp3Buffer = NULL;
+
+ return m;
+}
+
+void HBMp3EncClose( HBMp3Enc ** _m )
+{
+ HBMp3Enc * m = *_m;
+
+ if( m->globalFlags ) lame_close( m->globalFlags );
+ if( m->rawBuffer ) HBBufferClose( &m->rawBuffer );
+ if( m->left ) free( m->left );
+ if( m->right ) free( m->right );
+ if( m->mp3Buffer ) HBBufferClose( &m->mp3Buffer );
+ free( m->name );
+ free( m );
+
+ *_m = NULL;
+}
+
+static int Mp3EncWork( HBWork * w )
+{
+ HBMp3Enc * m = (HBMp3Enc*) w;
+ HBAudio * audio = m->audio;
+
+ HBBuffer * mp3Buffer;
+ int ret;
+
+ int didSomething = 0;
+
+ if( !m->globalFlags )
+ {
+ int i;
+
+ /* Get a first buffer so we know that audio->inSampleRate is
+ correct */
+ if( ( m->rawBuffer = HBFifoPop( audio->rawFifo ) ) )
+ {
+ didSomething = 1;
+ }
+ else
+ {
+ return didSomething;
+ }
+ m->rawBufferPos = 0;
+ m->position = m->rawBuffer->position;
+
+ /* The idea is to have exactly one mp3 frame (i.e. 1152 samples) by
+ output buffer. As we are resampling from inSampleRate to
+ outSampleRate, we will give ( 1152 * inSampleRate ) /
+ ( 2 * outSampleRate ) samples to libmp3lame so we are sure we
+ will never get more than 1 frame at a time */
+ m->samplesNeeded = 1152 * audio->inSampleRate /
+ audio->outSampleRate / 2;
+
+ HBLog( "HBMp3Enc: opening lame (%d->%d Hz, %d kbps)",
+ audio->inSampleRate, audio->outSampleRate,
+ audio->outBitrate );
+ m->globalFlags = lame_init();
+ lame_set_in_samplerate( m->globalFlags, audio->inSampleRate );
+ lame_set_out_samplerate( m->globalFlags, audio->outSampleRate );
+ lame_set_brate( m->globalFlags, audio->outBitrate );
+
+ if( lame_init_params( m->globalFlags ) == -1 )
+ {
+ HBLog( "HBMp3Enc: lame_init_params() failed" );
+ HBErrorOccured( m->handle, HB_ERROR_MP3_INIT );
+ return didSomething;
+ }
+
+ m->left = malloc( m->samplesNeeded * sizeof( float ) );
+ m->right = malloc( m->samplesNeeded * sizeof( float ) );
+
+ if( !m->left || !m->right )
+ {
+ HBLog( "HBMp3Enc: malloc() failed, gonna crash" );
+ }
+
+ for( i = 0; i < m->samplesNeeded; i++ )
+ {
+ m->left[i] = 0.0;
+ m->right[i] = 0.0;
+ }
+ }
+
+ /* Push encoded buffer */
+ if( m->mp3Buffer )
+ {
+ if( HBFifoPush( audio->mp3Fifo, &m->mp3Buffer ) )
+ {
+ didSomething = 1;
+ }
+ else
+ {
+ return didSomething;
+ }
+ }
+
+ /* A/V synchro fix in case audio doesn't start at the same time
+ than video */
+ if( audio->delay > 0 )
+ {
+ /* Audio starts later - insert some silence */
+ int length = m->samplesNeeded * 1000 / audio->inSampleRate;
+
+ if( audio->delay > length )
+ {
+ HBLog( "HBMp3Enc: adding %d ms of silence", length );
+ m->samplesGot = m->samplesNeeded;
+ audio->delay -= length;
+ }
+ else
+ {
+ audio->delay = 0;
+ }
+ }
+ else if( audio->delay < 0 )
+ {
+ /* Audio starts sooner - trash some */
+ int length = m->samplesNeeded * 1000 / audio->inSampleRate;
+
+ if( - audio->delay > length )
+ {
+ if( GetBytes( m ) )
+ {
+ didSomething = 1;
+ HBLog( "HBMp3Enc: trashing %d ms", length );
+ m->samplesGot = 0;
+ audio->delay += length;
+ return didSomething;
+ }
+ else
+ {
+ return didSomething;
+ }
+ }
+ else
+ {
+ audio->delay = 0;
+ }
+ }
+
+ /* Get new samples */
+ if( GetBytes( m ) )
+ {
+ didSomething = 1;
+ }
+ else
+ {
+ return didSomething;
+ }
+
+ m->samplesGot = 0;
+
+ mp3Buffer = HBBufferInit( LAME_MAXMP3BUFFER );
+ ret = lame_encode_buffer_float( m->globalFlags, m->left,
+ m->right, m->samplesNeeded,
+ mp3Buffer->data,
+ mp3Buffer->size );
+
+ if( ret < 0 )
+ {
+ /* Error */
+ HBLog( "HBMp3Enc: lame_encode_buffer_float() failed (%d)",
+ ret );
+ HBErrorOccured( m->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 = m->position;
+
+ m->mp3Buffer = mp3Buffer;
+ }
+
+ return didSomething;
+}
+
+static int GetBytes( HBMp3Enc * m )
+{
+ while( m->samplesGot < m->samplesNeeded )
+ {
+ int i;
+
+ if( !m->rawBuffer )
+ {
+ if( !( m->rawBuffer = HBFifoPop( m->audio->rawFifo ) ) )
+ {
+ return 0;
+ }
+
+ m->rawBufferPos = 0;
+ m->position = m->rawBuffer->position;
+ }
+
+ i = MIN( m->samplesNeeded - m->samplesGot,
+ ( m->rawBuffer->size / 2 -
+ m->rawBufferPos ) / sizeof( float ) );
+
+ memcpy( m->left + m->samplesGot,
+ m->rawBuffer->data + m->rawBufferPos,
+ i * sizeof( float ) );
+ memcpy( m->right + m->samplesGot,
+ m->rawBuffer->data + m->rawBuffer->size / 2 +
+ m->rawBufferPos,
+ i * sizeof( float ) );
+
+ m->samplesGot += i;
+ m->rawBufferPos += i * sizeof( float );
+
+ if( m->rawBufferPos == m->rawBuffer->size / 2 )
+ {
+ HBBufferClose( &m->rawBuffer );
+ }
+ }
+
+ return 1;
+}
diff --git a/core/Mp3Enc.h b/core/Mp3Enc.h
new file mode 100644
index 000000000..db02f4f44
--- /dev/null
+++ b/core/Mp3Enc.h
@@ -0,0 +1,15 @@
+/* $Id: Mp3Enc.h,v 1.1 2003/11/03 12:08: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. */
+
+#ifndef HB_MP3_ENCODER_H
+#define HB_MP3_ENCODER_H
+
+#include "HandBrakeInternal.h"
+
+HBMp3Enc * HBMp3EncInit( HBHandle *, HBAudio * );
+void HBMp3EncClose( HBMp3Enc ** );
+
+#endif
diff --git a/core/Mp3Encoder.cpp b/core/Mp3Encoder.cpp
deleted file mode 100644
index 96ae8c568..000000000
--- a/core/Mp3Encoder.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-/* $Id: Mp3Encoder.cpp,v 1.14 2003/10/14 14:35:20 titer Exp $
-
- This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
- It may be used under the terms of the GNU General Public License. */
-
-#include "Mp3Encoder.h"
-#include "Manager.h"
-#include "Fifo.h"
-
-#include <lame/lame.h>
-
-HBMp3Encoder::HBMp3Encoder( HBManager * manager, HBAudio * audio )
-{
- fManager = manager;
- fAudio = audio;
-
- fLock = new HBLock();
- fUsed = false;
-
- fRawBuffer = NULL;
- fPosInBuffer = 0;
- fSamplesNb = 0;
- fLeftSamples = NULL;
- fRightSamples = NULL;
-
- fPosition = 0;
- fInitDone = false;
- fMp3Buffer = NULL;
-}
-
-bool HBMp3Encoder::Work()
-{
- if( !Lock() )
- {
- return false;
- }
-
- if( !fInitDone )
- {
- /* Wait for a first buffer so we know fAudio->fInSampleRate
- is correct */
- if( !fAudio->fRawFifo->Size() )
- {
- Unlock();
- return false;
- }
-
- /* The idea is to have exactly one mp3 frame (i.e. 1152 samples) by
- output buffer. As we are resampling from fInSampleRate to
- fOutSampleRate, we will give ( 1152 * fInSampleRate ) /
- ( 2 * fOutSampleRate ) to libmp3lame so we are sure we will
- never get more than 1 frame at a time */
- fCount = ( 1152 * fAudio->fInSampleRate ) /
- ( 2 * fAudio->fOutSampleRate );
-
- /* Init libmp3lame */
- fGlobalFlags = lame_init();
- lame_set_in_samplerate( fGlobalFlags, fAudio->fInSampleRate );
- lame_set_out_samplerate( fGlobalFlags, fAudio->fOutSampleRate );
- lame_set_brate( fGlobalFlags, fAudio->fOutBitrate );
-
- if( lame_init_params( fGlobalFlags ) == -1 )
- {
- Log( "HBMp3Encoder: lame_init_params() failed" );
- fManager->Error( HB_ERROR_MP3_INIT );
- return false;
- }
-
- fLeftSamples = (float*) malloc( fCount * sizeof( float ) );
- fRightSamples = (float*) malloc( fCount * sizeof( float ) );
-
- fInitDone = true;
- }
-
- if( fMp3Buffer )
- {
- if( fAudio->fMp3Fifo->Push( fMp3Buffer ) )
- {
- fMp3Buffer = NULL;
- }
- else
- {
- Unlock();
- return false;
- }
- }
-
- /* Get new samples */
- if( GetSamples() )
- {
- fSamplesNb = 0;
-
- fMp3Buffer = new HBBuffer( LAME_MAXMP3BUFFER );
- int ret = lame_encode_buffer_float( fGlobalFlags, fLeftSamples,
- fRightSamples, fCount,
- fMp3Buffer->fData,
- fMp3Buffer->fSize );
-
- if( ret < 0 )
- {
- Log( "HBMp3Encoder: lame_encode_buffer_float() failed "
- "(%d)", ret );
- fManager->Error( HB_ERROR_MP3_ENCODE );
- return false;
- }
- else if( ret > 0 )
- {
- /* We got something, send it to the muxer */
- fMp3Buffer->fSize = ret;
- fMp3Buffer->fKeyFrame = true;
- fMp3Buffer->fPosition = fPosition;
- }
- else
- {
- delete fMp3Buffer;
- fMp3Buffer = NULL;
- }
- }
- else
- {
- Unlock();
- return false;
- }
-
- Unlock();
- return true;
-}
-
-bool HBMp3Encoder::Lock()
-{
- fLock->Lock();
- if( fUsed )
- {
- fLock->Unlock();
- return false;
- }
- fUsed = true;
- fLock->Unlock();
- return true;
-}
-
-void HBMp3Encoder::Unlock()
-{
- fLock->Lock();
- fUsed = false;
- fLock->Unlock();
-}
-
-bool HBMp3Encoder::GetSamples()
-{
- while( fSamplesNb < fCount )
- {
- if( !fRawBuffer )
- {
- if( !( fRawBuffer = fAudio->fRawFifo->Pop() ) )
- {
- return false;
- }
-
- fPosInBuffer = 0;
- fPosition = fRawBuffer->fPosition;
- }
-
- int willCopy = MIN( fCount - fSamplesNb, 6 * 256 - fPosInBuffer );
-
- memcpy( fLeftSamples + fSamplesNb,
- (float*) fRawBuffer->fData + fPosInBuffer,
- willCopy * sizeof( float ) );
- memcpy( fRightSamples + fSamplesNb,
- (float*) fRawBuffer->fData + 6 * 256 + fPosInBuffer,
- willCopy * sizeof( float ) );
-
- fSamplesNb += willCopy;
- fPosInBuffer += willCopy;
-
- if( fPosInBuffer == 6 * 256 )
- {
- delete fRawBuffer;
- fRawBuffer = NULL;
- }
- }
-
- return true;
-}
diff --git a/core/Mp3Encoder.h b/core/Mp3Encoder.h
deleted file mode 100644
index fb8348961..000000000
--- a/core/Mp3Encoder.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* $Id: Mp3Encoder.h,v 1.9 2003/10/07 22:48:31 titer Exp $
-
- This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
- It may be used under the terms of the GNU General Public License. */
-
-#ifndef HB_MP3_ENCODER_H
-#define HB_MP3_ENCODER_H
-
-#include "Common.h"
-
-class HBMp3Encoder
-{
- public:
- HBMp3Encoder( HBManager * manager,
- HBAudio * audio );
- bool Work();
-
- private:
- bool Lock();
- void Unlock();
- bool GetSamples();
-
- HBManager * fManager;
- HBAudio * fAudio;
-
- HBLock * fLock;
- bool fUsed;
-
- HBBuffer * fRawBuffer;
- uint32_t fPosInBuffer; /* in samples */
- uint32_t fSamplesNb;
- float * fLeftSamples;
- float * fRightSamples;
-
- float fPosition;
- lame_global_flags * fGlobalFlags;
- bool fInitDone;
- HBBuffer * fMp3Buffer;
- uint32_t fCount;
-};
-
-#endif
diff --git a/core/Mpeg2Dec.c b/core/Mpeg2Dec.c
new file mode 100644
index 000000000..d6ce22b3f
--- /dev/null
+++ b/core/Mpeg2Dec.c
@@ -0,0 +1,195 @@
+/* $Id: Mpeg2Dec.c,v 1.3 2003/11/06 12:33:11 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"
+#include "Mpeg2Dec.h"
+#include "Work.h"
+
+#include <mpeg2dec/mpeg2.h>
+
+/* Local prototypes */
+static int Mpeg2DecWork( HBWork * );
+
+struct HBMpeg2Dec
+{
+ HB_WORK_COMMON_MEMBERS
+
+ HBHandle * handle;
+ HBTitle * title;
+ HBList * rawBufferList;
+ int pass;
+ mpeg2dec_t * libmpeg2;
+ const mpeg2_info_t * info;
+ int lateField;
+};
+
+HBMpeg2Dec * HBMpeg2DecInit( HBHandle * handle, HBTitle * title )
+{
+ HBMpeg2Dec * m ;
+ if( !( m = malloc( sizeof( HBMpeg2Dec ) ) ) )
+ {
+ HBLog( "HBMpeg2Dec: malloc() failed, gonna crash" );
+ return NULL;
+ }
+
+ m->name = strdup( "Mpeg2Dec" );
+ m->work = Mpeg2DecWork;
+
+ m->handle = handle;
+ m->title = title;
+
+ m->rawBufferList = HBListInit();
+ m->pass = 42;
+ m->libmpeg2 = NULL;
+ m->info = NULL;
+ m->lateField = 0;
+
+ return m;
+}
+
+void HBMpeg2DecClose( HBMpeg2Dec ** _m )
+{
+ HBBuffer * buffer;
+
+ HBMpeg2Dec * m = *_m;
+
+ if( m->libmpeg2 )
+ {
+ HBLog( "HBMpeg2Dec: closing libmpeg2 (pass %d)", m->pass );
+ mpeg2_close( m->libmpeg2 );
+ }
+ while( ( buffer = HBListItemAt( m->rawBufferList, 0 ) ) )
+ {
+ HBListRemove( m->rawBufferList, buffer );
+ HBBufferClose( &buffer );
+ }
+ HBListClose( &m->rawBufferList );
+ free( m->name );
+ free( m );
+
+ *_m = NULL;
+}
+
+static int Mpeg2DecWork( HBWork * w )
+{
+ HBMpeg2Dec * m = (HBMpeg2Dec*) w;
+ HBTitle * title = m->title;
+ HBBuffer * mpeg2Buffer;
+ HBBuffer * rawBuffer;
+ HBBuffer * tmpBuffer;
+ mpeg2_state_t state;
+
+ int didSomething = 0;
+
+ /* Push decoded buffers */
+ while( ( rawBuffer = (HBBuffer*)
+ HBListItemAt( m->rawBufferList, 0 ) ) )
+ {
+ tmpBuffer = rawBuffer;
+ if( HBFifoPush( title->rawFifo, &rawBuffer ) )
+ {
+ didSomething = 1;
+ HBListRemove( m->rawBufferList, tmpBuffer );
+ }
+ else
+ {
+ return didSomething;
+ }
+ }
+
+ /* Get a new buffer to decode */
+ if( ( mpeg2Buffer = HBFifoPop( title->mpeg2Fifo ) ) )
+ {
+ didSomething = 1;
+ }
+ else
+ {
+ return didSomething;
+ }
+
+ /* Init or re-init if needed */
+ if( mpeg2Buffer->pass != m->pass )
+ {
+ if( m->libmpeg2 )
+ {
+ HBLog( "HBMpeg2Dec: closing libmpeg2 (pass %d)", m->pass );
+ mpeg2_close( m->libmpeg2 );
+ }
+
+ m->pass = mpeg2Buffer->pass;
+
+ HBLog( "HBMpeg2Dec: opening libmpeg2 (pass %d)", m->pass );
+ m->libmpeg2 = mpeg2_init();
+ m->info = mpeg2_info( m->libmpeg2 );
+ m->lateField = 0;
+ }
+
+ /* Decode */
+ mpeg2_buffer( m->libmpeg2, mpeg2Buffer->data,
+ mpeg2Buffer->data + mpeg2Buffer->size );
+
+ for( ;; )
+ {
+ state = mpeg2_parse( m->libmpeg2 );
+
+ if( state == STATE_BUFFER )
+ {
+ break;
+ }
+ else if( ( state == STATE_SLICE || state == STATE_END ) &&
+ m->info->display_fbuf )
+ {
+ rawBuffer = HBBufferInit( 3 * title->inWidth *
+ title->outWidth );
+
+ /* TODO: make libmpeg2 write directly in our buffer */
+ memcpy( rawBuffer->data, m->info->display_fbuf->buf[0],
+ title->inWidth * title->inHeight );
+ memcpy( rawBuffer->data + title->inWidth * title->inHeight,
+ m->info->display_fbuf->buf[1],
+ title->inWidth * title->inHeight / 4 );
+ memcpy( rawBuffer->data + title->inWidth * title->inHeight +
+ title->inWidth * title->inHeight / 4,
+ m->info->display_fbuf->buf[2],
+ title->inWidth * title->inHeight / 4 );
+
+ rawBuffer->position = mpeg2Buffer->position;
+ rawBuffer->pass = mpeg2Buffer->pass;
+
+ HBListAdd( m->rawBufferList, rawBuffer );
+
+ /* NTSC pulldown kludge */
+ if( m->info->display_picture->nb_fields == 3 )
+ {
+ if( m->lateField )
+ {
+ tmpBuffer = HBBufferInit( rawBuffer->size );
+ tmpBuffer->position = rawBuffer->position;
+ tmpBuffer->pass = rawBuffer->pass;
+ tmpBuffer->last = rawBuffer->last;
+ memcpy( tmpBuffer->data, rawBuffer->data,
+ tmpBuffer->size );
+ HBListAdd( m->rawBufferList, tmpBuffer );
+ }
+ m->lateField = !m->lateField;
+ }
+ }
+ else if( state == STATE_INVALID )
+ {
+ /* Shouldn't happen on a DVD */
+ HBLog( "HBMpeg2Dec: STATE_INVALID" );
+ }
+ }
+
+ if( mpeg2Buffer->last )
+ {
+ HBDone( m->handle );
+ }
+
+ HBBufferClose( &mpeg2Buffer );
+
+ return didSomething;
+}
diff --git a/core/Mpeg2Dec.h b/core/Mpeg2Dec.h
new file mode 100644
index 000000000..af7f18c44
--- /dev/null
+++ b/core/Mpeg2Dec.h
@@ -0,0 +1,15 @@
+/* $Id: Mpeg2Dec.h,v 1.1 2003/11/03 12:08: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. */
+
+#ifndef HB_MPEG2_DEC_H
+#define HB_MPEG2_DEC_H
+
+#include "HandBrakeInternal.h"
+
+HBMpeg2Dec * HBMpeg2DecInit( HBHandle *, HBTitle * );
+void HBMpeg2DecClose( HBMpeg2Dec ** );
+
+#endif
diff --git a/core/Mpeg2Decoder.cpp b/core/Mpeg2Decoder.cpp
deleted file mode 100644
index a9b6a5373..000000000
--- a/core/Mpeg2Decoder.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-/* $Id: Mpeg2Decoder.cpp,v 1.22 2003/10/14 14:35:20 titer Exp $
-
- This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
- It may be used under the terms of the GNU General Public License. */
-
-#include "Mpeg2Decoder.h"
-#include "Manager.h"
-#include "Fifo.h"
-
-extern "C" {
-#include <mpeg2dec/mpeg2.h>
-}
-#include <ffmpeg/avcodec.h>
-
-HBMpeg2Decoder::HBMpeg2Decoder( HBManager * manager, HBTitle * title )
-{
- fManager = manager;
- fTitle = title;
-
- fLock = new HBLock();
- fUsed = false;
-
- fPass = 42;
- fRawBuffer = NULL;
- fRawBufferList = new HBList();
- fHandle = NULL;
-}
-
-bool HBMpeg2Decoder::Work()
-{
- if( !Lock() )
- {
- return false;
- }
-
- /* Push decoded buffers */
- while( ( fRawBuffer =
- (HBBuffer*) fRawBufferList->ItemAt( 0 ) ) )
- {
- if( fTitle->fRawFifo->Push( fRawBuffer ) )
- {
- fRawBufferList->RemoveItem( fRawBuffer );
- }
- else
- {
- Unlock();
- return false;
- }
- }
-
- /* Get a new buffer to decode */
- if( ( fMpeg2Buffer = fTitle->fMpeg2Fifo->Pop() ) )
- {
- /* (Re)init if needed */
- if( fMpeg2Buffer->fPass != fPass )
- {
- fPass = fMpeg2Buffer->fPass;
- Init();
- }
-
- /* Do the job */
- DecodeBuffer();
- }
- else
- {
- Unlock();
- return false;
- }
-
- Unlock();
- return true;
-}
-
-bool HBMpeg2Decoder::Lock()
-{
- fLock->Lock();
- if( fUsed )
- {
- fLock->Unlock();
- return false;
- }
- fUsed = true;
- fLock->Unlock();
- return true;
-}
-
-void HBMpeg2Decoder::Unlock()
-{
- fLock->Lock();
- fUsed = false;
- fLock->Unlock();
-}
-
-void HBMpeg2Decoder::Init()
-{
- if( fHandle )
- {
- mpeg2_close( fHandle );
- }
-
- fLateField = false;
-
- fHandle = mpeg2_init();
-}
-
-void HBMpeg2Decoder::DecodeBuffer()
-{
- const mpeg2_info_t * info = mpeg2_info( fHandle );
-
- /* Feed libmpeg2 */
- mpeg2_buffer( fHandle, fMpeg2Buffer->fData,
- fMpeg2Buffer->fData + fMpeg2Buffer->fSize );
-
- mpeg2_state_t state;
- for( ;; )
- {
- state = mpeg2_parse( fHandle );
-
- if( state == STATE_BUFFER )
- {
- break;
- }
- else if( ( state == STATE_SLICE || state == STATE_END ) &&
- info->display_fbuf )
- {
- fRawBuffer = new HBBuffer( 3 * fTitle->fInWidth *
- fTitle->fInHeight / 2 );
-
- /* TODO : make libmpeg2 write directly in our buffer */
- memcpy( fRawBuffer->fData,
- info->display_fbuf->buf[0],
- fTitle->fInWidth * fTitle->fInHeight );
- memcpy( fRawBuffer->fData + fTitle->fInWidth *
- fTitle->fInHeight,
- info->display_fbuf->buf[1],
- fTitle->fInWidth * fTitle->fInHeight / 4 );
- memcpy( fRawBuffer->fData + fTitle->fInWidth *
- fTitle->fInHeight + fTitle->fInWidth *
- fTitle->fInHeight / 4,
- info->display_fbuf->buf[2],
- fTitle->fInWidth * fTitle->fInHeight / 4 );
-
- fRawBuffer->fPosition = fMpeg2Buffer->fPosition;
- fRawBuffer->fPass = fMpeg2Buffer->fPass;
-
- fRawBufferList->AddItem( fRawBuffer );
-
- /* NTSC pulldown kludge */
- if( info->display_picture->nb_fields == 3 )
- {
- if( fLateField )
- {
- HBBuffer * pulldownBuffer;
- pulldownBuffer = new HBBuffer( fRawBuffer->fSize );
- pulldownBuffer->fPosition = fRawBuffer->fPosition;
- pulldownBuffer->fPass = fRawBuffer->fPass;
- memcpy( pulldownBuffer->fData, fRawBuffer->fData,
- pulldownBuffer->fSize );
- fRawBufferList->AddItem( pulldownBuffer );
- }
- fLateField = !fLateField;
- }
- }
- else if( state == STATE_INVALID )
- {
- /* Shouldn't happen on a DVD */
- Log( "HBMpeg2Decoder: STATE_INVALID" );
- }
- }
-
- delete fMpeg2Buffer;
- fMpeg2Buffer = NULL;
-}
-
diff --git a/core/Mpeg2Decoder.h b/core/Mpeg2Decoder.h
deleted file mode 100644
index 6e20509a2..000000000
--- a/core/Mpeg2Decoder.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* $Id: Mpeg2Decoder.h,v 1.16 2003/10/14 14:35:20 titer Exp $
-
- This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
- It may be used under the terms of the GNU General Public License. */
-
-#ifndef HB_MPEG2_DECODER_H
-#define HB_MPEG2_DECODER_H
-
-#include "Common.h"
-
-class HBMpeg2Decoder
-{
- public:
- HBMpeg2Decoder( HBManager * manager,
- HBTitle * title );
- bool Work();
-
- private:
- bool Lock();
- void Unlock();
-
- void Init();
- void DecodeBuffer();
-
- HBManager * fManager;
- HBTitle * fTitle;
-
- HBLock * fLock;
- bool fUsed;
-
- uint32_t fPass;
- HBBuffer * fMpeg2Buffer;
- HBBuffer * fRawBuffer;
- HBList * fRawBufferList;
- mpeg2dec_t * fHandle;
- bool fLateField;
-};
-
-#endif
diff --git a/core/Mpeg4Encoder.cpp b/core/Mpeg4Encoder.cpp
deleted file mode 100644
index bf5821a4c..000000000
--- a/core/Mpeg4Encoder.cpp
+++ /dev/null
@@ -1,181 +0,0 @@
-/* $Id: Mpeg4Encoder.cpp,v 1.25 2003/10/14 15:23:56 titer Exp $
-
- This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
- It may be used under the terms of the GNU General Public License. */
-
-#include "Mpeg4Encoder.h"
-#include "Manager.h"
-#include "Fifo.h"
-
-#include <ffmpeg/avcodec.h>
-
-HBMpeg4Encoder::HBMpeg4Encoder( HBManager * manager, HBTitle * title )
-{
- fManager = manager;
- fTitle = title;
-
- fLock = new HBLock();
- fUsed = false;
-
- fPass = 42;
- fMpeg4Buffer = NULL;
- fFile = NULL;
- fFrame = avcodec_alloc_frame();
- fLog = NULL;
-}
-
-bool HBMpeg4Encoder::Work()
-{
- if( !Lock() )
- {
- return false;
- }
-
- if( fMpeg4Buffer )
- {
- if( fTitle->fMpeg4Fifo->Push( fMpeg4Buffer ) )
- {
- fMpeg4Buffer = NULL;
- }
- else
- {
- Unlock();
- return false;
- }
- }
-
- if( ( fResizedBuffer = fTitle->fResizedFifo->Pop() ) )
- {
- if( fResizedBuffer->fPass != fPass )
- {
- fPass = fResizedBuffer->fPass;
- Init();
- }
-
- fManager->SetPosition( fResizedBuffer->fPosition );
- EncodeBuffer();
- }
- else
- {
- Unlock();
- return false;
- }
-
- Unlock();
- return true;
-}
-
-bool HBMpeg4Encoder::Lock()
-{
- fLock->Lock();
- if( fUsed )
- {
- fLock->Unlock();
- return false;
- }
- fUsed = true;
- fLock->Unlock();
- return true;
-}
-
-void HBMpeg4Encoder::Unlock()
-{
- fLock->Lock();
- fUsed = false;
- fLock->Unlock();
-}
-
-void HBMpeg4Encoder::Init()
-{
- /* Clean up if needed */
- if( fFile )
- {
- fclose( fFile );
- }
-
- AVCodec * codec = avcodec_find_encoder( CODEC_ID_MPEG4 );
- if( !codec )
- {
- Log( "HBMpeg4Encoder: avcodec_find_encoder() failed" );
- fManager->Error( HB_ERROR_MPEG4_INIT );
- return;
- }
-
- fContext = avcodec_alloc_context();
- fContext->bit_rate = 1024 * fTitle->fBitrate;
- fContext->bit_rate_tolerance = 10240 * fTitle->fBitrate;
- fContext->width = fTitle->fOutWidth;
- fContext->height = fTitle->fOutHeight;
- fContext->frame_rate = fTitle->fRate;
- fContext->frame_rate_base = fTitle->fScale;
- fContext->gop_size = 10 * fTitle->fRate / fTitle->fScale;
-
- if( fPass == 1 )
- {
- fContext->flags |= CODEC_FLAG_PASS1;
-
- char fileName[1024]; memset( fileName, 0, 1024 );
- sprintf( fileName, "/tmp/HB.%d.ffmpeg.log", fManager->GetPid() );
- fFile = fopen( fileName, "w" );
- }
- else if( fPass == 2 )
- {
- fContext->flags |= CODEC_FLAG_PASS2;
-
- char fileName[1024]; memset( fileName, 0, 1024 );
- sprintf( fileName, "/tmp/HB.%d.ffmpeg.log", fManager->GetPid() );
- fFile = fopen( fileName, "r" );
- fseek( fFile, 0, SEEK_END );
- uint32_t size = ftell( fFile );
- fLog = (char*) malloc( size + 1 );
- fseek( fFile, 0, SEEK_SET );
- fread( fLog, size, 1, fFile );
- fclose( fFile );
- fLog[size] = '\0';
- fContext->stats_in = fLog;
- }
-
- if( avcodec_open( fContext, codec ) < 0 )
- {
- Log( "HBMpeg4Encoder: avcodec_open() failed" );
- fManager->Error( HB_ERROR_MPEG4_INIT );
- return;
- }
-}
-
-void HBMpeg4Encoder::EncodeBuffer()
-{
- fFrame->data[0] = fResizedBuffer->fData;
- fFrame->data[1] = fFrame->data[0] + fTitle->fOutWidth *
- fTitle->fOutHeight;
- fFrame->data[2] = fFrame->data[1] + fTitle->fOutWidth *
- fTitle->fOutHeight / 4;
- fFrame->linesize[0] = fTitle->fOutWidth;
- fFrame->linesize[1] = fTitle->fOutWidth / 2;
- fFrame->linesize[2] = fTitle->fOutWidth / 2;
-
- fMpeg4Buffer = new HBBuffer( 3 * fTitle->fOutWidth *
- fTitle->fOutHeight / 2 );
- /* Should be really too much... */
-
- fMpeg4Buffer->fPosition = fResizedBuffer->fPosition;
- fMpeg4Buffer->fSize =
- avcodec_encode_video( fContext, fMpeg4Buffer->fData,
- fMpeg4Buffer->fAllocSize, fFrame );
- fMpeg4Buffer->fKeyFrame = ( fContext->coded_frame->key_frame != 0 );
-
- if( fResizedBuffer->fPass == 1 )
- {
- if( fContext->stats_out )
- {
- fprintf( fFile, "%s", fContext->stats_out );
- }
- delete fMpeg4Buffer;
- fMpeg4Buffer = NULL;
- }
-
- delete fResizedBuffer;
- fResizedBuffer = NULL;
-}
-
diff --git a/core/Mpeg4Encoder.h b/core/Mpeg4Encoder.h
deleted file mode 100644
index 3d20f315a..000000000
--- a/core/Mpeg4Encoder.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* $Id: Mpeg4Encoder.h,v 1.11 2003/10/08 11:56:40 titer Exp $
-
- This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
- It may be used under the terms of the GNU General Public License. */
-
-#ifndef HB_MPEG4_ENCODER_H
-#define HB_MPEG4_ENCODER_H
-
-#include "Common.h"
-
-class HBMpeg4Encoder
-{
- public:
- HBMpeg4Encoder( HBManager * manager,
- HBTitle * title );
- bool Work();
-
- private:
- bool Lock();
- void Unlock();
-
- void Init();
- void EncodeBuffer();
-
- HBManager * fManager;
- HBTitle * fTitle;
-
- HBLock * fLock;
- bool fUsed;
-
- uint32_t fPass;
- HBBuffer * fResizedBuffer;
- AVCodecContext * fContext;
- AVFrame * fFrame;
- FILE * fFile;
- char * fLog;
- HBBuffer * fMpeg4Buffer;
-};
-
-#endif
diff --git a/core/MpegDemux.cpp b/core/MpegDemux.cpp
deleted file mode 100644
index 249ee2738..000000000
--- a/core/MpegDemux.cpp
+++ /dev/null
@@ -1,308 +0,0 @@
-/* $Id: MpegDemux.cpp,v 1.20 2003/10/16 13:36:17 titer Exp $
-
- This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
- It may be used under the terms of the GNU General Public License. */
-
-#include "MpegDemux.h"
-#include "Manager.h"
-#include "Fifo.h"
-
-extern "C" {
-#include <a52dec/a52.h>
-}
-
-HBMpegDemux::HBMpegDemux( HBManager * manager, HBTitle * title,
- HBAudio * audio1, HBAudio * audio2 )
-{
- fManager = manager;
- fTitle = title;
- fAudio1 = audio1;
- fAudio2 = audio2;
-
- fLock = new HBLock();
- fUsed = false;
-
- fPSBuffer = NULL;
- fESBuffer = NULL;
- fESBufferList = NULL;
-
- fFirstVideoPTS = -1;
- fFirstAudio1PTS = -1;
- fFirstAudio2PTS = -1;
-}
-
-HBMpegDemux::~HBMpegDemux()
-{
- /* Free memory */
- if( fESBufferList )
- {
- while( ( fESBuffer = (HBBuffer*) fESBufferList->ItemAt( 0 ) ) )
- {
- fESBufferList->RemoveItem( fESBuffer );
- delete fESBuffer;
- }
- }
- delete fLock;
-}
-
-bool HBMpegDemux::Work()
-{
- if( !Lock() )
- {
- return false;
- }
-
- /* Push waiting buffers */
- if( fESBufferList )
- {
- for( uint32_t i = 0; i < fESBufferList->CountItems(); )
- {
- fESBuffer = (HBBuffer*) fESBufferList->ItemAt( i );
-
- if( fESBuffer->fPass == 1 && fESBuffer->fStreamId != 0xE0 )
- {
- fESBufferList->RemoveItem( fESBuffer );
- delete fESBuffer;
- continue;
- }
-
- /* Look for a decoder for this ES */
-
- if( fESBuffer->fStreamId == 0xE0 )
- {
- if( fFirstVideoPTS < 0 )
- {
- fFirstVideoPTS = fESBuffer->fPTS;
- Log( "HBMpegDemux: got first 0xE0 packet (%lld)",
- fFirstVideoPTS );
- }
- if( fTitle->fMpeg2Fifo->Push( fESBuffer ) )
- {
- fESBufferList->RemoveItem( fESBuffer );
- }
- else
- {
- i++;
- }
- }
- else if( fAudio1 &&
- fESBuffer->fStreamId == fAudio1->fId )
- {
- if( fFirstAudio1PTS < 0 )
- {
- fFirstAudio1PTS = fESBuffer->fPTS;
- Log( "HBMpegDemux: got first 0x%x packet (%lld)",
- fAudio1->fId, fFirstAudio1PTS );
-
- fAudio1->fDelay =
- ( fFirstAudio1PTS - fFirstVideoPTS ) / 90;
- }
- if( fAudio1->fAc3Fifo->Push( fESBuffer ) )
- {
- fESBufferList->RemoveItem( fESBuffer );
- }
- else
- {
- i++;
- }
- }
- else if( fAudio2 &&
- fESBuffer->fStreamId == fAudio2->fId )
- {
- if( fFirstAudio2PTS < 0 )
- {
- fFirstAudio2PTS = fESBuffer->fPTS;
- Log( "HBMpegDemux: got first 0x%x packet (%lld)",
- fAudio2->fId, fFirstAudio2PTS );
-
- fAudio2->fDelay =
- ( fFirstAudio2PTS - fFirstVideoPTS ) / 90;
- }
- if( fAudio2->fAc3Fifo->Push( fESBuffer ) )
- {
- fESBufferList->RemoveItem( fESBuffer );
- }
- else
- {
- i++;
- }
- }
- else
- {
- fESBufferList->RemoveItem( fESBuffer );
- delete fESBuffer;
- }
- }
-
- if( !fESBufferList->CountItems() )
- {
- delete fESBufferList;
- fESBufferList = NULL;
- }
- else
- {
- Unlock();
- return false;
- }
- }
-
- /* Get a PS packet */
- if( ( fPSBuffer = fTitle->fPSFifo->Pop() ) )
- {
- /* Get the ES data in it */
- PStoES( fPSBuffer, &fESBufferList );
- }
- else
- {
- Unlock();
- return false;
- }
-
- Unlock();
- return true;
-}
-
-bool HBMpegDemux::Lock()
-{
- fLock->Lock();
- if( fUsed )
- {
- fLock->Unlock();
- return false;
- }
- fUsed = true;
- fLock->Unlock();
- return true;
-}
-
-void HBMpegDemux::Unlock()
-{
- fLock->Lock();
- fUsed = false;
- fLock->Unlock();
-}
-
-bool PStoES( HBBuffer * psBuffer, HBList ** _esBufferList )
-{
-#define psData (psBuffer->fData)
-
- uint32_t pos = 0;
-
- /* pack_header */
- if( psData[pos] != 0 || psData[pos+1] != 0 ||
- psData[pos+2] != 0x1 || psData[pos+3] != 0xBA )
- {
- Log( "PStoES: not a PS packet (%02x%02x%02x%02x)",
- psData[pos] << 24, psData[pos+1] << 16,
- psData[pos+2] << 8, psData[pos+3] );
- delete psBuffer;
- (*_esBufferList) = NULL;
- return false;
- }
- pos += 4; /* pack_start_code */
- pos += 9; /* pack_header */
- pos += 1 + ( psData[pos] & 0x7 ); /* stuffing bytes */
-
- /* system_header */
- if( psData[pos] == 0 && psData[pos+1] == 0 &&
- psData[pos+2] == 0x1 && psData[pos+3] == 0xBB )
- {
- uint32_t header_length;
-
- pos += 4; /* system_header_start_code */
- header_length = ( psData[pos] << 8 ) + psData[pos+1];
- pos += 2 + header_length;
- }
-
- HBList * esBufferList = new HBList();
- HBBuffer * esBuffer;
-
- /* PES */
- while( pos + 6 < psBuffer->fSize &&
- psData[pos] == 0 && psData[pos+1] == 0 && psData[pos+2] == 0x1 )
- {
- uint32_t streamId;
- uint32_t PES_packet_length;
- uint32_t PES_packet_end;
- uint32_t PES_header_data_length;
- uint32_t PES_header_end;
- bool hasPTS;
- uint64_t PTS = 0;
-
- pos += 3; /* packet_start_code_prefix */
- streamId = psData[pos];
- pos += 1;
-
- PES_packet_length = ( psData[pos] << 8 ) + psData[pos+1];
- pos += 2; /* PES_packet_length */
- PES_packet_end = pos + PES_packet_length;
-
- if( streamId != 0xE0 && streamId != 0xBD )
- {
- /* Not interesting */
- pos = PES_packet_end;
- continue;
- }
-
- hasPTS = ( ( psData[pos+1] >> 6 ) & 0x2 );
- pos += 2; /* Required headers */
-
- PES_header_data_length = psData[pos];
- pos += 1;
- PES_header_end = pos + PES_header_data_length;
-
- if( hasPTS )
- {
- PTS = ( ( ( (uint64_t) psData[pos] >> 1 ) & 0x7 ) << 30 ) +
- ( psData[pos+1] << 22 ) +
- ( ( psData[pos+2] >> 1 ) << 15 ) +
- ( psData[pos+3] << 7 ) +
- ( psData[pos+4] >> 1 );
- }
-
- pos = PES_header_end;
-
- if( streamId == 0xBD )
- {
- /* A52: don't ask */
- streamId |= ( psData[pos] << 8 );
- pos += 4;
- }
-
- /* Sanity check */
- if( pos >= PES_packet_end )
- {
- Log( "PStoES: pos >= PES_packet_end" );
- pos = PES_packet_end;
- continue;
- }
-
- /* Here we hit we ES payload */
- esBuffer = new HBBuffer( PES_packet_end - pos );
-
- esBuffer->fPosition = psBuffer->fPosition;
- esBuffer->fPass = psBuffer->fPass;
- esBuffer->fStreamId = streamId;
- esBuffer->fPTS = PTS;
- memcpy( esBuffer->fData, psBuffer->fData + pos,
- PES_packet_end - pos );
-
- esBufferList->AddItem( esBuffer );
-
- pos = PES_packet_end;
- }
-
- delete psBuffer;
-
- if( !esBufferList->CountItems() )
- {
- delete esBufferList;
- esBufferList = NULL;
- }
-
- (*_esBufferList) = esBufferList;
- return true;
-
-#undef psData
-}
diff --git a/core/MpegDemux.h b/core/MpegDemux.h
deleted file mode 100644
index 187a08de9..000000000
--- a/core/MpegDemux.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* $Id: MpegDemux.h,v 1.11 2003/10/09 13:24:48 titer Exp $
-
- This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
- It may be used under the terms of the GNU General Public License. */
-
-#ifndef HB_MPEG_DEMUX_H
-#define HB_MPEG_DEMUX_H
-
-#include "Common.h"
-
-bool PStoES( HBBuffer * psBuffer, HBList ** _esBufferList );
-
-class HBMpegDemux
-{
- public:
- HBMpegDemux( HBManager * manager, HBTitle * title,
- HBAudio * audio1, HBAudio * audio2 );
- ~HBMpegDemux();
- bool Work();
-
- private:
- bool Lock();
- void Unlock();
-
- HBManager * fManager;
- HBTitle * fTitle;
- HBAudio * fAudio1;
- HBAudio * fAudio2;
-
- HBLock * fLock;
- bool fUsed;
-
- HBBuffer * fPSBuffer;
- HBBuffer * fESBuffer;
- HBList * fESBufferList;
-
- int64_t fFirstVideoPTS;
- int64_t fFirstAudio1PTS;
- int64_t fFirstAudio2PTS;
-};
-
-#endif
diff --git a/core/Resizer.cpp b/core/Resizer.cpp
deleted file mode 100644
index c49a39bf3..000000000
--- a/core/Resizer.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-/* $Id: Resizer.cpp,v 1.9 2003/10/14 14:35:20 titer Exp $
-
- This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
- It may be used under the terms of the GNU General Public License. */
-
-#include "Resizer.h"
-#include "Manager.h"
-#include "Fifo.h"
-
-#include <ffmpeg/avcodec.h>
-
-HBResizer::HBResizer( HBManager * manager, HBTitle * title )
-{
- fManager = manager;
- fTitle = title;
-
- /* Lock */
- fLock = new HBLock();
- fUsed = false;
-
- /* Init libavcodec */
- fResampleContext =
- img_resample_full_init( fTitle->fOutWidth, fTitle->fOutHeight,
- fTitle->fInWidth, fTitle->fInHeight,
- fTitle->fTopCrop, fTitle->fBottomCrop,
- fTitle->fLeftCrop, fTitle->fRightCrop );
-
- /* Buffers & pictures */
- fRawBuffer = NULL;
- fDeinterlacedBuffer = new HBBuffer( 3 * fTitle->fInWidth *
- fTitle->fInHeight / 2 );
- fResizedBuffer = NULL;
- fRawPicture = (AVPicture*) malloc( sizeof( AVPicture ) );
- fDeinterlacedPicture = (AVPicture*) malloc( sizeof( AVPicture ) );
- fResizedPicture = (AVPicture*) malloc( sizeof( AVPicture ) );
-
- avpicture_fill( fDeinterlacedPicture, fDeinterlacedBuffer->fData,
- PIX_FMT_YUV420P, fTitle->fInWidth,
- fTitle->fInHeight );
-}
-
-HBResizer::~HBResizer()
-{
- /* Free memory */
- free( fResizedPicture );
- free( fDeinterlacedPicture );
- free( fRawPicture );
- if( fResizedBuffer ) delete fResizedBuffer;
- delete fDeinterlacedBuffer;
- img_resample_close( fResampleContext );
- delete fLock;
-}
-
-bool HBResizer::Work()
-{
- if( !Lock() )
- {
- return false;
- }
-
- /* Push the latest resized buffer */
- if( fResizedBuffer )
- {
- if( fTitle->fResizedFifo->Push( fResizedBuffer ) )
- {
- fResizedBuffer = NULL;
- }
- else
- {
- Unlock();
- return false;
- }
- }
-
- /* Get a new raw picture */
- if( ( fRawBuffer = fTitle->fRawFifo->Pop() ) )
- {
- /* Do the job */
- avpicture_fill( fRawPicture, fRawBuffer->fData,
- PIX_FMT_YUV420P, fTitle->fInWidth,
- fTitle->fInHeight );
-
- fResizedBuffer = new HBBuffer( 3 * fTitle->fOutWidth *
- fTitle->fOutHeight / 2 );
- fResizedBuffer->fPosition = fRawBuffer->fPosition;
- fResizedBuffer->fPass = fRawBuffer->fPass;
- avpicture_fill( fResizedPicture, fResizedBuffer->fData,
- PIX_FMT_YUV420P, fTitle->fOutWidth,
- fTitle->fOutHeight );
-
- if( fTitle->fDeinterlace )
- {
- avpicture_deinterlace( fDeinterlacedPicture, fRawPicture,
- PIX_FMT_YUV420P,
- fTitle->fInWidth,
- fTitle->fInHeight );
- img_resample( fResampleContext, fResizedPicture,
- fDeinterlacedPicture );
- }
- else
- {
- img_resample( fResampleContext, fResizedPicture,
- fRawPicture );
- }
- delete fRawBuffer;
- fRawBuffer = NULL;
- }
- else
- {
- Unlock();
- return false;
- }
-
- Unlock();
- return true;
-}
-
-bool HBResizer::Lock()
-{
- fLock->Lock();
- if( fUsed )
- {
- fLock->Unlock();
- return false;
- }
- fUsed = true;
- fLock->Unlock();
- return true;
-}
-
-void HBResizer::Unlock()
-{
- fLock->Lock();
- fUsed = false;
- fLock->Unlock();
-}
-
diff --git a/core/Resizer.h b/core/Resizer.h
deleted file mode 100644
index f6d4a4568..000000000
--- a/core/Resizer.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* $Id: Resizer.h,v 1.5 2003/10/07 22:48:31 titer Exp $
-
- This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
- It may be used under the terms of the GNU General Public License. */
-
-#ifndef HB_RESIZER_H
-#define HB_RESIZER_H
-
-#include "Common.h"
-
-class HBResizer
-{
- public:
- HBResizer( HBManager * manager, HBTitle * title );
- ~HBResizer();
- bool Work();
-
- private:
- bool Lock();
- void Unlock();
-
- HBManager * fManager;
- HBTitle * fTitle;
-
- HBLock * fLock;
- bool fUsed;
-
- ImgReSampleContext * fResampleContext;
- HBBuffer * fRawBuffer;
- HBBuffer * fDeinterlacedBuffer;
- HBBuffer * fResizedBuffer;
- AVPicture * fRawPicture;
- AVPicture * fDeinterlacedPicture;
- AVPicture * fResizedPicture;
-};
-
-#endif
diff --git a/core/Scale.c b/core/Scale.c
new file mode 100644
index 000000000..7e9295962
--- /dev/null
+++ b/core/Scale.c
@@ -0,0 +1,139 @@
+/* $Id: Scale.c,v 1.4 2003/11/06 13:03: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 "Fifo.h"
+#include "Scale.h"
+#include "Work.h"
+
+#include <ffmpeg/avcodec.h>
+
+/* Local prototypes */
+static int ScaleWork( HBWork * );
+
+struct HBScale
+{
+ HB_WORK_COMMON_MEMBERS
+
+ HBHandle * handle;
+ HBTitle * title;
+
+ ImgReSampleContext * context;
+ AVPicture rawPicture;
+ HBBuffer * deintBuffer;
+ AVPicture deintPicture;
+ HBBuffer * scaledBuffer;
+ AVPicture scaledPicture;
+};
+
+HBScale * HBScaleInit( HBHandle * handle, HBTitle * title )
+{
+ HBScale * s;
+ if( !( s = malloc( sizeof( HBScale ) ) ) )
+ {
+ HBLog( "HBScaleInit: malloc() failed, gonna crash" );
+ return NULL;
+ }
+
+ s->name = strdup( "Scale" );
+ s->work = ScaleWork;
+
+ s->handle = handle;
+ s->title = title;
+
+ /* Init libavcodec */
+ s->context =
+ img_resample_full_init( title->outWidth, title->outHeight,
+ title->inWidth, title->inHeight,
+ title->topCrop, title->bottomCrop,
+ title->leftCrop, title->rightCrop );
+
+ /* Allocate a constant buffer used for deinterlacing */
+ s->deintBuffer = HBBufferInit( 3 * title->inWidth *
+ title->inHeight / 2 );
+ avpicture_fill( &s->deintPicture, s->deintBuffer->data,
+ PIX_FMT_YUV420P, title->inWidth, title->inHeight );
+
+ s->scaledBuffer = NULL;
+
+ return s;
+}
+
+void HBScaleClose( HBScale ** _s )
+{
+ HBScale * s = *_s;
+
+ img_resample_close( s->context );
+ HBBufferClose( &s->deintBuffer );
+ free( s->name );
+ free( s );
+
+ *_s = NULL;
+}
+
+static int ScaleWork( HBWork * w )
+{
+ HBScale * s = (HBScale*) w;
+ HBTitle * title = s->title;
+ HBBuffer * rawBuffer;
+
+ int didSomething = 0;
+
+ /* Push scaled buffer */
+ if( s->scaledBuffer )
+ {
+ if( HBFifoPush( title->scaledFifo, &s->scaledBuffer ) )
+ {
+ didSomething = 1;
+ }
+ else
+ {
+ return didSomething;
+ }
+ }
+
+ /* Get a new raw picture */
+ if( ( rawBuffer = HBFifoPop( title->rawFifo ) ) )
+ {
+ didSomething = 1;
+ }
+ else
+ {
+ return didSomething;
+ }
+
+ /* Allocate new buffer for the scaled picture */
+ s->scaledBuffer = HBBufferInit( 3 * title->outWidth *
+ title->outHeight / 2 );
+ s->scaledBuffer->position = rawBuffer->position;
+ s->scaledBuffer->pass = rawBuffer->pass;
+
+ /* libavcodec stuff */
+ avpicture_fill( &s->rawPicture, rawBuffer->data, PIX_FMT_YUV420P,
+ title->inWidth, title->inHeight );
+ avpicture_fill( &s->scaledPicture, s->scaledBuffer->data,
+ PIX_FMT_YUV420P, title->outWidth,
+ title->outHeight );
+
+ /* Do the job */
+ if( title->deinterlace )
+ {
+ avpicture_deinterlace( &s->deintPicture, &s->rawPicture,
+ PIX_FMT_YUV420P, title->inWidth,
+ title->inHeight );
+ img_resample( s->context, &s->scaledPicture,
+ &s->deintPicture );
+ }
+ else
+ {
+ img_resample( s->context, &s->scaledPicture, &s->rawPicture );
+ }
+
+ /* Free memory */
+ HBBufferClose( &rawBuffer );
+
+ return didSomething;
+}
+
diff --git a/core/Scale.h b/core/Scale.h
new file mode 100644
index 000000000..cf06ad661
--- /dev/null
+++ b/core/Scale.h
@@ -0,0 +1,15 @@
+/* $Id: Scale.h,v 1.1 2003/11/03 12:08: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. */
+
+#ifndef HB_SCALE_H
+#define HB_SCALE_H
+
+#include "HandBrakeInternal.h"
+
+HBScale * HBScaleInit( HBHandle *, HBTitle * );
+void HBScaleClose( HBScale ** );
+
+#endif
diff --git a/core/Scan.c b/core/Scan.c
new file mode 100644
index 000000000..83f2fc098
--- /dev/null
+++ b/core/Scan.c
@@ -0,0 +1,395 @@
+/* $Id: Scan.c,v 1.4 2003/11/06 13:03: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 "Fifo.h"
+#include "Languages.h"
+#include "Scan.h"
+#include "Thread.h"
+
+#include <dvdread/ifo_types.h>
+#include <dvdplay/dvdplay.h>
+#include <dvdplay/info.h>
+#include <dvdplay/state.h>
+#include <dvdplay/nav.h>
+
+#include <mpeg2dec/mpeg2.h>
+
+/* Local prototypes */
+static void ScanThread( void * );
+static HBTitle * ScanTitle( HBScan *, dvdplay_ptr vmg, int index );
+static int DecodeFrame( HBScan * s, dvdplay_ptr vmg,
+ HBTitle * title, int which );
+static char * LanguageForCode( int code );
+
+struct HBScan
+{
+ HBHandle * handle;
+ char * device;
+ int title;
+ int die;
+ HBThread * thread;
+};
+
+HBScan * HBScanInit( HBHandle * handle, 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 )
+{
+ HBScan * s = (HBScan*) _s;
+ dvdplay_ptr vmg;
+ HBList * titleList = HBListInit();
+ HBTitle * title;
+ int i;
+
+ HBLog( "HBScan: opening device %s", s->device );
+ HBScanning( s->handle, 0 );
+
+ vmg = dvdplay_open( s->device, NULL, NULL );
+ if( !vmg )
+ {
+ HBLog( "HBScan: dvdplay_open() failed (%s)", s->device );
+ HBScanDone( s->handle, titleList );
+ return;
+ }
+
+ /* Detect titles */
+ for( i = ( s->title ? s->title - 1 : 0 );
+ i < ( s->title ? s->title : dvdplay_title_nr( vmg ) );
+ i++ )
+ {
+ if( s->die )
+ {
+ break;
+ }
+
+ if( !( title = ScanTitle( s, vmg, i + 1 ) ) )
+ {
+ continue;
+ }
+
+ HBListAdd( titleList, title );
+ }
+
+ HBLog( "HBScan: closing device %s", s->device );
+ dvdplay_close( vmg );
+
+ HBScanDone( s->handle, titleList );
+}
+
+static HBTitle * ScanTitle( HBScan * s, dvdplay_ptr vmg, int index )
+{
+ HBTitle * title;
+ int audio_nr, foo;
+ audio_attr_t * attr;
+ HBAudio * audio;
+ int i;
+ uint8_t dummy[DVD_VIDEO_LB_LEN];
+
+ HBLog( "HBScan: scanning title %d", index );
+ HBScanning( s->handle, index );
+
+ title = HBTitleInit( s->device, index );
+ dvdplay_start( vmg, index );
+
+ /* Length */
+ title->length = dvdplay_title_time( vmg );
+ HBLog( "HBScan: title length is %d seconds", title->length );
+
+ /* Discard titles under 10 seconds */
+ if( title->length < 10 )
+ {
+ HBLog( "HBScan: ignoring title %d (too short)", index );
+ HBTitleClose( &title );
+ return NULL;
+ }
+
+ /* Detect languages */
+ dvdplay_audio_info( vmg, &audio_nr, &foo );
+
+ for( i = 0; i < audio_nr; i++ )
+ {
+ int id;
+ int j;
+
+ if( s->die )
+ {
+ break;
+ }
+
+ id = dvdplay_audio_id( vmg, i );
+
+ if( id < 1 )
+ {
+ continue;
+ }
+
+ if( ( id & 0xFF ) != 0xBD )
+ {
+ HBLog( "HBScan: non-AC3 audio track detected, ignoring" );
+ continue;
+ }
+
+ /* Check if we don't already found an track with the same id */
+ audio = NULL;
+ for( j = 0; j < HBListCountItems( title->audioList ); j++ )
+ {
+ audio = (HBAudio*) HBListItemAt( title->audioList, j );
+ if( id == audio->id )
+ {
+ break;
+ }
+ else
+ {
+ audio = NULL;
+ }
+ }
+
+ if( audio )
+ {
+ HBLog( "HBScan: discarding duplicate track %x", id );
+ continue;
+ }
+
+ attr = dvdplay_audio_attr( vmg, j );
+ audio = HBAudioInit( id, LanguageForCode( attr->lang_code ) );
+ HBLog( "HBScan: new language (%x, %s)", id, audio->language );
+ HBListAdd( title->audioList, audio );
+ }
+
+ /* Discard titles with no audio tracks */
+ if( !HBListCountItems( title->audioList ) )
+ {
+ HBLog( "HBScan: ignoring title %d (no audio track)", index );
+ HBTitleClose( &title );
+ return NULL;
+ }
+
+ /* Kludge : libdvdplay wants we to read a first block before seeking */
+ dvdplay_read( vmg, dummy, 1 );
+
+
+ for( i = 0; i < 10; i++ )
+ {
+ if( s->die )
+ {
+ break;
+ }
+
+ if( !DecodeFrame( s, vmg, title, i ) )
+ {
+ HBLog( "HBScan: ignoring title %d (could not decode)",
+ index );
+ HBTitleClose( &title );
+ return NULL;
+ }
+ }
+
+ 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 int DecodeFrame( HBScan * s, dvdplay_ptr vmg,
+ HBTitle * title, int which )
+{
+ int titleFirst = dvdplay_title_first( vmg );
+ int titleEnd = dvdplay_title_end( vmg );
+ int pictureStart = ( which + 1 ) * ( titleEnd - titleFirst ) / 11;
+ int pictureEnd = titleFirst + ( which + 2 ) *
+ ( titleEnd - titleFirst ) / 11;
+
+ mpeg2dec_t * handle;
+ const mpeg2_info_t * info;
+ mpeg2_state_t state;
+ char fileName[1024];
+ FILE * file;
+
+ HBList * esBufferList = HBListInit();
+ HBBuffer * psBuffer = NULL;
+ HBBuffer * esBuffer = NULL;
+
+ /* Seek to the right place */
+ dvdplay_seek( vmg, pictureStart );
+
+ /* Init libmpeg2 */
+ handle = mpeg2_init();
+ info = mpeg2_info( handle );
+
+ /* Init the destination file */
+ memset( fileName, 0, 1024 );
+ sprintf( fileName, "/tmp/HB.%d.%d.%d", HBGetPid( s->handle ),
+ title->index, which );
+ file = fopen( fileName, "w" );
+
+#define CLEANUP \
+ while( ( esBuffer = (HBBuffer*) HBListItemAt( esBufferList, 0 ) ) ) \
+ { \
+ HBListRemove( esBufferList, esBuffer ); \
+ HBBufferClose( &esBuffer ); \
+ } \
+ HBListClose( &esBufferList ); \
+ if( psBuffer ) HBBufferClose( &psBuffer ); \
+ if( esBuffer ) HBBufferClose( &esBuffer ); \
+ mpeg2_close( handle ); \
+ fclose( file )
+
+ for( ;; )
+ {
+ state = mpeg2_parse( handle );
+
+ if( state == STATE_BUFFER )
+ {
+ /* Free the previous buffer */
+ if( esBuffer )
+ {
+ HBBufferClose( &esBuffer );
+ }
+
+ /* Get a new one */
+ while( !esBuffer )
+ {
+ while( !HBListCountItems( esBufferList ) )
+ {
+ psBuffer = HBBufferInit( DVD_VIDEO_LB_LEN );
+ if( dvdplay_read( vmg, psBuffer->data, 1 ) != 1 ||
+ !HBPStoES( &psBuffer, esBufferList ) )
+ {
+ HBLog( "HBScan: failed to get a valid PS "
+ "packet" );
+ CLEANUP;
+ return 0;
+ }
+
+ if( dvdplay_position( vmg ) >= pictureEnd )
+ {
+ HBLog( "HBScan: gone too far, aborting" );
+ CLEANUP;
+ return 0;
+ }
+ }
+
+ esBuffer = (HBBuffer*) HBListItemAt( esBufferList, 0 );
+ HBListRemove( esBufferList, esBuffer );
+
+ if( esBuffer->streamId != 0xE0 )
+ {
+ HBBufferClose( &esBuffer );
+ }
+ }
+
+ /* Feed libmpeg2 */
+ mpeg2_buffer( handle, esBuffer->data,
+ esBuffer->data + esBuffer->size );
+ }
+ else if( state == STATE_SEQUENCE )
+ {
+ /* 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;
+ }
+ else if( ( state == STATE_SLICE || state == STATE_END ) &&
+ ( info->display_fbuf ) &&
+ ( info->display_picture->flags & PIC_MASK_CODING_TYPE )
+ == PIC_FLAG_CODING_TYPE_I )
+ {
+ /* 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 );
+ break;
+ }
+ else if( state == STATE_INVALID )
+ {
+ /* Reset libmpeg2 */
+ mpeg2_close( handle );
+ handle = mpeg2_init();
+ }
+ }
+
+ CLEANUP;
+
+ return 1;
+
+#undef CLEANUP
+}
+
+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/Scan.h b/core/Scan.h
new file mode 100644
index 000000000..5cc8542e7
--- /dev/null
+++ b/core/Scan.h
@@ -0,0 +1,15 @@
+/* $Id: Scan.h,v 1.2 2003/11/06 13:03: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. */
+
+#ifndef HB_SCAN_H
+#define HB_SCAN_H
+
+#include "HandBrakeInternal.h"
+
+HBScan * HBScanInit( HBHandle *, char * device, int title );
+void HBScanClose( HBScan ** );
+
+#endif
diff --git a/core/Scanner.cpp b/core/Scanner.cpp
deleted file mode 100644
index 44ff6be3a..000000000
--- a/core/Scanner.cpp
+++ /dev/null
@@ -1,303 +0,0 @@
-/* $Id: Scanner.cpp,v 1.23 2003/10/13 14:12:18 titer Exp $
-
- This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
- It may be used under the terms of the GNU General Public License. */
-
-#include "Scanner.h"
-#include "Manager.h"
-#include "Fifo.h"
-#include "MpegDemux.h"
-
-#include <dvdread/ifo_types.h>
-#include <dvdplay/dvdplay.h>
-#include <dvdplay/info.h>
-#include <dvdplay/state.h>
-#include <dvdplay/nav.h>
-
-extern "C" {
-#include <mpeg2dec/mpeg2.h>
-}
-
-HBScanner::HBScanner( HBManager * manager, char * device )
- : HBThread( "scanner", HB_NORMAL_PRIORITY )
-{
- fManager = manager;
- fDevice = strdup( device );
-
- Run();
-}
-
-void HBScanner::DoWork()
-{
- Log( "HBScanner: opening device %s", fDevice );
-
- dvdplay_ptr vmg;
- vmg = dvdplay_open( fDevice, NULL, NULL );
- if( !vmg )
- {
- Log( "HBScanner: dvdplay_open() failed (%s)",
- fDevice );
- fManager->ScanDone( NULL );
- return;
- }
-
- /* Detect titles */
- HBList * titleList = new HBList();
- HBTitle * title;
- for( int i = 0; i < dvdplay_title_nr( vmg ); i++ )
- {
- if( fDie )
- {
- break;
- }
-
- Log( "HBScanner: scanning title %d", i + 1 );
- fManager->Scanning( fDevice, i + 1 );
-
- title = new HBTitle( fDevice, i + 1 );
-
- if( ScanTitle( title, vmg ) )
- {
- titleList->AddItem( title );
- }
- else
- {
- Log( "HBScanner: ignoring title %d", i + 1 );
- delete title;
- }
- }
-
- Log( "HBScanner: closing device %s", fDevice );
- dvdplay_close( vmg );
-
- fManager->ScanDone( titleList );
-}
-
-bool HBScanner::ScanTitle( HBTitle * title, dvdplay_ptr vmg )
-{
- dvdplay_start( vmg, title->fIndex );
-
- /* Length */
- title->fLength = dvdplay_title_time( vmg );
- Log( "HBScanner::ScanTitle: title length is %lld seconds",
- title->fLength );
-
- /* Discard titles under 10 seconds */
- if( title->fLength < 10 )
- {
- return false;
- }
-
- /* Detect languages */
- int audio_nr, foo;
- dvdplay_audio_info( vmg, &audio_nr, &foo );
-
- audio_attr_t * attr;
- HBAudio * audio;
- for( int i = 0; i < audio_nr; i++ )
- {
- if( fDie )
- {
- break;
- }
-
- int id = dvdplay_audio_id( vmg, i );
-
- if( id < 1 )
- {
- continue;
- }
-
- if( ( id & 0xFF ) != 0xBD )
- {
- Log( "HBScanner::ScanTitle: non-AC3 audio track "
- "detected, ignoring" );
- continue;
- }
-
- /* Check if we don't already found an track with the same id */
- audio = NULL;
- for( uint32_t j = 0; j < title->fAudioList->CountItems(); j++ )
- {
- audio = (HBAudio*) title->fAudioList->ItemAt( j );
- if( (uint32_t) id == audio->fId )
- {
- break;
- }
- else
- {
- audio = NULL;
- }
- }
-
- if( audio )
- {
- Log( "HBScanner::ScanTitle: discarding duplicate track %x",
- id );
- continue;
- }
-
- attr = dvdplay_audio_attr( vmg, i );
- audio = new HBAudio( id, LanguageForCode( attr->lang_code ) );
- Log( "HBScanner::ScanTitle: new language (%x, %s)",
- id, audio->fDescription );
- title->fAudioList->AddItem( audio );
- }
-
- /* Discard titles with no audio tracks */
- if( !title->fAudioList->CountItems() )
- {
- return false;
- }
-
- /* Kludge : libdvdplay wants we to read a first block before seeking */
- uint8_t dummyBuf[DVD_VIDEO_LB_LEN];
- dvdplay_read( vmg, dummyBuf, 1 );
-
- for( int i = 0; i < 10; i++ )
- {
- if( fDie )
- {
- break;
- }
-
- if( !DecodeFrame( title, vmg, i ) )
- {
- return false;
- }
- }
-
- if( title->fInHeight * title->fAspect >
- title->fInWidth * VOUT_ASPECT_FACTOR )
- {
- title->fOutWidthMax = title->fInWidth;
- title->fOutHeightMax = MULTIPLE_16( (uint64_t)title->fInWidth *
- VOUT_ASPECT_FACTOR / title->fAspect );
- }
- else
- {
- title->fOutWidthMax = MULTIPLE_16( (uint64_t)title->fInHeight *
- title->fAspect / VOUT_ASPECT_FACTOR );
- title->fOutHeightMax = title->fInHeight;
- }
-
- /* Default picture size */
- title->fOutWidth = title->fOutWidthMax;
- title->fOutHeight = title->fOutHeightMax;
-
- return true;
-}
-bool HBScanner::DecodeFrame( HBTitle * title, dvdplay_ptr vmg, int i )
-{
- /* Seek to the right place */
- int titleFirst = dvdplay_title_first ( vmg );
- int titleEnd = dvdplay_title_end( vmg );
-
- dvdplay_seek( vmg, ( i + 1 ) * ( titleEnd - titleFirst ) / 11 ) ;
-
- /* Init libmpeg2 */
- mpeg2dec_t * handle = mpeg2_init();
- const mpeg2_info_t * info = mpeg2_info( handle );
- mpeg2_state_t state;
-
- /* Init the destination file */
- char fileName[1024];
- memset( fileName, 0, 1024 );
- sprintf( fileName, "/tmp/HB.%d.%x.%d", fManager->GetPid(),
- (uint32_t) title, i );
- FILE * file = fopen( fileName, "w" );
-
- HBList * esBufferList = NULL;
- HBBuffer * psBuffer = NULL;
- HBBuffer * esBuffer = NULL;
-
- for( ;; )
- {
- state = mpeg2_parse( handle );
-
- if( state == STATE_BUFFER )
- {
- /* Free the previous buffer */
- if( esBuffer )
- {
- delete esBuffer;
- esBuffer = NULL;
- }
-
- /* Get a new one */
- while( !esBuffer )
- {
- while( !esBufferList )
- {
- psBuffer = new HBBuffer( DVD_VIDEO_LB_LEN );
- if( dvdplay_read( vmg, psBuffer->fData, 1 ) != 1 ||
- !PStoES( psBuffer, &esBufferList ) )
- {
- Log( "HBScanner::DecodeFrame: failed to get "
- "a valid PS packet" );
- mpeg2_close( handle );
- fclose( file );
- return false;
- }
- }
-
- esBuffer = (HBBuffer*) esBufferList->ItemAt( 0 );
- esBufferList->RemoveItem( esBuffer );
- if( !esBufferList->CountItems() )
- {
- delete esBufferList;
- esBufferList = NULL;
- }
-
- if( esBuffer->fStreamId != 0xE0 )
- {
- delete esBuffer;
- esBuffer = NULL;
- }
- }
-
- /* Feed libmpeg2 */
- mpeg2_buffer( handle, esBuffer->fData,
- esBuffer->fData + esBuffer->fSize );
- }
- else if( state == STATE_SEQUENCE )
- {
- /* Get size & framerate info */
- title->fInWidth = info->sequence->width;
- title->fInHeight = info->sequence->height;
- title->fAspect = (uint64_t)info->sequence->display_width *
- info->sequence->pixel_width * VOUT_ASPECT_FACTOR /
- ( info->sequence->display_height *
- info->sequence->pixel_height );
- title->fRate = 27000000;
- title->fScale = info->sequence->frame_period;
- }
- else if( ( state == STATE_SLICE || state == STATE_END ) &&
- ( info->display_fbuf ) &&
- ( info->display_picture->flags & PIC_MASK_CODING_TYPE )
- == PIC_FLAG_CODING_TYPE_I )
- {
- /* Write the raw picture to a file */
- fwrite( info->display_fbuf->buf[0],
- title->fInWidth * title->fInHeight, 1, file );
- fwrite( info->display_fbuf->buf[1],
- title->fInWidth * title->fInHeight / 4, 1, file );
- fwrite( info->display_fbuf->buf[2],
- title->fInWidth * title->fInHeight / 4, 1, file );
- break;
- }
- else if( state == STATE_INVALID )
- {
- /* Reset libmpeg2 */
- mpeg2_close( handle );
- handle = mpeg2_init();
- }
- }
-
- mpeg2_close( handle );
-
- fclose( file );
-
- return true;
-}
diff --git a/core/Scanner.h b/core/Scanner.h
deleted file mode 100644
index dbdb587c4..000000000
--- a/core/Scanner.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* $Id: Scanner.h,v 1.5 2003/09/30 21:21:32 titer Exp $
-
- This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
- It may be used under the terms of the GNU General Public License. */
-
-#ifndef HB_SCANNER_H
-#define HB_SCANNER_H
-
-#include "Common.h"
-#include "Thread.h"
-
-class HBScanner : public HBThread
-{
- public:
- HBScanner( HBManager * manager, char * device );
-
- private:
- void DoWork();
- bool ScanTitle( HBTitle * title, dvdplay_ptr vmg );
- bool DecodeFrame( HBTitle * title, dvdplay_ptr vmg, int i );
-
- HBManager * fManager;
- char * fDevice;
-};
-
-#endif
diff --git a/core/Thread.c b/core/Thread.c
new file mode 100644
index 000000000..77caa0ee5
--- /dev/null
+++ b/core/Thread.c
@@ -0,0 +1,138 @@
+/* $Id: Thread.c,v 1.4 2003/11/06 15:51: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 "Thread.h"
+
+struct HBThread
+{
+ char * name;
+ int priority;
+ void (*function) ( void * );
+ void * arg;
+
+#if defined( SYS_BEOS )
+ int thread;
+#elif defined( SYS_MACOSX ) || defined( SYS_LINUX )
+ pthread_t thread;
+#elif defined( SYS_CYGWIN )
+ /* TODO */
+ int thread;
+#endif
+};
+
+#ifndef SYS_CYGWIN
+static void ThreadFunc( void * t );
+#endif
+
+HBThread * HBThreadInit( char * name, void (* function)(void *),
+ void * arg, int priority )
+{
+ HBThread * t;
+ if( !( t = malloc( sizeof( HBThread ) ) ) )
+ {
+ HBLog( "HBThreadInit: malloc() failed, gonna crash" );
+ return NULL;
+ }
+
+ t->name = strdup( name );
+ t->priority = priority;
+ t->function = function;
+ t->arg = arg;
+
+#if defined( SYS_BEOS )
+ t->thread = spawn_thread( (int32 (*)( void * )) ThreadFunc,
+ name, priority, t );
+ resume_thread( t->thread );
+#elif defined( SYS_MACOSX ) || defined( SYS_LINUX )
+ pthread_create( &t->thread, NULL,
+ (void * (*)( void * )) ThreadFunc, t );
+#elif defined( SYS_CYGWIN )
+ /* TODO */
+ t->thread = 0;
+#endif
+
+ HBLog( "HBThreadInit: thread %d started (\"%s\")",
+ t->thread, t->name );
+
+ return t;
+}
+
+#ifndef SYS_CYGWIN
+static void ThreadFunc( void * _t )
+{
+ HBThread * t = (HBThread*) _t;
+
+#if defined( SYS_MACOSX )
+ 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( "HBThreadInit: couldn't set thread priority" );
+ }
+#endif
+
+ t->function( t->arg );
+}
+#endif
+
+void HBThreadClose( HBThread ** _t )
+{
+ HBThread * t = *_t;
+
+#if defined( SYS_BEOS )
+ long exitValue;
+ wait_for_thread( t->thread, &exitValue );
+#elif defined( SYS_MACOSX ) || defined( SYS_LINUX )
+ pthread_join( t->thread, NULL );
+#elif defined( SYS_CYGWIN )
+ /* TODO */
+#endif
+
+ HBLog( "HBThreadClose: thread %d stopped (\"%s\")",
+ t->thread, t->name );
+
+ free( t->name );
+ free( t );
+ *_t = NULL;
+}
+
+HBLock * HBLockInit()
+{
+ HBLock * l;
+ if( !( l = malloc( sizeof( HBLock ) ) ) )
+ {
+ HBLog( "HBLockInit: malloc() failed, gonna crash" );
+ return NULL;
+ }
+
+#if defined( SYS_BEOS )
+ l->sem = create_sem( 1, "sem" );
+#elif defined( SYS_MACOSX ) || defined( SYS_LINUX )
+ pthread_mutex_init( &l->mutex, NULL );
+#elif defined( SYS_CYGWIN )
+ /* TODO */
+#endif
+
+ return l;
+}
+
+void HBLockClose( HBLock ** _l )
+{
+ HBLock * l = *_l;
+
+#if defined( SYS_BEOS )
+ delete_sem( l->sem );
+#elif defined( SYS_MACOSX ) || defined( SYS_LINUX )
+ pthread_mutex_destroy( &l->mutex );
+#elif defined( SYS_CYGWIN )
+ /* TODO */
+#endif
+ free( l );
+
+ *_l = NULL;
+}
+
diff --git a/core/Thread.cpp b/core/Thread.cpp
deleted file mode 100644
index c52f7506a..000000000
--- a/core/Thread.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-/* $Id: Thread.cpp,v 1.24 2003/10/14 14:35:20 titer Exp $
-
- This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
- It may be used under the terms of the GNU General Public License. */
-
-#if defined( SYS_BEOS )
-# include <OS.h>
-# include <Locker.h>
-#elif defined( SYS_MACOSX ) || defined( SYS_LINUX )
-# include <pthread.h>
-#endif
-
-#include "Thread.h"
-#include "Fifo.h"
-
-HBThread::HBThread( char * name, int priority )
-{
- fName = strdup( name );
- fPriority = priority;
- fDie = false;
- fSuspend = false;
-}
-
-HBThread::~HBThread()
-{
- fDie = true;
- fSuspend = false;
-
-#if defined( SYS_BEOS )
- long exit_value;
- wait_for_thread( fThread, &exit_value );
-#elif defined( SYS_MACOSX ) || defined( SYS_LINUX )
- pthread_join( fThread, NULL );
-#endif
-
- Log( "HBThread: thread %d stopped (\"%s\")", fThread, fName );
- free( fName );
-}
-
-void HBThread::Suspend()
-{
- fSuspend = true;
-}
-
-void HBThread::Resume()
-{
- fSuspend = false;
-}
-
-int HBThread::GetPid()
-{
- return fPid;
-}
-
-void HBThread::Run()
-{
-#if defined( SYS_BEOS )
- fThread = spawn_thread( (int32 (*)(void *)) ThreadFunc,
- fName, fPriority, this );
- resume_thread( fThread );
-#elif defined( SYS_MACOSX ) || defined( SYS_LINUX )
- pthread_create( &fThread, NULL,
- (void * (*)(void *)) ThreadFunc, this );
-#endif
-
- Log( "HBThread: thread %d started (\"%s\")",
- fThread, fName );
-}
-
-bool HBThread::Push( HBFifo * fifo, HBBuffer * buffer )
-{
- while( !fDie )
- {
- if( fifo->Push( buffer ) )
- {
- return true;
- }
-
- Snooze( 10000 );
- }
-
- delete buffer;
- return false;
-}
-
-HBBuffer * HBThread::Pop( HBFifo * fifo )
-{
- HBBuffer * buffer;
-
- while( !fDie )
- {
- if( ( buffer = fifo->Pop() ) )
- {
- return buffer;
- }
-
- Snooze( 10000 );
- }
-
- return NULL;
-}
-
-void HBThread::ThreadFunc( HBThread * _this )
-{
-#if defined( SYS_MACOSX )
- struct sched_param param;
- memset( &param, 0, sizeof( struct sched_param ) );
- param.sched_priority = _this->fPriority;
- if ( pthread_setschedparam( pthread_self(), SCHED_OTHER, &param ) )
- {
- Log( "HBThread: couldn't set thread priority" );
- }
-#endif
-
- _this->fPid = (int) getpid();
-
- _this->DoWork();
-}
-
-void HBThread::DoWork()
-{
-}
-
-
-HBLock::HBLock()
-{
-#if defined( SYS_BEOS )
- fLocker = new BLocker();
-#elif defined( SYS_MACOSX ) || defined( SYS_LINUX )
- pthread_mutex_init( &fMutex, NULL );
-#endif
-}
-
-HBLock::~HBLock()
-{
-#if defined( SYS_BEOS )
- delete fLocker;
-#elif defined( SYS_MACOSX ) || defined( SYS_LINUX )
- pthread_mutex_destroy( &fMutex );
-#endif
-}
-
-void HBLock::Lock()
-{
-#if defined( SYS_BEOS )
- fLocker->Lock();
-#elif defined( SYS_MACOSX ) || defined( SYS_LINUX )
- pthread_mutex_lock( &fMutex );
-#endif
-}
-
-void HBLock::Unlock()
-{
-#if defined( SYS_BEOS )
- fLocker->Unlock();
-#elif defined( SYS_MACOSX ) || defined( SYS_LINUX )
- pthread_mutex_unlock( &fMutex );
-#endif
-}
diff --git a/core/Thread.h b/core/Thread.h
index 0a09fabc9..58700aae1 100644
--- a/core/Thread.h
+++ b/core/Thread.h
@@ -1,13 +1,19 @@
-/* $Id: Thread.h,v 1.19 2003/10/09 16:03:51 titer Exp $
+/* $Id: Thread.h,v 1.3 2003/11/06 15:51:36 titer Exp $
This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
+ 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
-#include "Common.h"
+#if defined( SYS_BEOS )
+# include <OS.h>
+#elif defined( SYS_MACOSX ) || defined( SYS_LINUX )
+# include <pthread.h>
+#endif
+
+#include "Utils.h"
#if defined( SYS_BEOS )
# define HB_LOW_PRIORITY 5
@@ -15,63 +21,52 @@
#elif defined( SYS_MACOSX )
# define HB_LOW_PRIORITY 0
# define HB_NORMAL_PRIORITY 31
-#elif defined( SYS_LINUX )
+#elif defined( SYS_LINUX ) || defined( SYS_CYGWIN )
/* Actually unused */
# define HB_LOW_PRIORITY 0
# define HB_NORMAL_PRIORITY 0
#endif
-class HBThread
-{
- public:
- HBThread( char * name,
- int priority = HB_LOW_PRIORITY );
- virtual ~HBThread();
- void Suspend();
- void Resume();
- int GetPid();
-
- protected:
- void Run();
- bool Push( HBFifo * fifo, HBBuffer * buffer );
- HBBuffer * Pop( HBFifo * fifo );
-
- volatile bool fDie;
- volatile bool fSuspend;
-
- private:
- static void ThreadFunc( HBThread * _this );
- virtual void DoWork();
-
- char * fName;
- int fPriority;
+HBThread * HBThreadInit( char * name, void (* function)(void *),
+ void * arg, int priority );
+void HBThreadClose( HBThread ** );
+struct HBLock
+{
#if defined( SYS_BEOS )
- int fThread;
+ sem_id sem;
#elif defined( SYS_MACOSX ) || defined( SYS_LINUX )
- pthread_t fThread;
+ pthread_mutex_t mutex;
+#elif defined( SYS_CYGWIN )
+ /* TODO */
#endif
- int fPid;
};
+HBLock * HBLockInit();
+static inline void HBLockLock( HBLock * );
+static inline void HBLockUnlock( HBLock * );
+void HBLockClose( HBLock ** );
+
+static inline void HBLockLock( HBLock * l )
+{
#if defined( SYS_BEOS )
-class BLocker;
+ acquire_sem( l->sem );
+#elif defined( SYS_MACOSX ) || defined( SYS_LINUX )
+ pthread_mutex_lock( &l->mutex );
+#elif defined( SYS_CYGWIN )
+ /* TODO */
#endif
+}
-class HBLock
+static inline void HBLockUnlock( HBLock * l )
{
- public:
- HBLock();
- ~HBLock();
- void Lock();
- void Unlock();
-
- private:
#if defined( SYS_BEOS )
- BLocker * fLocker;
+ release_sem( l->sem );
#elif defined( SYS_MACOSX ) || defined( SYS_LINUX )
- pthread_mutex_t fMutex;
+ pthread_mutex_unlock( &l->mutex );
+#elif defined( SYS_CYGWIN )
+ /* TODO */
#endif
-};
+}
#endif
diff --git a/core/Utils.c b/core/Utils.c
new file mode 100644
index 000000000..5f35ec3ae
--- /dev/null
+++ b/core/Utils.c
@@ -0,0 +1,352 @@
+/* $Id: Utils.c,v 1.6 2003/11/06 15:51: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 <stdarg.h>
+#include <time.h>
+#include <sys/time.h>
+
+#include "Utils.h"
+#include "Fifo.h"
+
+struct HBList
+{
+ void ** items;
+ int allocItems;
+ int nbItems;
+};
+
+void HBSnooze( int time )
+{
+#if defined( SYS_BEOS )
+ snooze( time );
+#elif defined( SYS_MACOSX ) || defined( SYS_LINUX )
+ usleep( time );
+#elif defined( SYS_CYGWIN )
+ /* TODO */
+#endif
+}
+
+void HBLog( char * log, ... )
+{
+ char string[81];
+ time_t _now;
+ struct tm * now;
+ va_list args;
+ int ret;
+
+ 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 );
+ ret = vsnprintf( string + 11, 68, log, args );
+ va_end( args );
+
+ /* Add the end of line */
+ string[ret+11] = '\n';
+ string[ret+12] = '\0';
+
+ /* Print it */
+ fprintf( stderr, "%s", string );
+}
+
+uint64_t HBGetDate()
+{
+#ifndef SYS_CYGWIN
+ struct timeval tv;
+ gettimeofday( &tv, NULL );
+ return( (uint64_t) tv.tv_sec * 1000000 + (uint64_t) tv.tv_usec );
+#else
+ return 0;
+#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] << 24, d[pos+1] << 16,
+ d[pos+2] << 8, 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 )
+ {
+ uint32_t streamId;
+ uint32_t PES_packet_length;
+ uint32_t PES_packet_end;
+ uint32_t PES_header_d_length;
+ uint32_t 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 )
+ {
+ /* 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 )
+ {
+ /* A52: don't ask */
+ streamId |= ( d[pos] << 8 );
+ pos += 4;
+ }
+
+ /* Sanity check */
+ if( pos >= PES_packet_end )
+ {
+ HBLog( "HBPStoES: 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;
+ }
+
+ 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 HBListCountItems( 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 = calloc( sizeof( HBTitle ), 1 );
+
+ t->device = strdup( device );
+ t->index = index;
+
+ t->codec = HB_CODEC_FFMPEG;
+ t->bitrate = 1024;
+
+ t->audioList = HBListInit();
+
+ 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 );
+
+ if( t->file ) free( t->file );
+ free( t->device );
+ free( t );
+
+ *_t = NULL;
+}
+
+HBAudio * HBAudioInit( int id, char * language )
+{
+ HBAudio * a;
+ if( !( a = malloc( sizeof( HBAudio ) ) ) )
+ {
+ HBLog( "HBAudioInit: malloc() failed, gonna crash" );
+ return NULL;
+ }
+
+ a->id = id;
+ a->language = strdup( language );
+ a->inSampleRate = 0;
+ a->outSampleRate = 44100;
+ a->delay = 0;
+ a->ac3Fifo = NULL;
+ a->rawFifo = NULL;
+ a->mp3Fifo = NULL;
+ a->ac3Dec = NULL;
+ a->mp3Enc = NULL;
+
+ return a;
+}
+
+void HBAudioClose( HBAudio ** _a )
+{
+ HBAudio * a = *_a;
+
+ free( a->language );
+ free( a );
+
+ *_a = NULL;
+}
+
diff --git a/core/Utils.h b/core/Utils.h
new file mode 100644
index 000000000..ba1a9101e
--- /dev/null
+++ b/core/Utils.h
@@ -0,0 +1,213 @@
+/* $Id: Utils.h,v 1.6 2003/11/07 21:22:17 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 SYS_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 HBAc3Dec HBAc3Dec;
+typedef struct HBAudio HBAudio;
+typedef struct HBAviMux HBAviMux;
+typedef struct HBBuffer HBBuffer;
+typedef struct HBDVDRead HBDVDRead;
+typedef struct HBFifo HBFifo;
+typedef struct HBList HBList;
+typedef struct HBLock HBLock;
+typedef struct HBHandle HBHandle;
+typedef struct HBMp3Enc HBMp3Enc;
+typedef struct HBMpeg2Dec HBMpeg2Dec;
+typedef struct HBFfmpegEnc HBFfmpegEnc;
+typedef struct HBMadDec HBMadDec;
+typedef struct HBScale HBScale;
+typedef struct HBScan HBScan;
+typedef struct HBStatus HBStatus;
+typedef struct HBThread HBThread;
+typedef struct HBTitle HBTitle;
+typedef struct HBWork HBWork;
+typedef struct HBWorkThread HBWorkThread;
+typedef struct HBXvidEnc HBXvidEnc;
+
+/* 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 HBListCountItems( 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 );
+void HBAudioClose( HBAudio ** );
+
+/* Possible states */
+typedef enum
+{
+ HB_MODE_UNDEF = 00000,
+ HB_MODE_NEED_DEVICE = 00001,
+ HB_MODE_SCANNING = 00002,
+ HB_MODE_INVALID_DEVICE = 00004,
+ HB_MODE_READY_TO_RIP = 00010,
+ HB_MODE_ENCODING = 00020,
+ HB_MODE_PAUSED = 00040,
+ HB_MODE_STOPPING = 00100,
+ HB_MODE_DONE = 00200,
+ HB_MODE_CANCELED = 00400,
+ HB_MODE_ERROR = 01000,
+ HB_MODE_EXITING = 02000
+} HBMode;
+
+/* Possible errors */
+typedef enum
+{
+ HB_ERROR_A52_SYNC = 0,
+ HB_ERROR_AVI_WRITE,
+ HB_ERROR_DVD_OPEN,
+ HB_ERROR_DVD_READ,
+ HB_ERROR_MP3_INIT,
+ HB_ERROR_MP3_ENCODE,
+ HB_ERROR_MPEG4_INIT
+} HBError;
+
+/* Possible codecs */
+typedef enum
+{
+ HB_CODEC_FFMPEG = 0,
+ HB_CODEC_XVID
+} HBCodec;
+
+struct HBStatus
+{
+ HBMode mode;
+
+ /* HB_MODE_SCANNING */
+ int scannedTitle;
+
+ /* HB_MODE_SCANDONE */
+ HBList * titleList;
+
+ /* HB_MODE_ENCODING || HB_MODE_PAUSED */
+ float position;
+ int pass;
+ int passCount;
+ float frameRate;
+ float avFrameRate;
+ uint32_t remainingTime; /* in seconds */
+
+ /* HB_MODE_ERROR */
+ HBError error;
+};
+
+struct HBTitle
+{
+ char * device;
+ int index;
+ int length;
+ char * file;
+
+ /* 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;
+ HBCodec codec;
+ int bitrate;
+ int twoPass;
+
+ /* Audio infos */
+ HBList * audioList;
+
+ /* Fifos */
+ HBFifo * mpeg2Fifo;
+ HBFifo * rawFifo;
+ HBFifo * scaledFifo;
+ HBFifo * mpeg4Fifo;
+
+ /* Threads */
+ HBDVDRead * dvdRead;
+ HBMpeg2Dec * mpeg2Dec;
+ HBScale * scale;
+ HBFfmpegEnc * ffmpegEnc;
+ HBXvidEnc * xvidEnc;
+ HBAviMux * aviMux;
+ HBWorkThread * workThreads[8];
+};
+
+struct HBAudio
+{
+ /* Ident */
+ uint32_t id;
+ char * language;
+
+ /* Settings */
+ int inSampleRate;
+ int outSampleRate;
+ int inBitrate;
+ int outBitrate;
+
+ int delay; /* in ms */
+
+ /* Fifos */
+ HBFifo * ac3Fifo;
+ HBFifo * rawFifo;
+ HBFifo * mp3Fifo;
+
+ /* Threads */
+ HBAc3Dec * ac3Dec;
+ HBMp3Enc * mp3Enc;
+};
+
+
+
+#endif
diff --git a/core/Work.c b/core/Work.c
new file mode 100644
index 000000000..b15e50839
--- /dev/null
+++ b/core/Work.c
@@ -0,0 +1,187 @@
+/* $Id: Work.c,v 1.4 2003/11/06 12:33:11 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"
+#include "Work.h"
+
+/* Local prototypes */
+static void WorkThread( void * t );
+
+struct HBWork
+{
+ HB_WORK_COMMON_MEMBERS
+};
+
+struct HBWorkThread
+{
+ HBHandle * handle;
+
+ HBList * workList;
+ int firstThread;
+
+ int die;
+ HBThread * thread;
+};
+
+HBWorkThread * HBWorkThreadInit( HBHandle * handle, HBTitle * title,
+ HBAudio * audio, HBAudio * optAudio,
+ int firstThread )
+{
+ int i;
+ HBWork * w;
+
+ 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 do */
+ t->workList = HBListInit();
+ HBListAdd( t->workList, title->mpeg2Dec );
+ HBListAdd( t->workList, title->scale );
+
+ if( title->codec == HB_CODEC_FFMPEG )
+ HBListAdd( t->workList, title->ffmpegEnc );
+ else if( title->codec == HB_CODEC_XVID )
+ HBListAdd( t->workList, title->xvidEnc );
+
+ HBListAdd( t->workList, audio->ac3Dec );
+ HBListAdd( t->workList, audio->mp3Enc );
+ if( optAudio )
+ {
+ HBListAdd( t->workList, optAudio->ac3Dec );
+ HBListAdd( t->workList, optAudio->mp3Enc );
+ }
+
+ 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 < HBListCountItems( 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 < HBListCountItems( t->workList ); i++ )
+ {
+ w = (HBWork*) HBListItemAt( t->workList, i );
+ HBLockClose( &w->lock );
+ total += w->time;
+ }
+
+ for( i = 0; i < HBListCountItems( t->workList ); i++ )
+ {
+ w = (HBWork*) HBListItemAt( t->workList, i );
+ HBLog( "HBWorkThreadClose: %- 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;
+
+ for( ;; )
+ {
+ HBCheckPaused( t->handle );
+
+ didSomething = 0;
+
+ for( i = 0; i < HBListCountItems( t->workList ); i++ )
+ {
+ if( t->die )
+ {
+ break;
+ }
+
+ w = (HBWork*) HBListItemAt( t->workList, i );
+
+ /* Check if another thread isn't using this work object.
+ If not, lock it */
+ HBLockLock( w->lock );
+ if( w->used )
+ {
+ HBLockUnlock( w->lock );
+ continue;
+ }
+ w->used = 1;
+ HBLockUnlock( w->lock );
+
+ /* Actually do the job */
+ date = HBGetDate();
+ if( w->work( w ) )
+ {
+ w->time += HBGetDate() - date;
+ didSomething = 1;
+ }
+
+ /* Unlock */
+ HBLockLock( w->lock );
+ w->used = 0;
+ HBLockUnlock( w->lock );
+ }
+
+ if( t->die )
+ {
+ break;
+ }
+
+ /* If nothing could be done, wait a bit to prevent a useless
+ CPU-consuming loop */
+ if( !didSomething )
+ {
+ HBSnooze( 10000 );
+ }
+ }
+}
+
diff --git a/core/Work.h b/core/Work.h
new file mode 100644
index 000000000..8d3cfba15
--- /dev/null
+++ b/core/Work.h
@@ -0,0 +1,27 @@
+/* $Id: Work.h,v 1.1 2003/11/03 12:08: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. */
+
+#ifndef HB_WORK_H
+#define HB_WORK_H
+
+#include "HandBrakeInternal.h"
+
+#define HB_WORK_COMMON_MEMBERS \
+ char * name; \
+ HBLock * lock; \
+ int used; \
+ uint64_t time; \
+ int (*work) ( HBWork * );
+
+void HBWorkLock( HBWork * );
+void HBWorkWork( HBWork * );
+void HBWorkUnlock( HBWork * );
+
+HBWorkThread * HBWorkThreadInit( HBHandle *, HBTitle *, HBAudio *,
+ HBAudio *, int firstThread );
+void HBWorkThreadClose( HBWorkThread ** );
+
+#endif
diff --git a/core/Worker.cpp b/core/Worker.cpp
deleted file mode 100644
index 4310e46f4..000000000
--- a/core/Worker.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-/* $Id: Worker.cpp,v 1.11 2003/10/16 13:36:17 titer Exp $
-
- This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
- It may be used under the terms of the GNU General Public License. */
-
-#include "Ac3Decoder.h"
-#include "Mp3Encoder.h"
-#include "Mpeg2Decoder.h"
-#include "Mpeg4Encoder.h"
-#include "MpegDemux.h"
-#include "Resizer.h"
-#include "Worker.h"
-
-HBWorker::HBWorker( HBTitle * title, HBAudio * audio1,
- HBAudio * audio2 )
- : HBThread( "worker")
-{
- fTitle = title;
- fAudio1 = audio1;
- fAudio2 = audio2;
-
- Run();
-}
-
-void HBWorker::DoWork()
-{
- bool didSomething;
- uint64_t mpegDemux = 0;
- uint64_t mpeg2Decoder = 0;
- uint64_t resizer = 0;
- uint64_t mpeg4Encoder = 0;
- uint64_t ac3Decoder1 = 0;
- uint64_t mp3Encoder1 = 0;
- uint64_t ac3Decoder2 = 0;
- uint64_t mp3Encoder2 = 0;
- uint64_t tmpDate;
-
- for( ;; )
- {
- while( fSuspend )
- {
- Snooze( 10000 );
- }
-
- didSomething = false;
-
- tmpDate = GetDate();
- if( fTitle->fMpegDemux->Work() )
- {
- mpegDemux += ( GetDate() - tmpDate );
- didSomething = true;
- }
-
- if( fDie ) break;
-
- tmpDate = GetDate();
- if( fTitle->fMpeg2Decoder->Work() )
- {
- mpeg2Decoder += ( GetDate() - tmpDate );
- didSomething = true;
- }
-
- if( fDie ) break;
-
- tmpDate = GetDate();
- if( fTitle->fResizer->Work() )
- {
- resizer += ( GetDate() - tmpDate );
- didSomething = true;
- }
-
- if( fDie ) break;
-
- tmpDate = GetDate();
- if( fTitle->fMpeg4Encoder->Work() )
- {
- mpeg4Encoder += ( GetDate() - tmpDate );
- didSomething = true;
- }
-
- if( fDie ) break;
-
- if( fAudio1 )
- {
- tmpDate = GetDate();
- if( fAudio1->fAc3Decoder->Work() )
- {
- ac3Decoder1 += ( GetDate() - tmpDate );
- didSomething = true;
- }
-
- if( fDie ) break;
-
- tmpDate = GetDate();
- if( fAudio1->fMp3Encoder->Work() )
- {
- mp3Encoder1 += ( GetDate() - tmpDate );
- didSomething = true;
- }
-
- if( fDie ) break;
- }
-
- if( fAudio2 )
- {
- tmpDate = GetDate();
- if( fAudio2->fAc3Decoder->Work() )
- {
- ac3Decoder2 += ( GetDate() - tmpDate );
- didSomething = true;
- }
-
- if( fDie ) break;
-
- tmpDate = GetDate();
- if( fAudio2->fMp3Encoder->Work() )
- {
- mp3Encoder2 += ( GetDate() - tmpDate );
- didSomething = true;
- }
-
- if( fDie ) break;
- }
-
- if( !didSomething )
- {
- Snooze( 10000 );
- }
- }
-
- tmpDate = mpegDemux + mpeg2Decoder + resizer + mpeg4Encoder +
- ac3Decoder1 + mp3Encoder1 + ac3Decoder2 + mp3Encoder2;
- Log( "HBWorker stopped. CPU utilization:" );
- Log( "- MPEG demuxer: %.2f %%", 100.0 * mpegDemux / tmpDate );
- Log( "- MPEG-2 decoder: %.2f %%", 100.0 * mpeg2Decoder / tmpDate );
- Log( "- Resizer: %.2f %%", 100.0 * resizer / tmpDate );
- Log( "- MPEG-4 encoder: %.2f %%", 100.0 * mpeg4Encoder / tmpDate );
- if( fAudio1 )
- {
- Log( "- AC3 decoder 1: %.2f %%", 100.0 * ac3Decoder1 / tmpDate );
- Log( "- MP3 encoder 1: %.2f %%", 100.0 * mp3Encoder1 / tmpDate );
- }
- if( fAudio2 )
- {
- Log( "- AC3 decoder 2: %.2f %%", 100.0 * ac3Decoder2 / tmpDate );
- Log( "- MP3 encoder 2: %.2f %%", 100.0 * mp3Encoder2 / tmpDate );
- }
-}
-
diff --git a/core/Worker.h b/core/Worker.h
deleted file mode 100644
index 5df8f648b..000000000
--- a/core/Worker.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* $Id: Worker.h,v 1.3 2003/10/16 13:36:17 titer Exp $
-
- This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
- It may be used under the terms of the GNU General Public License. */
-
-#ifndef HB_WORKER_H
-#define HB_WORKER_H
-
-#include "Common.h"
-#include "Thread.h"
-
-class HBWorker : public HBThread
-{
- public:
- HBWorker( HBTitle * title, HBAudio * audio1,
- HBAudio * audio2 );
- void WaitUntilDone();
-
- private:
- void DoWork();
-
- HBTitle * fTitle;
- HBAudio * fAudio1;
- HBAudio * fAudio2;
-};
-
-#endif
diff --git a/core/XvidEnc.c b/core/XvidEnc.c
new file mode 100644
index 000000000..8f16ad4ba
--- /dev/null
+++ b/core/XvidEnc.c
@@ -0,0 +1,170 @@
+/* $Id: XvidEnc.c,v 1.5 2003/11/05 19:14:37 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 "XvidEnc.h"
+#include "Fifo.h"
+#include "Work.h"
+
+#include <xvid.h>
+
+/* Local prototypes */
+static int XvidEncWork( HBWork * );
+
+struct HBXvidEnc
+{
+ HB_WORK_COMMON_MEMBERS
+
+ HBHandle * handle;
+ HBTitle * title;
+
+ void * xvid;
+ HBBuffer * mpeg4Buffer;
+ int pass;
+};
+
+HBXvidEnc * HBXvidEncInit( HBHandle * handle, HBTitle * title )
+{
+ HBXvidEnc * x;
+ if( !( x = malloc( sizeof( HBXvidEnc ) ) ) )
+ {
+ HBLog( "HBXvidEncInit: malloc() failed, gonna crash" );
+ return NULL;
+ }
+
+ x->name = strdup( "XvidEnc" );
+ x->work = XvidEncWork;
+
+ x->handle = handle;
+ x->title = title;
+
+ x->xvid = NULL;
+ x->mpeg4Buffer = NULL;
+ x->pass = 42;
+
+ return x;
+}
+
+void HBXvidEncClose( HBXvidEnc ** _x )
+{
+ HBXvidEnc * x = *_x;
+ free( x );
+ *_x = NULL;
+}
+
+static int XvidEncWork( HBWork * w )
+{
+ HBXvidEnc * x = (HBXvidEnc*) w;
+ HBTitle * title = x->title;
+ HBBuffer * scaledBuffer;
+ HBBuffer * mpeg4Buffer;
+ XVID_ENC_FRAME xframe;
+
+ int didSomething = 0;
+
+ if( x->mpeg4Buffer )
+ {
+ if( HBFifoPush( title->mpeg4Fifo, &x->mpeg4Buffer ) )
+ {
+ didSomething = 1;
+ }
+ else
+ {
+ return didSomething;
+ }
+ }
+
+ if( ( scaledBuffer = HBFifoPop( title->scaledFifo ) ) )
+ {
+ didSomething = 1;
+ }
+ else
+ {
+ return didSomething;
+ }
+
+ /* Init or re-init if needed */
+ if( scaledBuffer->pass != x->pass )
+ {
+ XVID_INIT_PARAM xinit;
+ XVID_ENC_PARAM xparam;
+
+ x->pass = scaledBuffer->pass;;
+
+ HBLog( "HBXvidEnc: opening libxvidcore (pass %d)", x->pass );
+
+ xinit.cpu_flags = 0;
+ xvid_init( NULL, 0, &xinit, NULL );
+
+ xparam.width = title->outWidth;
+ xparam.height = title->outHeight;
+
+ xparam.fincr = title->rateBase;
+ xparam.fbase = title->rate;
+
+ xparam.rc_bitrate = title->bitrate * 1000;
+
+ /* Default values should be ok */
+ xparam.rc_reaction_delay_factor = -1;
+ xparam.rc_averaging_period = -1;
+ xparam.rc_buffer = -1;
+ xparam.max_quantizer = -1;
+ xparam.min_quantizer = -1;
+ xparam.max_key_interval = -1;
+
+ if( xvid_encore( NULL, XVID_ENC_CREATE, &xparam, NULL ) )
+ {
+ HBLog( "HBXvidEnc: xvid_encore() failed" );
+ }
+
+ x->xvid = xparam.handle;
+ }
+
+ /* TODO implement 2-pass encoding */
+ if( x->pass == 1 )
+ {
+ HBPosition( x->handle, scaledBuffer->position );
+ HBBufferClose( &scaledBuffer );
+ return didSomething;
+ }
+
+ mpeg4Buffer = HBBufferInit( title->outWidth *
+ title->outHeight * 3 / 2 );
+ mpeg4Buffer->position = scaledBuffer->position;
+
+ xframe.general = XVID_H263QUANT | XVID_HALFPEL | XVID_INTER4V;
+ xframe.motion = PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 |
+ PMV_EXTSEARCH16 | PMV_EARLYSTOP8 |
+ PMV_HALFPELREFINE8 | PMV_HALFPELDIAMOND8 |
+ PMV_USESQUARES16;
+ xframe.bitstream = mpeg4Buffer->data;
+
+ xframe.image = scaledBuffer->data;
+ xframe.colorspace = XVID_CSP_I420;
+
+ xframe.quant_intra_matrix = NULL;
+ xframe.quant_inter_matrix = NULL;
+ xframe.quant = 0;
+ xframe.intra = -1;
+
+ xframe.hint.hintstream = NULL;
+
+ if( xvid_encore( x->xvid, XVID_ENC_ENCODE, &xframe, NULL ) )
+ {
+ HBLog( "HBXvidEnc: xvid_encore() failed" );
+ }
+
+ mpeg4Buffer->size = xframe.length;
+ mpeg4Buffer->keyFrame = xframe.intra;
+
+ /* Inform the GUI about the current position */
+ HBPosition( x->handle, scaledBuffer->position );
+
+ HBBufferClose( &scaledBuffer );
+ x->mpeg4Buffer = mpeg4Buffer;
+
+ return didSomething;
+}
+
diff --git a/core/XvidEnc.h b/core/XvidEnc.h
new file mode 100644
index 000000000..01cb6f4d4
--- /dev/null
+++ b/core/XvidEnc.h
@@ -0,0 +1,15 @@
+/* $Id: XvidEnc.h,v 1.1 2003/11/03 12:08: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. */
+
+#ifndef HB_XVID_ENC_H
+#define HB_XVID_ENC_H
+
+#include "HandBrakeInternal.h"
+
+HBXvidEnc * HBXvidEncInit( HBHandle *, HBTitle * );
+void HBXvidEncClose( HBXvidEnc ** );
+
+#endif
diff --git a/macosx/Controller.h b/macosx/Controller.h
index 4759a1d5b..469994c68 100644
--- a/macosx/Controller.h
+++ b/macosx/Controller.h
@@ -1,12 +1,12 @@
-/* $Id: Controller.h,v 1.6 2003/10/13 23:09:56 titer Exp $
+/* $Id: Controller.h,v 1.4 2003/11/07 21:22:17 titer Exp $
This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
+ Homepage: <http://handbrake.m0k.org/>.
It may be used under the terms of the GNU General Public License. */
#include <Cocoa/Cocoa.h>
-#include "Common.h"
+#include "HandBrake.h"
#include "PictureGLView.h"
#include "TargetSizeField.h"
@@ -18,7 +18,6 @@
IBOutlet NSWindow * fWindow;
/* Scan view */
- uint64_t fLastDVDDetection;
IBOutlet NSView * fScanView;
IBOutlet NSMatrix * fScanMatrix;
IBOutlet NSPopUpButton * fDVDPopUp;
@@ -63,7 +62,7 @@
/* "Done" alert panel */
IBOutlet NSPanel * fDonePanel;
- /* Crop & resize panel */
+ /* Crop & scale panel */
IBOutlet NSPanel * fPicturePanel;
IBOutlet HBPictureGLView * fPictureGLView;
IBOutlet NSTextField * fWidthField;
@@ -78,9 +77,12 @@
IBOutlet NSTextField * fRightField;
IBOutlet NSStepper * fRightStepper;
IBOutlet NSTextField * fInfoField;
+ IBOutlet NSButton * fOpenGLCheck;
+ IBOutlet NSButton * fPreviousButton;
+ IBOutlet NSButton * fNextButton;
int fPicture;
- HBManager * fManager;
+ HBHandle * fHandle;
HBList * fTitleList;
}
@@ -91,6 +93,7 @@
- (IBAction) Scan: (id) sender;
- (IBAction) TitlePopUpChanged: (id) sender;
+- (IBAction) VideoCodecPopUpChanged: (id) sender;
- (IBAction) VideoMatrixChanged: (id) sender;
- (IBAction) AudioPopUpChanged: (id) sender;
- (IBAction) BrowseFile: (id) sender;
@@ -111,6 +114,6 @@
- (IBAction) UpdatePicture: (id) sender;
- (void) UpdateIntf: (NSTimer *) timer;
-- (void) DetectDrives;
+- (void) DetectDrives: (NSNotification *) notification;
@end
diff --git a/macosx/Controller.mm b/macosx/Controller.mm
index 402d721fa..a345bdec1 100644
--- a/macosx/Controller.mm
+++ b/macosx/Controller.mm
@@ -1,7 +1,7 @@
-/* $Id: Controller.mm,v 1.10 2003/10/13 23:09:56 titer Exp $
+/* $Id: Controller.mm,v 1.7 2003/11/07 21:22:17 titer Exp $
This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
+ Homepage: <http://handbrake.m0k.org/>.
It may be used under the terms of the GNU General Public License. */
#include <paths.h>
@@ -11,20 +11,25 @@
#include <IOKit/storage/IODVDMedia.h>
#include "Controller.h"
-#include "Manager.h"
@implementation HBController
- (void) applicationDidFinishLaunching: (NSNotification *) notification
{
/* Init libhb */
- fManager = new HBManager( true );
+ fHandle = HBInit( 1, 0 );
+ [fPictureGLView SetHandle: fHandle];
/* Update the GUI every 1/10 sec */
fDie = false;
[NSTimer scheduledTimerWithTimeInterval: 0.1
target: self selector: @selector( UpdateIntf: )
userInfo: nil repeats: YES];
+
+ /* Detect drives mounted after the app is started */
+ [[[NSWorkspace sharedWorkspace] notificationCenter]
+ addObserver: self selector: @selector( DetectDrives: )
+ name: NSWorkspaceDidMountNotification object: nil];
}
- (NSApplicationTerminateReply) applicationShouldTerminate:
@@ -32,7 +37,7 @@
{
/* Clean up */
fDie = true;
- delete fManager;
+ HBClose( &fHandle );
return NSTerminateNow;
}
@@ -42,6 +47,10 @@
[fDVDPopUp removeAllItems];
[fScanProgress setStyle: NSProgressIndicatorSpinningStyle];
[fScanProgress setDisplayedWhenStopped: NO];
+ [fVideoCodecPopUp removeAllItems];
+ [fVideoCodecPopUp addItemWithTitle: @"MPEG-4 (Ffmpeg)"];
+ [fVideoCodecPopUp addItemWithTitle: @"MPEG-4 (XviD)"];
+ [fVideoCodecPopUp selectItemWithTitle: @"MPEG-4 (Ffmpeg)"];
[fAudioBitratePopUp removeAllItems];
[fAudioBitratePopUp addItemWithTitle: @"32"];
[fAudioBitratePopUp addItemWithTitle: @"64"];
@@ -65,8 +74,7 @@
[fWindow center];
/* Detect DVD drives */
- fLastDVDDetection = GetDate();
- [self DetectDrives];
+ [self DetectDrives: nil];
[self ScanMatrixChanged: self];
}
@@ -139,76 +147,82 @@
- (IBAction) Scan: (id) sender
{
- /* Ask the manager to start scanning the specified volume */
+ /* Ask libhb to start scanning the specified volume */
if( ![fScanMatrix selectedRow] )
{
/* DVD drive */
- fManager->ScanVolumes( (char*) [[fDVDPopUp titleOfSelectedItem]
- cString] );
+ HBScanDevice( fHandle,
+ (char*) [[fDVDPopUp titleOfSelectedItem] cString],
+ 0 );
}
else
{
/* DVD folder */
- fManager->ScanVolumes( (char*) [[fDVDFolderField stringValue]
- cString] );
+ HBScanDevice( fHandle,
+ (char*) [[fDVDFolderField stringValue] cString],
+ 0 );
}
}
- (IBAction) ShowPicturePanel: (id) sender
{
HBTitle * title = (HBTitle*)
- fTitleList->ItemAt( [fTitlePopUp indexOfSelectedItem] );
+ HBListItemAt( fTitleList, [fTitlePopUp indexOfSelectedItem] );
- [fPictureGLView SetManager: fManager];
[fPictureGLView SetTitle: title];
fPicture = 0;
- [fPictureGLView ShowPicture: fPicture];
+ [fPictureGLView ShowPicture: fPicture animate: HB_ANIMATE_NONE];
[fWidthStepper setValueWraps: NO];
[fWidthStepper setIncrement: 16];
[fWidthStepper setMinValue: 16];
- [fWidthStepper setMaxValue: title->fOutWidthMax];
- [fWidthStepper setIntValue: title->fOutWidth];
- [fWidthField setIntValue: title->fOutWidth];
- [fTopStepper setValueWraps: NO];
+ [fWidthStepper setMaxValue: title->outWidthMax];
+ [fWidthStepper setIntValue: title->outWidth];
+ [fWidthField setIntValue: title->outWidth];
+ [fDeinterlaceCheck setState:
+ title->deinterlace ? NSOnState : NSOffState];
+ [fTopStepper setValueWraps: NO];
[fTopStepper setIncrement: 2];
[fTopStepper setMinValue: 0];
- [fTopStepper setMaxValue: title->fInHeight / 4];
- [fTopStepper setIntValue: title->fTopCrop];
- [fTopField setIntValue: title->fTopCrop];
+ [fTopStepper setMaxValue: title->inHeight / 4];
+ [fTopStepper setIntValue: title->topCrop];
+ [fTopField setIntValue: title->topCrop];
[fBottomStepper setValueWraps: NO];
[fBottomStepper setIncrement: 2];
[fBottomStepper setMinValue: 0];
- [fBottomStepper setMaxValue: title->fInHeight / 4];
- [fBottomStepper setIntValue: title->fBottomCrop];
- [fBottomField setIntValue: title->fBottomCrop];
+ [fBottomStepper setMaxValue: title->inHeight / 4];
+ [fBottomStepper setIntValue: title->bottomCrop];
+ [fBottomField setIntValue: title->bottomCrop];
[fLeftStepper setValueWraps: NO];
[fLeftStepper setIncrement: 2];
[fLeftStepper setMinValue: 0];
- [fLeftStepper setMaxValue: title->fInWidth / 4];
- [fLeftStepper setIntValue: title->fLeftCrop];
- [fLeftField setIntValue: title->fLeftCrop];
+ [fLeftStepper setMaxValue: title->inWidth / 4];
+ [fLeftStepper setIntValue: title->leftCrop];
+ [fLeftField setIntValue: title->leftCrop];
[fRightStepper setValueWraps: NO];
[fRightStepper setIncrement: 2];
[fRightStepper setMinValue: 0];
- [fRightStepper setMaxValue: title->fInWidth / 4];
- [fRightStepper setIntValue: title->fRightCrop];
- [fRightField setIntValue: title->fRightCrop];
+ [fRightStepper setMaxValue: title->inWidth / 4];
+ [fRightStepper setIntValue: title->rightCrop];
+ [fRightField setIntValue: title->rightCrop];
+
+ [fPreviousButton setEnabled: NO];
+ [fNextButton setEnabled: YES];
char string[1024]; memset( string, 0, 1024 );
sprintf( string, "Final size: %dx%d",
- title->fOutWidth, title->fOutHeight );
+ title->outWidth, title->outHeight );
[fInfoField setStringValue: [NSString stringWithCString: string]];
/* Resize the panel */
NSSize newSize;
/* XXX */
newSize.width = 762 /*fPicturePanelSize.width*/ +
- title->fOutWidthMax - 720;
+ title->outWidthMax - 720;
newSize.height = 740 /*fPicturePanelSize.height*/ +
- title->fOutHeightMax - 576;
+ title->outHeightMax - 576;
[fPicturePanel setContentSize: newSize];
[NSApp beginSheet: fPicturePanel modalForWindow: fWindow
@@ -260,10 +274,10 @@
{
fclose( file );
NSBeginCriticalAlertSheet( @"File already exists",
- @"Nooo", @"Yes, go ahead!", nil, fWindow, self,
+ @"Nooo!", @"Yes, go ahead", nil, fWindow, self,
@selector( OverwriteAlertDone:returnCode:contextInfo: ),
nil, nil,
- [NSString stringWithFormat: @"Do you want to overwrite %s ?",
+ [NSString stringWithFormat: @"Do you want to overwrite %s?",
[[fFileField stringValue] cString]] );
return;
}
@@ -284,32 +298,36 @@
{
/* Get the specified title & audio track(s) */
HBTitle * title = (HBTitle*)
- fTitleList->ItemAt( [fTitlePopUp indexOfSelectedItem] );
+ HBListItemAt( fTitleList, [fTitlePopUp indexOfSelectedItem] );
HBAudio * audio1 = (HBAudio*)
- title->fAudioList->ItemAt( [fLanguagePopUp indexOfSelectedItem] );
+ HBListItemAt( title->audioList,
+ [fLanguagePopUp indexOfSelectedItem] );
HBAudio * audio2 = (HBAudio*)
- title->fAudioList->ItemAt( [fSecondaryLanguagePopUp
- indexOfSelectedItem] );
+ HBListItemAt( title->audioList,
+ [fSecondaryLanguagePopUp indexOfSelectedItem] );
/* Use user settings */
- title->fBitrate = [fCustomBitrateField intValue];
- title->fTwoPass = ( [fTwoPassCheck state] == NSOnState );
- audio1->fOutBitrate = [[fAudioBitratePopUp titleOfSelectedItem]
+ title->file = strdup( [[fFileField stringValue] cString] );
+ title->bitrate = [fCustomBitrateField intValue];
+ title->twoPass = ( [fTwoPassCheck state] == NSOnState );
+ title->codec = ( [[fVideoCodecPopUp titleOfSelectedItem] compare:
+ @"MPEG-4 (Ffmpeg)"] == NSOrderedSame ) ?
+ HB_CODEC_FFMPEG : HB_CODEC_XVID;
+ audio1->outBitrate = [[fAudioBitratePopUp titleOfSelectedItem]
intValue];
if( audio2 )
{
- audio2->fOutBitrate =
+ audio2->outBitrate =
[[fAudioBitratePopUp titleOfSelectedItem] intValue];
}
/* Let libhb do the job */
- fManager->StartRip( title, audio1, audio2,
- (char*) [[fFileField stringValue] cString] );
+ HBStartRip( fHandle, title, audio1, audio2 );
}
- (IBAction) Cancel: (id) sender
{
- fManager->StopRip();
+ HBStopRip( fHandle );
}
- (IBAction) Suspend: (id) sender
@@ -320,50 +338,68 @@
return;
}
- fManager->SuspendRip();
+ HBPauseRip( fHandle );
}
- (IBAction) Resume: (id) sender
{
- fManager->ResumeRip();
+ HBResumeRip( fHandle );
}
- (IBAction) PreviousPicture: (id) sender
{
- if( fPicture > 0 )
+ fPicture--;
+ if( [fOpenGLCheck state] == NSOnState )
{
- fPicture--;
- [fPictureGLView ShowPicture: fPicture];
+ [fPictureGLView ShowPicture: fPicture
+ animate: HB_ANIMATE_LEFT];
}
+ else
+ {
+ [fPictureGLView ShowPicture: fPicture
+ animate: HB_ANIMATE_NONE];
+ }
+
+ [fPreviousButton setEnabled: ( fPicture > 0 )];
+ [fNextButton setEnabled: YES];
}
- (IBAction) NextPicture: (id) sender
{
- if( fPicture < 9 )
+ fPicture++;
+ if( [fOpenGLCheck state] == NSOnState )
+ {
+ [fPictureGLView ShowPicture: fPicture
+ animate: HB_ANIMATE_RIGHT];
+ }
+ else
{
- fPicture++;
- [fPictureGLView ShowPicture: fPicture];
+ [fPictureGLView ShowPicture: fPicture
+ animate: HB_ANIMATE_NONE];
}
+
+ [fPreviousButton setEnabled: YES];
+ [fNextButton setEnabled: ( fPicture < 9 )];
}
- (IBAction) UpdatePicture: (id) sender
{
HBTitle * title = (HBTitle*)
- fTitleList->ItemAt( [fTitlePopUp indexOfSelectedItem] );
- title->fOutWidth = [fWidthStepper intValue];
- title->fDeinterlace = ( [fDeinterlaceCheck state] == NSOnState );
- title->fTopCrop = [fTopStepper intValue];
- title->fBottomCrop = [fBottomStepper intValue];
- title->fLeftCrop = [fLeftStepper intValue];
- title->fRightCrop = [fRightStepper intValue];
-
- [fPictureGLView ShowPicture: fPicture];
-
- [fWidthStepper setIntValue: title->fOutWidth];
- [fTopStepper setIntValue: title->fTopCrop];
- [fBottomStepper setIntValue: title->fBottomCrop];
- [fLeftStepper setIntValue: title->fLeftCrop];
- [fRightStepper setIntValue: title->fRightCrop];
+ HBListItemAt( fTitleList, [fTitlePopUp 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];
[fWidthField setIntValue: [fWidthStepper intValue]];
[fTopField setIntValue: [fTopStepper intValue]];
[fBottomField setIntValue: [fBottomStepper intValue]];
@@ -372,7 +408,7 @@
char string[1024]; memset( string, 0, 1024 );
sprintf( string, "Final size: %dx%d",
- title->fOutWidth, title->fOutHeight );
+ title->outWidth, title->outHeight );
[fInfoField setStringValue: [NSString stringWithCString: string]];
}
@@ -384,25 +420,19 @@
return;
}
- /* Update DVD popup */
- if( [fWindow contentView] == fScanView &&
- GetDate() > fLastDVDDetection + 2000000 )
- {
- [self DetectDrives];
- fLastDVDDetection = GetDate();
- }
-
- /* Ask libhb about what's happening now */
- if( fManager->NeedUpdate() )
+ int modeChanged;
+ HBStatus status;
+
+ modeChanged = HBGetStatus( fHandle, &status );
+
+ switch( status.mode )
{
- HBStatus status = fManager->GetStatus();
+ case HB_MODE_NEED_DEVICE:
+ break;
- switch( status.fMode )
+ case HB_MODE_SCANNING:
{
- case HB_MODE_NEED_VOLUME:
- break;
-
- case HB_MODE_SCANNING:
+ if( modeChanged )
{
[fScanMatrix setEnabled: NO];
[fDVDPopUp setEnabled: NO];
@@ -410,81 +440,88 @@
[fScanBrowseButton setEnabled: NO];
[fScanProgress startAnimation: self];
[fScanButton setEnabled: NO];
-
- char string[1024]; memset( string, 0, 1024 );
- if( status.fScannedTitle )
- {
- sprintf( string, "Scanning %s, title %d...",
- status.fScannedVolume,
- status.fScannedTitle );
- }
- else
- {
- sprintf( string, "Opening %s...",
- status.fScannedVolume );
- }
- [fScanStatusField setStringValue:
- [NSString stringWithCString: string]];
-
- break;
}
- case HB_MODE_INVALID_VOLUME:
+ char string[1024]; memset( string, 0, 1024 );
+ if( status.scannedTitle )
+ {
+ sprintf( string, "Scanning title %d...",
+ status.scannedTitle );
+ }
+ else
{
- [fScanMatrix setEnabled: YES];
- [self ScanMatrixChanged: self];
- [fScanProgress stopAnimation: self];
- [fScanButton setEnabled: YES];
+ sprintf( string, "Opening device..." );
+ }
+ [fScanStatusField setStringValue:
+ [NSString stringWithCString: string]];
+
+ break;
+ }
- [fScanStatusField setStringValue:
- @"Invalid volume, try again" ];
+ case HB_MODE_INVALID_DEVICE:
+ {
+ if( !modeChanged )
break;
- }
+
+ [fScanMatrix setEnabled: YES];
+ [self ScanMatrixChanged: self];
+ [fScanProgress stopAnimation: self];
+ [fScanButton setEnabled: YES];
+
+ [fScanStatusField setStringValue:
+ @"Invalid volume, try again" ];
+ break;
+ }
- case HB_MODE_READY_TO_RIP:
- {
- fTitleList = status.fTitleList;
-
- /* 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 ];
- [fSuspendButton setEnabled: NO];
-
- [fTitlePopUp removeAllItems];
- HBTitle * title;
- for( uint32_t i = 0; i < fTitleList->CountItems(); i++ )
- {
- title = (HBTitle*) fTitleList->ItemAt( i );
- char string[1024]; memset( string, 0, 1024 );
- sprintf( string, "%d (%02lld:%02lld:%02lld)",
- title->fIndex, title->fLength / 3600,
- ( title->fLength % 3600 ) / 60,
- title->fLength % 60 );
- [[fTitlePopUp menu] addItemWithTitle:
- [NSString stringWithCString: string]
- action: nil keyEquivalent: @""];
- }
- [self TitlePopUpChanged: self];
-
+ case HB_MODE_READY_TO_RIP:
+ {
+ if( !modeChanged )
break;
+
+ fTitleList = status.titleList;
+
+ /* 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 ];
+ [fSuspendButton setEnabled: NO];
+
+ [fTitlePopUp removeAllItems];
+ HBTitle * title;
+ for( int i = 0; i < HBListCountItems( fTitleList ); i++ )
+ {
+ title = (HBTitle*) HBListItemAt( fTitleList, i );
+ char string[1024]; memset( string, 0, 1024 );
+ sprintf( string, "%d - %02dh%02dm%02ds",
+ title->index, title->length / 3600,
+ ( title->length % 3600 ) / 60,
+ title->length % 60 );
+ [[fTitlePopUp menu] addItemWithTitle:
+ [NSString stringWithCString: string]
+ action: nil keyEquivalent: @""];
}
+ [self TitlePopUpChanged: self];
+
+ break;
+ }
- case HB_MODE_ENCODING:
+ case HB_MODE_ENCODING:
+ {
+ if( modeChanged )
{
[fTitlePopUp setEnabled: NO];
[fVideoCodecPopUp setEnabled: NO];
@@ -502,150 +539,161 @@
[fSuspendButton setEnabled: YES];
[fSuspendButton setTitle: @"Suspend"];
[fRipButton setTitle: @"Cancel"];
-
- if( !status.fPosition )
- {
- [fRipStatusField setStringValue: @"Starting..."];
- [fRipProgress setIndeterminate: YES];
- [fRipProgress startAnimation: self];;
- }
- else
- {
- char string[1024];
- memset( string, 0, 1024 );
- sprintf( string, "Encoding: %.2f %%",
- 100 * status.fPosition );
- [fRipStatusField setStringValue:
- [NSString stringWithCString: string]];
- memset( string, 0, 1024 );
- sprintf( string,
- "Speed: %.2f fps (%02d:%02d:%02d remaining)",
- status.fFrameRate,
- status.fRemainingTime / 3600,
- ( status.fRemainingTime % 3600 ) / 60,
- status.fRemainingTime % 60 );
- [fRipInfoField setStringValue:
- [NSString stringWithCString: string]];
-
- [fRipProgress setIndeterminate: NO];
- [fRipProgress setDoubleValue: 100 * status.fPosition];
- }
-
- break;
}
-
- case HB_MODE_SUSPENDED:
+
+ if( !status.position )
{
- char string[1024]; memset( string, 0, 1024 );
- sprintf( string, "Encoding: %.2f %% (PAUSED)",
- 100 * status.fPosition ) ;
+ [fRipStatusField setStringValue: @"Starting..."];
+ [fRipProgress setIndeterminate: YES];
+ [fRipProgress startAnimation: self];;
+ }
+ else
+ {
+ char string[1024];
+ memset( string, 0, 1024 );
+ sprintf( string, "Encoding: %.2f %% (pass %d of %d)",
+ 100 * status.position, status.pass,
+ status.passCount );
[fRipStatusField setStringValue:
[NSString stringWithCString: string]];
- [fRipInfoField setStringValue: @""];
-
- [fRipProgress setDoubleValue: 100 * status.fPosition];
+ memset( string, 0, 1024 );
+ sprintf( string, "Speed: %.2f fps (avg %.2f fps, "
+ "%02dh%02dm%02ds remaining)",
+ status.frameRate, status.avFrameRate,
+ status.remainingTime / 3600,
+ ( status.remainingTime / 60 ) % 60,
+ status.remainingTime % 60 );
+ [fRipInfoField setStringValue:
+ [NSString stringWithCString: string]];
- [fSuspendButton setTitle: @"Resume"];
- break;
+ [fRipProgress setIndeterminate: NO];
+ [fRipProgress setDoubleValue: 100 * status.position];
}
+
+ break;
+ }
- case HB_MODE_STOPPING:
- [fRipStatusField setStringValue: @"Stopping..."];
- [fRipInfoField setStringValue: @""];
- [fRipProgress setIndeterminate: YES];
- [fRipProgress startAnimation: self];;
+ case HB_MODE_PAUSED:
+ {
+ if( !modeChanged )
break;
+
+ char string[1024]; memset( string, 0, 1024 );
+ sprintf( string, "Encoding: %.2f %% (PAUSED)",
+ 100 * status.position ) ;
+ [fRipStatusField setStringValue:
+ [NSString stringWithCString: string]];
+ [fRipInfoField setStringValue: @""];
+
+ [fRipProgress setDoubleValue: 100 * status.position];
- case HB_MODE_DONE:
- case HB_MODE_CANCELED:
- case HB_MODE_ERROR:
- [fRipProgress setIndeterminate: NO];
-
- if( status.fMode == HB_MODE_DONE )
- {
- [fRipProgress setDoubleValue: 100];
- [fRipStatusField setStringValue: @"Done." ];
- NSBeep();
- [NSApp requestUserAttention: NSInformationalRequest];
- [NSApp beginSheet: fDonePanel
- modalForWindow: fWindow modalDelegate: nil
- didEndSelector: nil contextInfo: nil];
- [NSApp runModalForWindow: fDonePanel];
- [NSApp endSheet: fDonePanel];
- [fDonePanel orderOut: self];
- }
- else if( status.fMode == HB_MODE_CANCELED )
- {
- [fRipProgress setDoubleValue: 0];
- [fRipStatusField setStringValue: @"Canceled." ];
- }
- else
- {
- [fRipProgress setDoubleValue: 0];
- switch( status.fError )
- {
- case HB_ERROR_A52_SYNC:
- [fRipStatusField setStringValue:
- @"An error occured (corrupted AC3 data)." ];
- break;
- case HB_ERROR_AVI_WRITE:
- [fRipStatusField setStringValue:
- @"An error occured (could not write to file)." ];
- break;
- case HB_ERROR_DVD_OPEN:
- [fRipStatusField setStringValue:
- @"An error occured (could not open device)." ];
- break;
- case HB_ERROR_DVD_READ:
- [fRipStatusField setStringValue:
- @"An error occured (DVD read failed)." ];
- break;
- case HB_ERROR_MP3_INIT:
- [fRipStatusField setStringValue:
- @"An error occured (could not init MP3 encoder)." ];
- break;
- case HB_ERROR_MP3_ENCODE:
- [fRipStatusField setStringValue:
- @"An error occured (MP3 encoder failed)." ];
- break;
- case HB_ERROR_MPEG4_INIT:
- [fRipStatusField setStringValue:
- @"An error occured (could not init MPEG4 encoder)." ];
- break;
- }
- }
+ [fSuspendButton setTitle: @"Resume"];
+ break;
+ }
- [fRipInfoField setStringValue: @""];
-
- [fTitlePopUp setEnabled: YES];
- [fVideoCodecPopUp setEnabled: YES];
- [fVideoMatrix setEnabled: YES];
- [fTwoPassCheck setEnabled: YES];
- [fCropButton setEnabled: YES];
- [fLanguagePopUp setEnabled: YES];
- [fSecondaryLanguagePopUp setEnabled: YES];
- [fAudioCodecPopUp setEnabled: YES];
- [fAudioBitratePopUp setEnabled: YES];
- [fFileFormatPopUp setEnabled: YES];
- [fFileBrowseButton setEnabled: YES];
- [fSuspendButton setEnabled: NO];
- [fSuspendButton setTitle: @"Suspend"];
- [fRipButton setTitle: @"Rip"];
+ case HB_MODE_STOPPING:
+ if( !modeChanged )
+ break;
- [self VideoMatrixChanged: self];
+ [fRipStatusField setStringValue: @"Stopping..."];
+ [fRipInfoField setStringValue: @""];
+ [fRipProgress setIndeterminate: YES];
+ [fRipProgress startAnimation: self];;
+ break;
- /* Warn the finder to update itself */
- [[NSWorkspace sharedWorkspace] noteFileSystemChanged:
- [fFileField stringValue]];
+ case HB_MODE_DONE:
+ case HB_MODE_CANCELED:
+ case HB_MODE_ERROR:
+ if( !modeChanged )
break;
- default:
- break;
- }
+ /* Warn the finder to update itself */
+ [[NSWorkspace sharedWorkspace] noteFileSystemChanged:
+ [fFileField stringValue]];
+
+ [fRipProgress setIndeterminate: NO];
+ [fRipInfoField setStringValue: @""];
+
+ if( status.mode == HB_MODE_DONE )
+ {
+ [fRipProgress setDoubleValue: 100];
+ [fRipStatusField setStringValue: @"Done." ];
+ NSBeep();
+ [NSApp requestUserAttention: NSInformationalRequest];
+ [NSApp beginSheet: fDonePanel
+ modalForWindow: fWindow modalDelegate: nil
+ didEndSelector: nil contextInfo: nil];
+ [NSApp runModalForWindow: fDonePanel];
+ [NSApp endSheet: fDonePanel];
+ [fDonePanel orderOut: self];
+ }
+ else if( status.mode == HB_MODE_CANCELED )
+ {
+ [fRipProgress setDoubleValue: 0];
+ [fRipStatusField setStringValue: @"Canceled." ];
+ }
+ else
+ {
+ [fRipProgress setDoubleValue: 0];
+ switch( status.error )
+ {
+ case HB_ERROR_A52_SYNC:
+ [fRipStatusField setStringValue:
+ @"An error occured (corrupted AC3 data)." ];
+ break;
+ case HB_ERROR_AVI_WRITE:
+ [fRipStatusField setStringValue:
+ @"An error occured (could not write to file)." ];
+ break;
+ case HB_ERROR_DVD_OPEN:
+ [fRipStatusField setStringValue:
+ @"An error occured (could not open device)." ];
+ break;
+ case HB_ERROR_DVD_READ:
+ [fRipStatusField setStringValue:
+ @"An error occured (DVD read failed)." ];
+ break;
+ case HB_ERROR_MP3_INIT:
+ [fRipStatusField setStringValue:
+ @"An error occured (could not init MP3 encoder)." ];
+ break;
+ case HB_ERROR_MP3_ENCODE:
+ [fRipStatusField setStringValue:
+ @"An error occured (MP3 encoder failed)." ];
+ break;
+ case HB_ERROR_MPEG4_INIT:
+ [fRipStatusField setStringValue:
+ @"An error occured (could not init MPEG4 encoder)." ];
+ break;
+ }
+ }
+
+ [fTitlePopUp setEnabled: YES];
+ [fVideoCodecPopUp setEnabled: YES];
+ [fVideoMatrix setEnabled: YES];
+ [fTwoPassCheck setEnabled: YES];
+ [fCropButton setEnabled: YES];
+ [fLanguagePopUp setEnabled: YES];
+ [fSecondaryLanguagePopUp setEnabled: YES];
+ [fAudioCodecPopUp setEnabled: YES];
+ [fAudioBitratePopUp setEnabled: YES];
+ [fFileFormatPopUp setEnabled: YES];
+ [fFileBrowseButton setEnabled: YES];
+ [fSuspendButton setEnabled: NO];
+ [fSuspendButton setTitle: @"Suspend"];
+ [fRipButton setTitle: @"Rip"];
+
+ [self VideoMatrixChanged: self];
+ [self VideoCodecPopUpChanged: self];
+
+ break;
+
+ default:
+ break;
}
}
-- (void) DetectDrives
+- (void) DetectDrives: (NSNotification *) notification
{
/* Scan DVD drives (stolen from VLC) */
io_object_t next_media;
@@ -666,7 +714,7 @@
return;
}
- CFDictionarySetValue( classes_to_match, CFSTR( kIOMediaEjectable ),
+ CFDictionarySetValue( classes_to_match, CFSTR( kIOMediaEjectableKey ),
kCFBooleanTrue );
kern_result =
@@ -690,7 +738,7 @@
{
str_bsd_path =
IORegistryEntryCreateCFProperty( next_media,
- CFSTR( kIOBSDName ),
+ CFSTR( kIOBSDNameKey ),
kCFAllocatorDefault,
0 );
if( str_bsd_path == NULL )
@@ -720,25 +768,6 @@
IOObjectRelease( media_iterator );
- /* Refresh only if a change occured */
- if( [drivesList count] == (unsigned) [fDVDPopUp numberOfItems] )
- {
- bool isSame = true;
- for( unsigned i = 0; i < [drivesList count]; i++ )
- {
- if( ![[drivesList objectAtIndex: i] isEqualToString:
- [fDVDPopUp itemTitleAtIndex: i]] )
- {
- isSame = false;
- break;
- }
- }
- if( isSame )
- {
- return;
- }
- }
-
[fDVDPopUp removeAllItems];
for( unsigned i = 0; i < [drivesList count]; i++ )
{
@@ -770,29 +799,29 @@
- (IBAction) TitlePopUpChanged: (id) sender
{
HBTitle * title = (HBTitle*)
- fTitleList->ItemAt( [fTitlePopUp indexOfSelectedItem] );
+ HBListItemAt( fTitleList, [fTitlePopUp indexOfSelectedItem] );
[fLanguagePopUp removeAllItems];
[fSecondaryLanguagePopUp removeAllItems];
HBAudio * audio;
- for( uint32_t i = 0; i < title->fAudioList->CountItems(); i++ )
+ for( int i = 0; i < HBListCountItems( title->audioList ); i++ )
{
- audio = (HBAudio*) title->fAudioList->ItemAt( i );
+ audio = (HBAudio*) HBListItemAt( title->audioList, i );
/* We cannot use NSPopUpButton's addItemWithTitle because
it checks for duplicate entries */
[[fLanguagePopUp menu] addItemWithTitle:
- [NSString stringWithCString: audio->fDescription]
+ [NSString stringWithCString: audio->language]
action: nil keyEquivalent: @""];
[[fSecondaryLanguagePopUp menu] addItemWithTitle:
- [NSString stringWithCString: audio->fDescription]
+ [NSString stringWithCString: audio->language]
action: nil keyEquivalent: @""];
}
[fSecondaryLanguagePopUp addItemWithTitle: @"None"];
[fSecondaryLanguagePopUp selectItemWithTitle: @"None"];
[fSecondaryLanguagePopUp setEnabled:
- ( title->fAudioList->CountItems() > 1 )];
+ ( HBListCountItems( title->audioList ) > 1 )];
[fTargetSizeField SetHBTitle: title];
if( [fVideoMatrix selectedRow] )
@@ -801,6 +830,20 @@
}
}
+- (IBAction) VideoCodecPopUpChanged: (id) sender
+{
+ if( [[fVideoCodecPopUp titleOfSelectedItem]
+ compare: @"MPEG-4 (Ffmpeg)"] == NSOrderedSame )
+ {
+ [fTwoPassCheck setEnabled: YES];
+ }
+ else
+ {
+ [fTwoPassCheck setState: NSOffState];
+ [fTwoPassCheck setEnabled: NO];
+ }
+}
+
- (IBAction) AudioPopUpChanged: (id) sender
{
if( [fVideoMatrix selectedRow] )
diff --git a/macosx/English.lproj/InfoPlist.strings b/macosx/English.lproj/InfoPlist.strings
index 7690c78ef..9a0f313a7 100644
--- a/macosx/English.lproj/InfoPlist.strings
+++ b/macosx/English.lproj/InfoPlist.strings
Binary files differ
diff --git a/macosx/English.lproj/MainMenu.nib/classes.nib b/macosx/English.lproj/MainMenu.nib/classes.nib
index 38429950c..c9539b9d2 100644
--- a/macosx/English.lproj/MainMenu.nib/classes.nib
+++ b/macosx/English.lproj/MainMenu.nib/classes.nib
@@ -18,6 +18,7 @@
Suspend = id;
TitlePopUpChanged = id;
UpdatePicture = id;
+ VideoCodecPopUpChanged = id;
VideoMatrixChanged = id;
};
CLASS = HBController;
@@ -40,8 +41,11 @@
fLanguagePopUp = NSPopUpButton;
fLeftField = NSTextField;
fLeftStepper = NSStepper;
+ fNextButton = NSButton;
+ fOpenGLCheck = NSButton;
fPictureGLView = HBPictureGLView;
fPicturePanel = NSPanel;
+ fPreviousButton = NSButton;
fRightField = NSTextField;
fRightStepper = NSStepper;
fRipButton = NSButton;
diff --git a/macosx/English.lproj/MainMenu.nib/info.nib b/macosx/English.lproj/MainMenu.nib/info.nib
index af41a1429..96ab6e7ce 100644
--- a/macosx/English.lproj/MainMenu.nib/info.nib
+++ b/macosx/English.lproj/MainMenu.nib/info.nib
@@ -3,31 +3,31 @@
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
- <string>29 16 381 380 0 0 1440 878 </string>
+ <string>25 188 381 380 0 0 1440 878 </string>
<key>IBEditorPositions</key>
<dict>
<key>29</key>
<string>407 469 205 44 0 0 1440 878 </string>
<key>556</key>
- <string>510 480 420 244 0 0 1440 878 </string>
+ <string>510 481 420 244 0 0 1440 878 </string>
<key>583</key>
- <string>648 516 144 171 0 0 1440 878 </string>
+ <string>648 517 144 171 0 0 1440 878 </string>
<key>589</key>
<string>510 282 420 586 0 0 1440 878 </string>
</dict>
<key>IBFramework Version</key>
- <string>291.0</string>
+ <string>349.0</string>
<key>IBOpenObjects</key>
<array>
- <integer>583</integer>
- <integer>21</integer>
- <integer>589</integer>
- <integer>365</integer>
+ <integer>556</integer>
<integer>434</integer>
<integer>29</integer>
- <integer>556</integer>
+ <integer>589</integer>
+ <integer>21</integer>
+ <integer>583</integer>
+ <integer>365</integer>
</array>
<key>IBSystem Version</key>
- <string>6R73</string>
+ <string>7B85</string>
</dict>
</plist>
diff --git a/macosx/English.lproj/MainMenu.nib/objects.nib b/macosx/English.lproj/MainMenu.nib/objects.nib
index 9fe323510..1e6996ef4 100644
--- a/macosx/English.lproj/MainMenu.nib/objects.nib
+++ b/macosx/English.lproj/MainMenu.nib/objects.nib
Binary files differ
diff --git a/macosx/HandBrake.pbproj/project.pbxproj b/macosx/HandBrake.pbproj/project.pbxproj
index 2cc6e1054..8c918d283 100644
--- a/macosx/HandBrake.pbproj/project.pbxproj
+++ b/macosx/HandBrake.pbproj/project.pbxproj
@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
- objectVersion = 38;
+ objectVersion = 39;
objects = {
080E96DCFE201CFB7F000001 = {
fileRef = 29B97318FDCFA39411CA2CEA;
@@ -23,6 +23,7 @@
isa = PBXGroup;
name = Classes;
refType = 4;
+ sourceTree = "<group>";
};
089C165CFE840E0CC02AAC07 = {
children = (
@@ -31,13 +32,16 @@
isa = PBXVariantGroup;
name = InfoPlist.strings;
refType = 4;
+ sourceTree = "<group>";
};
089C165DFE840E0CC02AAC07 = {
+ expectedFileType = text.plist.strings;
fileEncoding = 10;
isa = PBXFileReference;
name = English;
path = English.lproj/InfoPlist.strings;
refType = 4;
+ sourceTree = "<group>";
};
089C165EFE840E0CC02AAC07 = {
fileRef = 089C165CFE840E0CC02AAC07;
@@ -64,12 +68,16 @@
isa = PBXGroup;
name = "Linked Frameworks";
refType = 4;
+ sourceTree = "<group>";
};
1058C7A1FEA54F0111CA2CBB = {
+ expectedFileType = wrapper.framework;
+ fallbackIsa = PBXFileReference;
isa = PBXFrameworkReference;
name = Cocoa.framework;
path = /System/Library/Frameworks/Cocoa.framework;
refType = 0;
+ sourceTree = "<absolute>";
};
1058C7A2FEA54F0111CA2CBB = {
children = (
@@ -79,6 +87,7 @@
isa = PBXGroup;
name = "Other Frameworks";
refType = 4;
+ sourceTree = "<group>";
};
1058C7A3FEA54F0111CA2CBB = {
fileRef = 1058C7A1FEA54F0111CA2CBB;
@@ -97,9 +106,12 @@
//173
//174
17587328FF379C6511CA2CBB = {
+ expectedFileType = wrapper.application;
+ fallbackIsa = PBXFileReference;
isa = PBXApplicationReference;
path = HandBrake.app;
refType = 3;
+ sourceTree = BUILT_PRODUCTS_DIR;
};
//170
//171
@@ -118,6 +130,7 @@
isa = PBXGroup;
name = Products;
refType = 4;
+ sourceTree = "<group>";
};
//190
//191
@@ -130,6 +143,10 @@
//293
//294
29B97313FDCFA39411CA2CEA = {
+ buildSettings = {
+ MACOSX_DEPLOYMENT_TARGET = 10.2;
+ SDKROOT = /Developer/SDKs/MacOSX10.2.7.sdk;
+ };
buildStyles = (
4A9504CCFFE6A4B311CA0CBA,
4A9504CDFFE6A4B311CA0CBA,
@@ -154,23 +171,26 @@
name = HandBrake;
path = "";
refType = 4;
+ sourceTree = "<group>";
};
29B97315FDCFA39411CA2CEA = {
children = (
29B97316FDCFA39411CA2CEA,
- 4D358C040534AB8100D654EB,
- 4D929FEB0527903D00A80101,
+ 4DFDC318054AC84C00151618,
);
isa = PBXGroup;
name = "Other Sources";
path = "";
refType = 4;
+ sourceTree = "<group>";
};
29B97316FDCFA39411CA2CEA = {
+ expectedFileType = sourcecode.cpp.objcpp;
fileEncoding = 30;
isa = PBXFileReference;
path = main.mm;
refType = 4;
+ sourceTree = "<group>";
};
29B97317FDCFA39411CA2CEA = {
children = (
@@ -183,6 +203,7 @@
4D69F5CC0527944A00A80101,
4D69F5CD0527944A00A80101,
4D69F5CE0527944A00A80101,
+ 4DDEF3B905474DCC002904DE,
4D118405053054CD00C39CA9,
089C165CFE840E0CC02AAC07,
);
@@ -190,6 +211,7 @@
name = Resources;
path = "";
refType = 4;
+ sourceTree = "<group>";
};
29B97318FDCFA39411CA2CEA = {
children = (
@@ -199,12 +221,15 @@
name = MainMenu.nib;
path = "";
refType = 4;
+ sourceTree = "<group>";
};
29B97319FDCFA39411CA2CEA = {
+ expectedFileType = wrapper.nib;
isa = PBXFileReference;
name = English;
path = English.lproj/MainMenu.nib;
refType = 4;
+ sourceTree = "<group>";
};
29B97323FDCFA39411CA2CEA = {
children = (
@@ -215,18 +240,25 @@
name = Frameworks;
path = "";
refType = 4;
+ sourceTree = "<group>";
};
29B97324FDCFA39411CA2CEA = {
+ expectedFileType = wrapper.framework;
+ fallbackIsa = PBXFileReference;
isa = PBXFrameworkReference;
name = AppKit.framework;
path = /System/Library/Frameworks/AppKit.framework;
refType = 0;
+ sourceTree = "<absolute>";
};
29B97325FDCFA39411CA2CEA = {
+ expectedFileType = wrapper.framework;
+ fallbackIsa = PBXFileReference;
isa = PBXFrameworkReference;
name = Foundation.framework;
path = /System/Library/Frameworks/Foundation.framework;
refType = 0;
+ sourceTree = "<absolute>";
};
29B97326FDCFA39411CA2CEA = {
buildPhases = (
@@ -263,7 +295,7 @@
<key>CFBundleExecutable</key>
<string>HandBrake</string>
<key>CFBundleGetInfoString</key>
- <string>HandBrake 0.4.1 - By Eric Petit &lt;[email protected]&gt;</string>
+ <string>HandBrake 0.5 - By Eric Petit &lt;[email protected]&gt;</string>
<key>CFBundleIconFile</key>
<string>HandBrake.icns</string>
<key>CFBundleIdentifier</key>
@@ -275,11 +307,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
- <string>0.4.1</string>
+ <string>0.5</string>
<key>CFBundleSignature</key>
<string>HB##</string>
<key>CFBundleVersion</key>
- <string>0.4.1</string>
+ <string>0.5</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
@@ -291,11 +323,10 @@
29B97327FDCFA39411CA2CEA = {
buildActionMask = 2147483647;
files = (
- 4D929FEC0527903D00A80101,
4D6615EA05288C2300A80101,
4D857591052B78E300C39CA9,
4D358C020534A91300D654EB,
- 4D358C050534AB8100D654EB,
+ 4DFDC319054AC84C00151618,
);
isa = PBXHeadersBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
@@ -343,6 +374,7 @@
4D69F5D50527944A00A80101,
4DEB2025052B055F00C39CA9,
4DDE9725052B7B2B00C39CA9,
+ 4DDEF3BA05474DCC002904DE,
);
isa = PBXFrameworksBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
@@ -362,7 +394,12 @@
);
buildSettings = {
COPY_PHASE_STRIP = NO;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
OPTIMIZATION_CFLAGS = "-O0";
+ ZERO_LINK = YES;
};
isa = PBXBuildStyle;
name = Development;
@@ -372,6 +409,8 @@
);
buildSettings = {
COPY_PHASE_STRIP = YES;
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ ZERO_LINK = NO;
};
isa = PBXBuildStyle;
name = Deployment;
@@ -387,9 +426,11 @@
//4D3
//4D4
4D118405053054CD00C39CA9 = {
+ expectedFileType = image.icns;
isa = PBXFileReference;
path = HandBrake.icns;
refType = 4;
+ sourceTree = "<group>";
};
4D118406053054CD00C39CA9 = {
fileRef = 4D118405053054CD00C39CA9;
@@ -398,16 +439,20 @@
};
};
4D358C000534A91300D654EB = {
+ expectedFileType = sourcecode.c.h;
fileEncoding = 30;
isa = PBXFileReference;
path = TargetSizeField.h;
refType = 4;
+ sourceTree = "<group>";
};
4D358C010534A91300D654EB = {
+ expectedFileType = sourcecode.cpp.objcpp;
fileEncoding = 30;
isa = PBXFileReference;
path = TargetSizeField.mm;
refType = 4;
+ sourceTree = "<group>";
};
4D358C020534A91300D654EB = {
fileRef = 4D358C000534A91300D654EB;
@@ -421,19 +466,6 @@
settings = {
};
};
- 4D358C040534AB8100D654EB = {
- fileEncoding = 30;
- isa = PBXFileReference;
- name = Common.h;
- path = /Users/titer/HandBrake/core/Common.h;
- refType = 0;
- };
- 4D358C050534AB8100D654EB = {
- fileRef = 4D358C040534AB8100D654EB;
- isa = PBXBuildFile;
- settings = {
- };
- };
4D6615EA05288C2300A80101 = {
fileRef = 4DF3C8CB052889CD00A80101;
isa = PBXBuildFile;
@@ -441,46 +473,60 @@
};
};
4D69F5C80527944A00A80101 = {
+ expectedFileType = archive.ar;
isa = PBXFileReference;
name = liba52.a;
path = /usr/local/lib/liba52.a;
refType = 0;
+ sourceTree = "<absolute>";
};
4D69F5C90527944A00A80101 = {
+ expectedFileType = archive.ar;
isa = PBXFileReference;
name = libavcodec.a;
path = /usr/local/lib/libavcodec.a;
refType = 0;
+ sourceTree = "<absolute>";
};
4D69F5CA0527944A00A80101 = {
+ expectedFileType = archive.ar;
isa = PBXFileReference;
name = libdvdcss.a;
path = /usr/local/lib/libdvdcss.a;
refType = 0;
+ sourceTree = "<absolute>";
};
4D69F5CB0527944A00A80101 = {
+ expectedFileType = archive.ar;
isa = PBXFileReference;
name = libdvdplay.a;
path = /usr/local/lib/libdvdplay.a;
refType = 0;
+ sourceTree = "<absolute>";
};
4D69F5CC0527944A00A80101 = {
+ expectedFileType = archive.ar;
isa = PBXFileReference;
name = libdvdread.a;
path = /usr/local/lib/libdvdread.a;
refType = 0;
+ sourceTree = "<absolute>";
};
4D69F5CD0527944A00A80101 = {
+ expectedFileType = archive.ar;
isa = PBXFileReference;
name = libmp3lame.a;
path = /usr/local/lib/libmp3lame.a;
refType = 0;
+ sourceTree = "<absolute>";
};
4D69F5CE0527944A00A80101 = {
+ expectedFileType = archive.ar;
isa = PBXFileReference;
name = libmpeg2.a;
path = /usr/local/lib/libmpeg2.a;
refType = 0;
+ sourceTree = "<absolute>";
};
4D69F5CF0527944A00A80101 = {
fileRef = 4D69F5C80527944A00A80101;
@@ -525,16 +571,20 @@
};
};
4D85758E052B78E300C39CA9 = {
+ expectedFileType = sourcecode.cpp.objcpp;
fileEncoding = 30;
isa = PBXFileReference;
path = PictureGLView.mm;
refType = 4;
+ sourceTree = "<group>";
};
4D85758F052B78E300C39CA9 = {
+ expectedFileType = sourcecode.c.h;
fileEncoding = 30;
isa = PBXFileReference;
path = PictureGLView.h;
refType = 4;
+ sourceTree = "<group>";
};
4D857590052B78E300C39CA9 = {
fileRef = 4D85758E052B78E300C39CA9;
@@ -548,24 +598,13 @@
settings = {
};
};
- 4D929FEB0527903D00A80101 = {
- fileEncoding = 30;
- isa = PBXFileReference;
- name = Manager.h;
- path = ../core/Manager.h;
- refType = 4;
- };
- 4D929FEC0527903D00A80101 = {
- fileRef = 4D929FEB0527903D00A80101;
- isa = PBXBuildFile;
- settings = {
- };
- };
4D929FED0527907200A80101 = {
+ expectedFileType = archive.ar;
isa = PBXFileReference;
name = libhb.a;
path = ../core/libhb.a;
refType = 4;
+ sourceTree = "<group>";
};
4D929FEE0527907200A80101 = {
fileRef = 4D929FED0527907200A80101;
@@ -574,10 +613,13 @@
};
};
4DDE9724052B7B2B00C39CA9 = {
+ expectedFileType = wrapper.framework;
+ fallbackIsa = PBXFileReference;
isa = PBXFrameworkReference;
name = OpenGL.framework;
path = /System/Library/Frameworks/OpenGL.framework;
refType = 0;
+ sourceTree = "<absolute>";
};
4DDE9725052B7B2B00C39CA9 = {
fileRef = 4DDE9724052B7B2B00C39CA9;
@@ -585,11 +627,28 @@
settings = {
};
};
+ 4DDEF3B905474DCC002904DE = {
+ expectedFileType = archive.ar;
+ isa = PBXFileReference;
+ name = libxvidcore.a;
+ path = /usr/local/lib/libxvidcore.a;
+ refType = 0;
+ sourceTree = "<absolute>";
+ };
+ 4DDEF3BA05474DCC002904DE = {
+ fileRef = 4DDEF3B905474DCC002904DE;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
4DEB2024052B055F00C39CA9 = {
+ expectedFileType = wrapper.framework;
+ fallbackIsa = PBXFileReference;
isa = PBXFrameworkReference;
name = IOKit.framework;
path = /System/Library/Frameworks/IOKit.framework;
refType = 0;
+ sourceTree = "<absolute>";
};
4DEB2025052B055F00C39CA9 = {
fileRef = 4DEB2024052B055F00C39CA9;
@@ -598,16 +657,20 @@
};
};
4DF3C8CB052889CD00A80101 = {
+ expectedFileType = sourcecode.c.h;
fileEncoding = 30;
isa = PBXFileReference;
path = Controller.h;
refType = 4;
+ sourceTree = "<group>";
};
4DF3C8CC052889CD00A80101 = {
+ expectedFileType = sourcecode.cpp.objcpp;
fileEncoding = 30;
isa = PBXFileReference;
path = Controller.mm;
refType = 4;
+ sourceTree = "<group>";
};
4DF3C8CE052889CD00A80101 = {
fileRef = 4DF3C8CC052889CD00A80101;
@@ -615,6 +678,21 @@
settings = {
};
};
+ 4DFDC318054AC84C00151618 = {
+ expectedFileType = sourcecode.c.h;
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ name = HandBrake.h;
+ path = ../core/HandBrake.h;
+ refType = 4;
+ sourceTree = "<group>";
+ };
+ 4DFDC319054AC84C00151618 = {
+ fileRef = 4DFDC318054AC84C00151618;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
};
rootObject = 29B97313FDCFA39411CA2CEA;
}
diff --git a/macosx/PictureGLView.h b/macosx/PictureGLView.h
index 06e5a16e1..c558c3c0f 100644
--- a/macosx/PictureGLView.h
+++ b/macosx/PictureGLView.h
@@ -1,20 +1,34 @@
-/* PictureGLView */
+/* $Id: PictureGLView.h,v 1.1.1.1 2003/11/03 12:03:51 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 "Manager.h"
+#include "HandBrake.h"
+
+#define HB_ANIMATE_NONE 0
+#define HB_ANIMATE_LEFT 1
+#define HB_ANIMATE_RIGHT 2
@interface HBPictureGLView : NSOpenGLView
{
- HBManager * fManager;
+ HBHandle * fHandle;
HBTitle * fTitle;
uint8_t * fPicture;
+ uint8_t * fOldPicture;
}
-- (void) SetManager: (HBManager*) manager;
+- (id) initWithFrame: (NSRect) frame;
+- (void) reshape;
+- (void) drawRect: (NSRect) rect;
+- (void) drawAnimation: (int) how;
+
+- (void) SetHandle: (HBHandle*) handle;
- (void) SetTitle: (HBTitle*) title;
-- (void) ShowPicture: (int) picture;
+- (void) ShowPicture: (int) index animate: (int) how;
@end
diff --git a/macosx/PictureGLView.mm b/macosx/PictureGLView.mm
index 79103f6b6..8df19907b 100644
--- a/macosx/PictureGLView.mm
+++ b/macosx/PictureGLView.mm
@@ -1,68 +1,153 @@
+/* $Id: PictureGLView.mm,v 1.3 2003/11/03 22:01:13 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 <OpenGL/gl.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) SetManager: (HBManager*) manager
+- (void) SetHandle: (HBHandle*) handle
{
- fManager = manager;
+ 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
+- (void) ShowPicture: (int) index animate: (int) how
{
+ if( fOldPicture ) free( fOldPicture );
+ fOldPicture = fPicture;
+
/* Get the picture */
- uint8_t * tmp = fManager->GetPreview( fTitle, index );
+ uint8_t * tmp = HBGetPreview( fHandle, fTitle, index );
/* Make it be upside-down */
- if( fPicture ) free( fPicture );
- fPicture = (uint8_t*) malloc( 4 * ( fTitle->fOutWidthMax + 2 ) *
- ( fTitle->fOutHeightMax + 2 ) );
- for( uint32_t i = 0; i < fTitle->fOutHeightMax + 2; i++ )
+ 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 = 0; i < fTitle->outHeightMax + 2; i++ )
{
- memcpy( fPicture + 4 * ( fTitle->fOutWidthMax + 2 ) * i,
- tmp + 4 * ( fTitle->fOutWidthMax + 2 ) *
- ( fTitle->fOutHeightMax + 1 - i ),
- 4 * ( fTitle->fOutWidthMax + 2 ) );
+ memcpy( out, in, 4 * ( fTitle->outWidthMax + 2 ) );
+ in += 4 * ( fTitle->outWidthMax + 2 );
+ out -= 4 * ( fTitle->outWidthMax + 2 );
}
free( tmp );
- /* Grrr - should find a way to give ARGB to OpenGL */
- uint8_t r, g, b, a;
- for( uint32_t i = 0; i < fTitle->fOutHeightMax + 2; i++ )
+ /* ARGB -> RGBA */
+ uint32_t * p = (uint32_t*) fPicture;
+ for( int i = 0;
+ i < ( fTitle->outHeightMax + 2 ) * ( fTitle->outWidthMax + 2 );
+ i++ )
+ {
+ *(p++) = ( ( (*p) & 0xff000000 ) >> 24 ) |
+ ( ( (*p) & 0x00ff0000 ) << 8 ) |
+ ( ( (*p) & 0x0000ff00 ) << 8 ) |
+ ( ( (*p) & 0x000000ff ) << 8 );
+ }
+
+ if( how == HB_ANIMATE_NONE )
+ {
+ [self drawRect: [self bounds]];
+ return;
+ }
+
+ in = fOldPicture;
+ out = truc;
+ for( int i = 0; 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 = 0; i < fTitle->outHeightMax + 2; i++ )
{
- for( uint32_t j = 0; j < fTitle->fOutWidthMax + 2; j++ )
+ 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
+
+ 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;
+ if( w * rotation >= 90.0 )
+ {
+ break;
+ }
+
+ wait = ANIMATION_TIME / 90 - ( HBGetDate() - date );
+ if( wait > 0 )
{
- a = fPicture[4*(i*(fTitle->fOutWidthMax+2)+j)];
- r = fPicture[4*(i*(fTitle->fOutWidthMax+2)+j)+1];
- g = fPicture[4*(i*(fTitle->fOutWidthMax+2)+j)+2];
- b = fPicture[4*(i*(fTitle->fOutWidthMax+2)+j)+3];
-
- fPicture[4*(i*(fTitle->fOutWidthMax+2)+j)] = r;
- fPicture[4*(i*(fTitle->fOutWidthMax+2)+j)+1] = g;
- fPicture[4*(i*(fTitle->fOutWidthMax+2)+j)+2] = b;
- fPicture[4*(i*(fTitle->fOutWidthMax+2)+j)+3] = a;
+ HBSnooze( wait );
}
}
- [self setNeedsDisplay: YES];
+ [self drawRect: [self bounds]];
}
-/* Override NSView's initWithFrame: to specify our pixel format */
- (id) initWithFrame: (NSRect) frame
{
- fManager = NULL;
- fTitle = NULL;
- fPicture = NULL;
+ fHandle = NULL;
+ fTitle = NULL;
+ fPicture = NULL;
+ fOldPicture = NULL;
GLuint attribs[] =
{
@@ -81,34 +166,109 @@
NSOpenGLPixelFormat * fmt = [[NSOpenGLPixelFormat alloc]
initWithAttributes: (NSOpenGLPixelFormatAttribute*) attribs];
- if( !fmt )
+ self = [super initWithFrame:frame pixelFormat: [fmt autorelease]];
+
+ if( !self )
{
- fprintf( stderr, "Sarass\n" );
+ return NULL;
}
- return self = [super initWithFrame:frame pixelFormat:
- [fmt autorelease]];
+ [[self openGLContext] makeCurrentContext];
+ [self reshape];
+
+ glGenTextures( 2, texture );
+ truc = (uint8_t*) malloc( 1024*1024*4 );
+
+ return self;
+}
+
+/*
+ * Resize ourself
+ */
+- (void) reshape
+{
+ NSRect bounds;
+
+ [[self openGLContext] update];
+ bounds = [self bounds];
+ glViewport( 0, 0, (GLsizei) bounds.size.width,
+ (GLsizei) bounds.size.height );
+}
+
+- (void) drawAnimation: (int) how
+{
+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+ glMatrixMode( GL_PROJECTION );
+ glLoadIdentity();
+ glFrustum( -1.0, 1.0, -1.0, 1.0, PROUT, 20.0 );
+ 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 )
+ {
+ 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 );
+ }
+ 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 );
+ }
+ glEnd();
+
+ [[self openGLContext] flushBuffer];
}
-/* Override the view's drawRect: to draw our GL content */
- (void) drawRect: (NSRect) rect
{
- glViewport( 0, 0, (GLsizei) rect.size.width,
- (GLsizei) rect.size.height );
+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
- /* Black background */
- glClearColor( 0, 0, 0, 0 );
- glClear( GL_COLOR_BUFFER_BIT );
+ if( !fPicture )
+ {
+ return;
+ }
- /* Show it */
- if( fPicture )
- {
- glDrawPixels( fTitle->fOutWidthMax + 2,
- fTitle->fOutHeightMax + 2, GL_RGBA,
- GL_UNSIGNED_BYTE, fPicture );
- }
+ glDrawPixels( fTitle->outWidthMax + 2,
+ fTitle->outHeightMax + 2, GL_RGBA,
+ GL_UNSIGNED_BYTE, fPicture );
- [[self openGLContext] flushBuffer];
+ [[self openGLContext] flushBuffer];
}
@end
diff --git a/macosx/TargetSizeField.h b/macosx/TargetSizeField.h
index 12224cae7..6bc4a716f 100644
--- a/macosx/TargetSizeField.h
+++ b/macosx/TargetSizeField.h
@@ -1,12 +1,12 @@
-/* $Id: TargetSizeField.h,v 1.2 2003/10/09 23:33:36 titer Exp $
+/* $Id: TargetSizeField.h,v 1.1.1.1 2003/11/03 12:03:51 titer Exp $
This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
+ Homepage: <http://handbrake.m0k.org/>.
It may be used under the terms of the GNU General Public License. */
#include <Cocoa/Cocoa.h>
-#include "Common.h"
+#include "HandBrake.h"
@interface HBTargetSizeField : NSTextField
diff --git a/macosx/TargetSizeField.mm b/macosx/TargetSizeField.mm
index 0c43701fb..bde9f0ec2 100644
--- a/macosx/TargetSizeField.mm
+++ b/macosx/TargetSizeField.mm
@@ -1,7 +1,7 @@
-/* $Id: TargetSizeField.mm,v 1.4 2003/10/09 23:33:36 titer Exp $
+/* $Id: TargetSizeField.mm,v 1.1.1.1 2003/11/03 12:03:51 titer Exp $
This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
+ Homepage: <http://handbrake.m0k.org/>.
It may be used under the terms of the GNU General Public License. */
#include "TargetSizeField.h"
@@ -41,14 +41,14 @@
/* Video chunk headers (8 bytes / frame)
and index (16 bytes / frame) */
- available -= 24 * fTitle->fLength * fTitle->fRate / fTitle->fScale;
+ available -= 24 * fTitle->length * fTitle->rate / fTitle->rateBase;
/* Audio tracks */
available -= ( ( [[fSecondaryLanguagePopUp titleOfSelectedItem]
compare: @"None"] == NSOrderedSame ) ? 1 : 2 ) *
- ( fTitle->fLength *
+ ( fTitle->length *
[[fAudioBitratePopUp titleOfSelectedItem] intValue] *
- 128 + 24 * fTitle->fLength * 44100 / 1152 );
+ 128 + 24 * fTitle->length * 44100 / 1152 );
if( available < 0 )
{
@@ -57,7 +57,7 @@
else
{
[fBitrateField setIntValue:
- available / ( 128 * fTitle->fLength )];
+ available / ( 128 * fTitle->length )];
}
}
diff --git a/macosx/main.mm b/macosx/main.mm
index 56aa102fa..bd649f8ba 100644
--- a/macosx/main.mm
+++ b/macosx/main.mm
@@ -1,7 +1,7 @@
-/* $Id: main.mm,v 1.5 2003/09/30 14:38:15 titer Exp $
+/* $Id: main.mm,v 1.1.1.1 2003/11/03 12:03:51 titer Exp $
This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
+ Homepage: <http://handbrake.m0k.org/>.
It may be used under the terms of the GNU General Public License. */
#import <Cocoa/Cocoa.h>
diff --git a/test/Test.cpp b/test/Test.cpp
deleted file mode 100644
index 4567f74b6..000000000
--- a/test/Test.cpp
+++ /dev/null
@@ -1,265 +0,0 @@
-/* $Id: Test.cpp,v 1.8 2003/10/13 10:58:24 titer Exp $
-
- This file is part of the HandBrake source code.
- Homepage: <http://beos.titer.org/handbrake/>.
- It may be used under the terms of the GNU General Public License. */
-
-#include <signal.h>
-
-#include "Manager.h"
-
-volatile bool die;
-
-void SigHandler( int signal )
-{
- die = true;
-}
-
-int main( int argc, char ** argv )
-{
- die = false;
-
- /* Exit ASAP on Ctrl-C */
- signal( SIGINT, SigHandler );
-
- /* Default values */
- bool debug = false;
- char * device = NULL;
- char * outputFile = NULL;
- int titleIdx = 1;
- int audio1Idx = 1;
- int audio2Idx = 0;
- bool twoPass = false;
- bool deinterlace = false;
- int width = 0;
- int topCrop = 0;
- int bottomCrop = 0;
- int leftCrop = 0;
- int rightCrop = 0;
- int cpuCount = 0;
- int vBitrate = 1024;
- int aBitrate = 128;
-
- /* Parse command line */
- int c;
- while( ( c = getopt( argc, argv, "vd:o:t:a:b:piw:j:k:l:m:c:e:f:" ) ) != -1 )
- {
- switch( c )
- {
- case 'v':
- debug = true;
- break;
-
- case 'd':
- device = strdup( optarg );
- break;
-
- case 'o':
- outputFile = strdup( optarg );
- break;
-
- case 't':
- titleIdx = atoi( optarg );
- break;
-
- case 'a':
- audio1Idx = atoi( optarg );
- break;
-
- case 'b':
- audio2Idx = atoi( optarg );
- break;
-
- case 'p':
- twoPass = true;
- break;
-
- case 'i':
- deinterlace = true;
- break;
-
- case 'w':
- width = atoi( optarg );
- break;
-
- case 'j':
- topCrop = atoi( optarg );
- break;
-
- case 'k':
- bottomCrop = atoi( optarg );
- break;
-
- case 'l':
- leftCrop = atoi( optarg );
- break;
-
- case 'm':
- rightCrop = atoi( optarg );
- break;
-
- case 'c':
- cpuCount = atoi( optarg );
- break;
-
- case 'e':
- vBitrate = atoi( optarg );
- break;
-
- case 'f':
- aBitrate = atoi( optarg );
- break;
-
- default:
- break;
- }
- }
-
- /* Check parsed options */
- if( !device || !outputFile )
- {
- fprintf( stderr,
- "Syntax: HBTest [options] -d <device> -o <file>\n"
- "Possible options are :\n"
- " -v verbose output\n"
- " -t <value> select a title (default is 1)\n"
- " -a <value> primary audio channel (default is 1)\n"
- " -b <value> secondary audio channel (default is none)\n"
- " -p 2-pass encoding\n"
- " -i deinterlace picture\n"
- " -w output width\n"
- " -j <value> top cropping\n"
- " -k <value> bottom cropping\n"
- " -l <value> left cropping\n"
- " -m <value> right cropping\n"
- " -c <value> CPU count\n"
- " -e <value> Video bitrate (default is 1024)\n"
- " -f <value> Audio bitrate (default is 128)\n" );
- return 1;
- }
-
- /* Create the manager thread */
- HBManager * manager = new HBManager( debug, cpuCount );
-
- /* Tell the manager to scan the specified volume */
- manager->ScanVolumes( device );
-
- HBStatus status;
- while( !die )
- {
- if( !manager->NeedUpdate() )
- {
- Snooze( 10000 );
- continue;
- }
-
- status = manager->GetStatus();
-
- switch( status.fMode )
- {
- case HB_MODE_UNDEF:
- break;
-
- case HB_MODE_SCANNING:
- if( !status.fScannedTitle )
- {
- fprintf( stderr, "Scanning %s\n",
- status.fScannedVolume );
- }
- else
- {
- fprintf( stderr, "Scanning %s, title %d\n",
- status.fScannedVolume,
- status.fScannedTitle );
- }
- break;
-
- case HB_MODE_READY_TO_RIP:
- {
- /* Find the title */
- HBTitle * title = NULL;
- for( uint32_t i = 0; i < status.fTitleList->CountItems(); i++ )
- {
- title = (HBTitle*) status.fTitleList->ItemAt( i );
- if( title->fIndex == titleIdx )
- {
- break;
- }
- else
- {
- title = NULL;
- }
- }
-
- if( !title )
- {
- fprintf( stderr, "Error: unvalid title. Possible "
- "choices are: " );
- for( uint32_t i = 0;
- i < status.fTitleList->CountItems(); i++ )
- {
- title = (HBTitle*) status.fTitleList->ItemAt( i );
- fprintf( stderr, "%d%s", title->fIndex,
- ( i == status.fTitleList->CountItems() - 1 )
- ? ".\n" : ", " );
- }
- die = true;
- break;
- }
- title->fTwoPass = twoPass;
- title->fDeinterlace = deinterlace;
- if( width ) title->fOutWidth = width;
- title->fTopCrop = topCrop;
- title->fBottomCrop = bottomCrop;
- title->fLeftCrop = leftCrop;
- title->fRightCrop = rightCrop;
- title->fBitrate = vBitrate;
-
- HBAudio * audio1 =
- (HBAudio*) title->fAudioList->ItemAt( audio1Idx - 1 );
- HBAudio * audio2 =
- (HBAudio*) title->fAudioList->ItemAt( audio2Idx - 1 );
- if( audio1 ) audio1->fOutBitrate = aBitrate;
- if( audio2 ) audio2->fOutBitrate = aBitrate;
-
- manager->StartRip( title, audio1, audio2, outputFile );
- break;
- }
-
- case HB_MODE_ENCODING:
- fprintf( stderr, "Progress = %.2f %%, %.2f fps "
- "(%02d:%02d:%02d remaining)\n",
- 100 * status.fPosition, status.fFrameRate,
- status.fRemainingTime / 3600,
- ( status.fRemainingTime % 3600 ) / 60,
- status.fRemainingTime % 60 );
- break;
-
- case HB_MODE_DONE:
- fprintf( stderr, "Done\n" );
- die = true;
- break;
-
- case HB_MODE_CANCELED:
- fprintf( stderr, "Canceled\n" );
- die = true;
- break;
-
- case HB_MODE_ERROR:
- fprintf( stderr, "Error\n" );
- die = true;
- break;
-
- default:
- break;
- }
- }
-
- delete manager;
-
- if( device ) free( device );
- if( outputFile ) free( outputFile );
-
- return 0;
-}
-
diff --git a/test/test.c b/test/test.c
new file mode 100644
index 000000000..ec576cbb3
--- /dev/null
+++ b/test/test.c
@@ -0,0 +1,237 @@
+/* $Id: test.c,v 1.5 2003/11/06 13:28:07 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 <signal.h>
+
+#include "HandBrake.h"
+
+volatile int die;
+
+void SigHandler( int signal )
+{
+ die = 1;
+}
+
+int main( int argc, char ** argv )
+{
+ int c;
+ HBHandle * h;
+ HBStatus s;
+
+ /* Default values */
+ int debug = 1;
+ char * device = NULL;
+ char * file = NULL;
+ int titleIdx = 1;
+ int audio1Idx = 1;
+ int audio2Idx = 0;
+ int twoPass = 0;
+ int deinterlace = 0;
+ int width = 0;
+ int topCrop = 0;
+ int bottomCrop = 0;
+ int leftCrop = 0;
+ int rightCrop = 0;
+ int cpuCount = 0;
+ int vBitrate = 1024;
+ int aBitrate = 128;
+ int xvid = 0;
+
+ die = 0;
+
+ /* Exit ASAP on Ctrl-C */
+ signal( SIGINT, SigHandler );
+
+ /* Parse command line */
+ while( ( c = getopt( argc, argv, "qd:o:t:a:b:piw:j:k:l:m:c:e:f:x" ) ) != -1 )
+ {
+ switch( c )
+ {
+ case 'q':
+ debug = 0;
+ break;
+
+ case 'd':
+ device = strdup( optarg );
+ break;
+
+ case 'o':
+ file = strdup( optarg );
+ break;
+
+ case 't':
+ titleIdx = atoi( optarg );
+ break;
+
+ case 'a':
+ audio1Idx = atoi( optarg );
+ break;
+
+ case 'b':
+ audio2Idx = atoi( optarg );
+ break;
+
+ case 'p':
+ twoPass = 1;
+ break;
+
+ case 'i':
+ deinterlace = 1;
+ break;
+
+ case 'w':
+ width = atoi( optarg );
+ break;
+
+ case 'j':
+ topCrop = atoi( optarg );
+ break;
+
+ case 'k':
+ bottomCrop = atoi( optarg );
+ break;
+
+ case 'l':
+ leftCrop = atoi( optarg );
+ break;
+
+ case 'm':
+ rightCrop = atoi( optarg );
+ break;
+
+ case 'c':
+ cpuCount = atoi( optarg );
+ break;
+
+ case 'e':
+ vBitrate = atoi( optarg );
+ break;
+
+ case 'f':
+ aBitrate = atoi( optarg );
+ break;
+
+ case 'x':
+ xvid = 1;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /* Check parsed options */
+ if( !device || !file )
+ {
+ fprintf( stderr,
+ "Syntax: HBTest [options] -d <device> -o <file>\n"
+ "Possible options are :\n"
+ " -q quiet output\n"
+ " -t <value> select a title (default is 1)\n"
+ " -a <value> primary audio channel (default is 1)\n"
+ " -b <value> secondary audio channel (default is none)\n"
+ " -p 2-pass encoding\n"
+ " -i deinterlace picture\n"
+ " -w output width\n"
+ " -j <value> top cropping\n"
+ " -k <value> bottom cropping\n"
+ " -l <value> left cropping\n"
+ " -m <value> right cropping\n"
+ " -c <value> CPU count (default: autodetected)\n"
+ " -e <value> Video bitrate (default is 1024)\n"
+ " -f <value> Audio bitrate (default is 128)\n"
+ " -x Use XviD instead of Ffmpeg\n" );
+ return 1;
+ }
+
+ /* Create the manager thread */
+ h = HBInit( debug, cpuCount );
+
+ while( !die )
+ {
+ HBSnooze( 100000 );
+
+ if( !HBGetStatus( h, &s ) )
+ continue;
+
+ switch( s.mode )
+ {
+ case HB_MODE_UNDEF:
+ /* Will never happen */
+ break;
+
+ case HB_MODE_NEED_DEVICE:
+ /* Feed libhb with a DVD to scan */
+ HBScanDevice( h, device, titleIdx );
+ break;
+
+ case HB_MODE_SCANNING:
+ /* s.scannedTitle: title scanned at the moment */
+ break;
+
+ case HB_MODE_INVALID_DEVICE:
+ die = 1;
+ break;
+
+ case HB_MODE_READY_TO_RIP:
+ {
+ HBAudio * audio1, * audio2;
+ HBTitle * title = HBListItemAt( s.titleList, 0 );
+
+ title->file = strdup( file );
+ title->twoPass = twoPass;
+ title->deinterlace = deinterlace;
+ if( width ) title->outWidth = width;
+ title->topCrop = topCrop;
+ title->bottomCrop = bottomCrop;
+ title->leftCrop = leftCrop;
+ title->rightCrop = rightCrop;
+ title->bitrate = vBitrate;
+ title->codec = xvid ? HB_CODEC_XVID : HB_CODEC_FFMPEG;
+
+ audio1 = HBListItemAt( title->audioList,
+ audio1Idx - 1 );
+ audio2 = HBListItemAt( title->audioList,
+ audio2Idx - 1 );
+ if( audio1 ) audio1->outBitrate = aBitrate;
+ if( audio2 ) audio2->outBitrate = aBitrate;
+
+ HBStartRip( h, title, audio1, audio2 );
+ break;
+ }
+
+ case HB_MODE_ENCODING:
+ /* s.position : current progress (0.0->1.0)
+ s.frameRate : average framerate
+ s.remainingTime: ... (in seconds) */
+ break;
+
+ case HB_MODE_DONE:
+ die = 1;
+ break;
+
+ case HB_MODE_CANCELED:
+ die = 1;
+ break;
+
+ case HB_MODE_ERROR:
+ /* s.error: error code */
+ die = 1;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ HBClose( &h );
+
+ if( device ) free( device );
+ if( file ) free( file );
+
+ return 0;
+}
+