summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhandbrake <[email protected]>2006-01-14 12:56:59 +0000
committerhandbrake <[email protected]>2006-01-14 12:56:59 +0000
commit452f36599a1ea52f3bd42361b534594568c428fd (patch)
tree7f53f79212cf524f0a13ed5ee2250992f21eabcb
parenta9a84221af31ca7d11d1aa182d8b152270203f9f (diff)
HandBrake 0.4
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@5 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r--Jamfile11
-rw-r--r--NEWS8
-rw-r--r--TODO6
-rw-r--r--beos/HandBrake.cpp47
-rw-r--r--beos/HandBrake.h10
-rw-r--r--beos/HandBrake.rsrcbin0 -> 4217 bytes
-rw-r--r--beos/MainWindow.cpp714
-rw-r--r--beos/MainWindow.h84
-rw-r--r--beos/RipView.cpp616
-rw-r--r--beos/RipView.h77
-rw-r--r--beos/ScanView.cpp280
-rw-r--r--beos/ScanView.h48
-rw-r--r--core/Ac3Decoder.cpp193
-rw-r--r--core/Ac3Decoder.h46
-rw-r--r--core/AviMuxer.cpp8
-rw-r--r--core/Common.cpp70
-rw-r--r--core/Common.h45
-rw-r--r--core/DVDReader.cpp10
-rw-r--r--core/Fifo.cpp5
-rw-r--r--core/Manager.cpp399
-rw-r--r--core/Manager.h11
-rw-r--r--core/Mp3Encoder.cpp172
-rw-r--r--core/Mp3Encoder.h19
-rw-r--r--core/Mpeg2Decoder.cpp119
-rw-r--r--core/Mpeg2Decoder.h13
-rw-r--r--core/Mpeg4Encoder.cpp114
-rw-r--r--core/Mpeg4Encoder.h15
-rw-r--r--core/MpegDemux.cpp230
-rw-r--r--core/MpegDemux.h19
-rw-r--r--core/Resizer.cpp122
-rw-r--r--core/Resizer.h23
-rw-r--r--core/Scanner.cpp66
-rw-r--r--core/Thread.cpp73
-rw-r--r--core/Thread.h11
-rw-r--r--core/Worker.cpp150
-rw-r--r--core/Worker.h27
-rw-r--r--macosx/Controller.h (renamed from macosx/HBController.h)52
-rw-r--r--macosx/Controller.mm (renamed from macosx/HBController.mm)363
-rw-r--r--macosx/English.lproj/InfoPlist.stringsbin488 -> 488 bytes
-rw-r--r--macosx/English.lproj/MainMenu.nib/classes.nib38
-rw-r--r--macosx/English.lproj/MainMenu.nib/info.nib18
-rw-r--r--macosx/English.lproj/MainMenu.nib/objects.nibbin14905 -> 17820 bytes
-rw-r--r--macosx/HandBrake.pbproj/project.pbxproj53
-rw-r--r--macosx/PictureGLView.h2
-rw-r--r--macosx/PictureGLView.mm2
-rw-r--r--macosx/TargetSizeField.h23
-rw-r--r--macosx/TargetSizeField.mm64
-rw-r--r--test/Test.cpp64
48 files changed, 2921 insertions, 1619 deletions
diff --git a/Jamfile b/Jamfile
index 31e4874a2..a900913d9 100644
--- a/Jamfile
+++ b/Jamfile
@@ -1,10 +1,10 @@
-# $Id: Jamfile,v 1.33 2003/10/06 21:21:27 titer Exp $
+# $Id: Jamfile,v 1.38 2003/10/13 23:46:41 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.
-HB_VERSION = 0.3 ;
+HB_VERSION = 0.4 ;
# Compilers
C++ = g++ ;
@@ -28,7 +28,7 @@ LINKLIBS = -ldvdplay -ldvdread -ldvdcss -lmpeg2 -lavcodec -la52 -lmp3lame ;
if $(OS) = BEOS
{
C++FLAGS += -Wno-multichar ;
- LINKLIBS += -lbe ;
+ LINKLIBS += -lbe -ltracker ;
}
else if $(OS) = LINUX
{
@@ -65,7 +65,7 @@ Library core/libhb : core/Ac3Decoder.cpp core/AviMuxer.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/Scanner.cpp core/Thread.cpp core/Worker.cpp ;
LinkLibraries HBTest : core/libhb.a ;
Main HBTest : test/Test.cpp ;
@@ -74,7 +74,8 @@ if $(OS) = BEOS
{
LinkLibraries HandBrake : core/libhb.a ;
Main HandBrake : beos/HandBrake.cpp beos/MainWindow.cpp
- beos/PictureWin.cpp ;
+ beos/PictureWin.cpp beos/ScanView.cpp
+ beos/RipView.cpp ;
}
if $(OS) = MACOSX
diff --git a/NEWS b/NEWS
index 9160a5509..b3bc5cb27 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,10 @@
-$Id: NEWS,v 1.9 2003/10/06 21:21:27 titer Exp $
+$Id: NEWS,v 1.11 2003/10/13 15:35:38 titer Exp $
+
+Changes between 0.3 and 0.4
+ - Better multithreading
+ - Allow the user to specify a target size instead of bitrate
+ - Misc GUI enhancements
+ - Use low-priority threads on OS X
Changes between 0.2 and 0.3
- OSX & Linux ports
diff --git a/TODO b/TODO
index fcbbe2a5e..127cc12a6 100644
--- a/TODO
+++ b/TODO
@@ -1,10 +1,8 @@
- General
- + Keep detecting DVDs after launching
- + Possible to specify a target size
+ Use the DVD name in popup and for the name of the created file
+ Show the current pass
+ + Should be able to boost the audio volume
- OSX port
- + Check thread priorities
- + "Ding" when done + window + "Ahuh"
+ Preview in a drawer
+ + Prompt before overwriting a file
diff --git a/beos/HandBrake.cpp b/beos/HandBrake.cpp
index b1b386a6d..b5f13196b 100644
--- a/beos/HandBrake.cpp
+++ b/beos/HandBrake.cpp
@@ -1,4 +1,4 @@
-/* $Id: HandBrake.cpp,v 1.6 2003/09/30 14:38:15 titer Exp $
+/* $Id: HandBrake.cpp,v 1.8 2003/10/13 22:23:02 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -11,42 +11,47 @@
void SigHandler( int signal )
{
+ /* Ugly way to exit cleanly when hitting Ctrl-C */
((HBApp*) be_app)->fWindow->PostMessage( B_QUIT_REQUESTED );
}
-int main( int argc, char ** argv )
+int main()
{
signal( SIGINT, SigHandler );
signal( SIGHUP, SigHandler );
signal( SIGQUIT, SigHandler );
- int c;
- bool debug = false;
- while( ( c = getopt( argc, argv, "v" ) ) != -1 )
- {
- switch( c )
- {
- case 'v':
- debug = true;
- break;
-
- default:
- break;
- }
- }
-
/* Run the BApplication */
- HBApp * app = new HBApp( debug );
+ HBApp * app = new HBApp();
app->Run();
delete app;
return 0;
}
/* Constructor */
-HBApp::HBApp( bool debug )
- : BApplication( "application/x-vnd.titer-handbrake" )
+HBApp::HBApp()
+ : BApplication("application/x-vnd.titer-handbrake" )
{
- fWindow = new HBWindow( debug );
+ fWindow = new MainWindow();
fWindow->Show();
}
+void HBApp::MessageReceived( BMessage * message )
+{
+ switch( message->what )
+ {
+ case B_SAVE_REQUESTED:
+ fWindow->PostMessage( message );
+ break;
+
+ default:
+ BApplication::MessageReceived( message );
+ break;
+ }
+}
+
+void HBApp::RefsReceived( BMessage * message )
+{
+ fWindow->PostMessage( message );
+}
+
diff --git a/beos/HandBrake.h b/beos/HandBrake.h
index 72234e195..7035b5487 100644
--- a/beos/HandBrake.h
+++ b/beos/HandBrake.h
@@ -1,4 +1,4 @@
-/* $Id: HandBrake.h,v 1.5 2003/09/30 14:38:15 titer Exp $
+/* $Id: HandBrake.h,v 1.7 2003/10/13 22:23:02 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -9,14 +9,16 @@
#include <Application.h>
-class HBWindow;
+class MainWindow;
class HBApp : public BApplication
{
public:
- HBApp( bool debug );
+ HBApp();
+ void MessageReceived( BMessage * message );
+ void RefsReceived( BMessage * message );
- HBWindow * fWindow;
+ MainWindow * fWindow;
};
#endif
diff --git a/beos/HandBrake.rsrc b/beos/HandBrake.rsrc
new file mode 100644
index 000000000..d9f87ee44
--- /dev/null
+++ b/beos/HandBrake.rsrc
Binary files differ
diff --git a/beos/MainWindow.cpp b/beos/MainWindow.cpp
index ca18537a5..613cf21df 100644
--- a/beos/MainWindow.cpp
+++ b/beos/MainWindow.cpp
@@ -1,248 +1,50 @@
-/* $Id: MainWindow.cpp,v 1.14 2003/10/05 14:56:38 titer Exp $
+/* $Id: MainWindow.cpp,v 1.19 2003/10/13 22:23:02 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 <fs_info.h>
-#include <sys/ioctl.h>
#include <Alert.h>
#include <Application.h>
-#include <Box.h>
-#include <Button.h>
-#include <Directory.h>
-#include <Drivers.h>
-#include <MenuField.h>
-#include <Path.h>
-#include <Query.h>
-#include <PopUpMenu.h>
#include <Screen.h>
-#include <Slider.h>
-#include <StatusBar.h>
-#include <StringView.h>
-#include <TextControl.h>
-#include <VolumeRoster.h>
-#include "MainWindow.h"
#include "Manager.h"
-#include "PictureWin.h"
-
-#define DEFAULT_FILE "/boot/home/Desktop/Movie.avi"
-#define WINDOW_RECT BRect( 0,0,400,405 )
-
-#define BUTTON_ADVANCED 'badv'
-#define BUTTON_FILE 'bfil'
-#define BUTTON_PICTURE 'bpic'
-#define BUTTON_START 'bsta'
-#define BUTTON_CANCEL 'bcan'
-#define BUTTON_SUSPEND 'bsus'
-#define BUTTON_RESUME 'bres'
-#define POPUP_AUDIO 'paud'
-#define POPUP_TITLE 'ptit'
-#define POPUP_VOLUME 'pvol'
-#define SLIDER_AUDIO 'saud'
-#define SLIDER_VIDEO 'svid'
-
-/* HBBox : almost a simple BBox, unless we draw a horizontal line
- before the "Picture" and "Advanced" buttons. There must be a
- cleaner way to do this, but I'm not a expert GUI programmer. */
-
-/* Constructor */
-HBBox::HBBox( BRect rect )
- : BBox( rect, NULL )
-{
-}
-
-/* Draw */
-void HBBox::Draw( BRect rect )
-{
- /* Inherited method */
- BBox::Draw( rect );
-
- /* Draw the line */
- SetHighColor( 120, 120, 120 );
- SetLowColor( 255, 255, 255 );
- StrokeLine( BPoint( 10, 265 ),
- BPoint( Bounds().Width() - 10, 265 ),
- B_SOLID_HIGH );
- StrokeLine( BPoint( 11, 266 ),
- BPoint( Bounds().Width() - 10, 266 ),
- B_SOLID_LOW );
-}
-
-HBVolumeItem::HBVolumeItem( HBVolume * volume )
- : BMenuItem( "", new BMessage( POPUP_VOLUME ) )
-{
- fVolume = volume;
-
- SetLabel( fVolume->fName );
-}
-
-HBTitleItem::HBTitleItem( HBTitle * title )
- : BMenuItem( "", new BMessage( POPUP_TITLE) )
-{
- fTitle = title;
-
- char label[1024]; memset( label, 0, 1024 );
- sprintf( label, "%d (%02lld:%02lld:%02lld)", fTitle->fIndex,
- fTitle->fLength / 3600, ( fTitle->fLength % 3600 ) / 60,
- fTitle->fLength % 60 );
- SetLabel( label );
-}
-
-HBAudioItem::HBAudioItem( HBAudio * audio )
- : BMenuItem( "", new BMessage( POPUP_AUDIO ) )
-{
- fAudio = audio;
-
- SetLabel( fAudio ? fAudio->fDescription : "None" );
-}
+#include "MainWindow.h"
+#include "ScanView.h"
+#include "RipView.h"
-HBWindow::HBWindow( bool debug )
- : BWindow( WINDOW_RECT, "HandBrake " VERSION, B_TITLED_WINDOW,
+MainWindow::MainWindow()
+ : BWindow( BRect( 0,0,10,10 ), "HandBrake " VERSION, B_TITLED_WINDOW,
B_NOT_RESIZABLE | B_NOT_ZOOMABLE )
{
- /* Center the window */
- BScreen screen;
- MoveTo( ( screen.Frame().Width() - Frame().Width() ) / 2,
- ( screen.Frame().Height() - Frame().Height() ) / 2 );
-
- /* -- GUI starts here -- */
-
- BRect r;
-
- /* Add a background view */
- BView * view;
- view = new BView( Bounds(), NULL, B_FOLLOW_ALL, B_WILL_DRAW );
- view->SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) );
-
- /* Add the settings box */
- r = BRect( 10, 10, view->Bounds().Width() - 10,
- view->Bounds().Height() - 85 );
- fBox = new HBBox( r );
- fBox->SetLabel( "Settings" );
-
- /* Volume */
- r = BRect( 10, 15, fBox->Bounds().Width() - 10, 35 );
- fVolumePopUp = new BPopUpMenu( "" );
- fVolumeField = new BMenuField( r, NULL, "Volume :",
- fVolumePopUp, true );
- fBox->AddChild( fVolumeField );
-
- /* Title */
- r = BRect( 10, 45, fBox->Bounds().Width() - 10, 65 );
- fTitlePopUp = new BPopUpMenu( "" );
- fTitleField = new BMenuField( r, NULL, "Title :",
- fTitlePopUp, true );
- fBox->AddChild( fTitleField );
-
- /* Audio 1 */
- r = BRect( 10, 75, fBox->Bounds().Width() - 10, 95 );
- fAudio1PopUp = new BPopUpMenu( "" );
- fAudio1Field = new BMenuField( r, NULL, "Audio 1 :",
- fAudio1PopUp, true );
- fBox->AddChild( fAudio1Field );
-
- /* Audio 2 */
- r = BRect( 10, 105, fBox->Bounds().Width() - 10, 125 );
- fAudio2PopUp = new BPopUpMenu( "" );
- fAudio2Field = new BMenuField( r, NULL, "Audio 2 :",
- fAudio2PopUp, true );
- fBox->AddChild( fAudio2Field );
-
- /* Video bitrate */
- r = BRect( 10, 135, fBox->Bounds().Width() - 10, 165 );
- fVideoSlider = new BSlider( r, NULL, "Video bitrate : 1024 kbps",
- new BMessage( SLIDER_VIDEO ),
- 128, 4096, B_TRIANGLE_THUMB );
- fVideoSlider->SetValue( 1024 );
- fBox->AddChild( fVideoSlider );
-
- /* Audio bitrate */
- r = BRect( 10, 175, fBox->Bounds().Width() - 10, 205 );
- fAudioSlider = new BSlider( r, NULL, "Audio bitrate : 128 kbps",
- new BMessage( SLIDER_AUDIO ),
- 64, 384, B_TRIANGLE_THUMB );
- fAudioSlider->SetValue( 128 );
- fBox->AddChild( fAudioSlider );
-
- /* Destination file */
- r = BRect( 10, 215, fBox->Bounds().Width() - 10, 230 );
- fFileString = new BStringView( r, NULL, "Destination file :" );
- fBox->AddChild( fFileString );
- r = BRect( 10, 235, fBox->Bounds().Width() - 90, 255 );
- fFileControl = new BTextControl( r, NULL, "", DEFAULT_FILE,
- new BMessage() );
- fFileControl->SetDivider( 0 );
- fBox->AddChild( fFileControl );
- r = BRect( fBox->Bounds().Width() - 80, 230,
- fBox->Bounds().Width() - 10, 255 );
- fFileButton = new BButton( r, NULL, "Browse...",
- new BMessage( BUTTON_FILE ) );
- fBox->AddChild( fFileButton );
-
- /* Settings buttons */
- r = BRect( fBox->Bounds().Width() - 200, 275,
- fBox->Bounds().Width() - 100, 300 );
- fPictureButton = new BButton( r, NULL, "Picture settings...",
- new BMessage( BUTTON_PICTURE ) );
- fBox->AddChild( fPictureButton );
-
- r = BRect( fBox->Bounds().Width() - 90, 275,
- fBox->Bounds().Width() - 10, 300 );
- fAdvancedButton = new BButton( r, NULL, "Advanced...",
- new BMessage( BUTTON_ADVANCED ) );
- fBox->AddChild( fAdvancedButton );
-
- view->AddChild( fBox );
-
- /* Status bar */
- r = BRect( 10, view->Bounds().Height() - 75,
- view->Bounds().Width() - 10, view->Bounds().Height() - 45 );
- fStatusBar = new BStatusBar( r, NULL, NULL );
- fStatusBar->SetMaxValue( 1.0 );
- view->AddChild( fStatusBar );
-
- /* Buttons */
- r = BRect( view->Bounds().Width() - 240, view->Bounds().Height() - 35,
- view->Bounds().Width() - 170, view->Bounds().Height() - 10 );
- BButton * aboutButton;
- aboutButton = new BButton( r, NULL, "About...",
- new BMessage( B_ABOUT_REQUESTED ) );
- view->AddChild( aboutButton );
-
- r = BRect( view->Bounds().Width() - 160, view->Bounds().Height() - 35,
- view->Bounds().Width() - 90, view->Bounds().Height() - 10 );
- fSuspendButton = new BButton( r, NULL, "Suspend",
- new BMessage( BUTTON_SUSPEND ) );
- view->AddChild( fSuspendButton );
-
- r = BRect( view->Bounds().Width() - 80, view->Bounds().Height() - 35,
- view->Bounds().Width() - 10, view->Bounds().Height() - 10 );
- fStartButton = new BButton( r, NULL, "Start !",
- new BMessage( BUTTON_START ) );
- view->AddChild( fStartButton );
-
- AddChild( view );
-
- /* -- GUI ends here -- */
-
/* Init libhb & launch the manager thread */
- fManager = new HBManager( debug );
+ fManager = new HBManager( true );
- /* Detects DVD drives & VOB folders, then tell libhb to scan it */
- ScanVolumes();
+ /* Add the scan view */
+ fScanView = new ScanView( fManager );
+ fRipView = new RipView( fManager );
+ 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 );
/* Update the interface */
+ fDie = false;
fUpdateThread = spawn_thread( (int32 (*)(void *)) UpdateInterface,
"interface", B_DISPLAY_PRIORITY, this );
resume_thread( fUpdateThread );
}
-bool HBWindow::QuitRequested()
+bool MainWindow::QuitRequested()
{
/* Clean up */
- kill_thread( fUpdateThread );
+ fDie = true;
+ long exit_value;
+ wait_for_thread( fUpdateThread, &exit_value );
delete fManager;
/* Stop the application */
@@ -250,7 +52,7 @@ bool HBWindow::QuitRequested()
return true;
}
-void HBWindow::MessageReceived( BMessage * message )
+void MainWindow::MessageReceived( BMessage * message )
{
switch( message->what )
{
@@ -269,209 +71,44 @@ void HBWindow::MessageReceived( BMessage * message )
break;
}
- case BUTTON_ADVANCED:
- break;
-
- case BUTTON_FILE:
- break;
-
- case BUTTON_PICTURE:
- {
- HBTitle * title =
- ((HBTitleItem*) fTitlePopUp->FindMarked())->fTitle;
- HBPictureWin * pictureWin = new HBPictureWin( fManager, title );
- pictureWin->Show();
+ case B_REFS_RECEIVED:
+ case SCAN_RADIO:
+ case SCAN_BROWSE_BUTTON:
+ case SCAN_OPEN:
+ fScanView->MessageReceived( message );
break;
- }
-
- case BUTTON_START:
- {
- HBTitle * title =
- ((HBTitleItem*) fTitlePopUp->FindMarked())->fTitle;
- HBAudio * audio1 =
- ((HBAudioItem*) fAudio1PopUp->FindMarked())->fAudio;
- HBAudio * audio2 =
- ((HBAudioItem*) fAudio2PopUp->FindMarked())->fAudio;
-
- title->fBitrate = fVideoSlider->Value();
- if( audio1 )
- {
- audio1->fOutBitrate = fAudioSlider->Value();
- }
- if( audio2 )
- {
- audio2->fOutBitrate = fAudioSlider->Value();
- }
- fManager->StartRip( title, audio1, audio2,
- (char*) fFileControl->Text() );
+ case B_SAVE_REQUESTED:
+ case RIP_TITLE_POPUP:
+ case RIP_BITRATE_RADIO:
+ case RIP_TARGET_CONTROL:
+ case RIP_CROP_BUTTON:
+ case RIP_BROWSE_BUTTON:
+ case RIP_SUSPEND_BUTTON:
+ case RIP_RIP_BUTTON:
+ fRipView->MessageReceived( message );
break;
- }
-
- case BUTTON_CANCEL:
- fManager->StopRip();
- break;
-
- case BUTTON_SUSPEND:
- fManager->SuspendRip();
- break;
-
- case BUTTON_RESUME:
- fManager->ResumeRip();
- break;
-
- case POPUP_AUDIO:
- break;
-
- case POPUP_TITLE:
- {
- HBTitle * title =
- ((HBTitleItem*) fTitlePopUp->FindMarked())->fTitle;
-
- /* Empty audio popups */
- HBAudioItem * audioItem;
- while( ( audioItem = (HBAudioItem*) fAudio1PopUp->ItemAt( 0 ) ) )
- {
- fAudio1PopUp->RemoveItem( audioItem );
- delete audioItem;
- }
- while( ( audioItem = (HBAudioItem*) fAudio2PopUp->ItemAt( 0 ) ) )
- {
- fAudio2PopUp->RemoveItem( audioItem );
- delete audioItem;
- }
-
- HBAudio * audio;
- for( uint32_t i = 0;
- i < title->fAudioList->CountItems();
- i++ )
- {
- audio = (HBAudio*) title->fAudioList->ItemAt( i );
- fAudio1PopUp->AddItem( new HBAudioItem( audio ) );
- fAudio2PopUp->AddItem( new HBAudioItem( audio ) );
- }
- fAudio1PopUp->AddItem( new HBAudioItem( NULL ) );
- fAudio2PopUp->AddItem( new HBAudioItem( NULL ) );
- ((HBAudioItem*) fAudio1PopUp->ItemAt( 0 ))->SetMarked( true );
- ((HBAudioItem*) fAudio2PopUp->ItemAt(
- fAudio2PopUp->CountItems() - 1 ))->SetMarked( true );
-
- break;
- }
-
- case POPUP_VOLUME:
- break;
-
- case SLIDER_AUDIO:
- {
- char label[64]; memset( label, 0, 64 );
- snprintf( label, 128, "Audio bitrate : %ld kbps",
- fAudioSlider->Value() );
- fAudioSlider->SetLabel( label );
- break;
- }
-
- case SLIDER_VIDEO:
- {
- char label[64]; memset( label, 0, 64 );
- snprintf( label, 128, "Video bitrate : %ld kbps",
- fVideoSlider->Value() );
- fVideoSlider->SetLabel( label );
- break;
- }
-
+
default:
BWindow::MessageReceived( message );
break;
}
}
-
-void HBWindow::ScanVolumes()
+void MainWindow::UpdateInterface( MainWindow * _this )
{
- BVolumeRoster * roster = new BVolumeRoster();
- BVolume * bVolume = new BVolume();
- fs_info info;
- int device;
- device_geometry geometry;
-
- HBVolume * volume;
- HBList * volumeList = new HBList();
+ uint64_t time;
- /* Parse mounted volumes */
- while( roster->GetNextVolume( bVolume ) == B_NO_ERROR )
- {
- /* open() and ioctl() for more informations */
- fs_stat_dev( bVolume->Device(), &info );
- if( ( device = open( info.device_name, O_RDONLY ) ) < 0 )
- {
- continue;
- }
-
- if( ioctl( device, B_GET_GEOMETRY, &geometry,
- sizeof( geometry ) ) < 0 )
-
- {
- continue;
- }
-
- /* Get the volume name */
- char volumeName[B_FILE_NAME_LENGTH];
- bVolume->GetName( volumeName );
-
- if( bVolume->IsReadOnly() && geometry.device_type == B_CD )
- {
- /* May be a DVD */
- volume = new HBVolume( info.device_name, volumeName );
- volumeList->AddItem( volume );
- }
- else if( geometry.device_type == B_DISK )
- {
- /* May be a hard drive. Look for VIDEO_TS folders on it */
- BQuery * query = new BQuery();
-
- if( query->SetVolume( bVolume ) != B_OK )
- {
- delete query;
- continue;
- }
-
- if( query->SetPredicate( "name = VIDEO_TS.BUP" ) != B_OK )
- {
- delete query;
- continue;
- }
-
- query->Fetch();
-
- BEntry entry, parentEntry;
- BPath path;
- while( query->GetNextEntry( &entry ) == B_OK )
- {
- entry.GetParent( &parentEntry );
- parentEntry.GetPath( &path );
-
- volume = new HBVolume( (char*) path.Path() );
- volumeList->AddItem( volume );
- }
-
- delete query;
- }
- }
-
- fManager->ScanVolumes( volumeList );
-}
-
-void HBWindow::UpdateInterface( HBWindow * _this )
-{
- for( ;; )
+ while( !_this->fDie )
{
+ /* Update every 0.1 sec */
+ time = system_time();
_this->_UpdateInterface();
- snooze( 10000 );
+ snooze( 100000 - ( system_time() - time ) );
}
}
-void HBWindow::_UpdateInterface()
+void MainWindow::_UpdateInterface()
{
if( !fManager->NeedUpdate() )
{
@@ -486,97 +123,31 @@ void HBWindow::_UpdateInterface()
return;
}
- EnableInterface( status.fMode );
-
switch( status.fMode )
{
case HB_MODE_UNDEF:
+ case HB_MODE_NEED_VOLUME:
break;
-
+
case HB_MODE_SCANNING:
- {
- char text[1024]; memset( text, 0, 1024 );
- sprintf( text, "Scanning %s, title %d...",
- status.fScannedVolume, status.fScannedTitle );
- fStatusBar->Update( - fStatusBar->CurrentValue(), text );
+ case HB_MODE_INVALID_VOLUME:
+ fScanView->UpdateIntf( status );
break;
- }
- case HB_MODE_SCANDONE:
- {
- HBVolume * volume;
- for( uint32_t i = 0;
- i < status.fVolumeList->CountItems();
- i++ )
- {
- volume = (HBVolume*) status.fVolumeList->ItemAt( i );
- fVolumePopUp->AddItem( new HBVolumeItem( volume ) );
- }
- ((HBVolumeItem*) fVolumePopUp->ItemAt( 0 ))->SetMarked( true );
-
- HBTitle * title;
- volume = (HBVolume*) status.fVolumeList->ItemAt( 0 );
- for( uint32_t i = 0;
- i < volume->fTitleList->CountItems();
- i++ )
- {
- title = (HBTitle*) volume->fTitleList->ItemAt( i );
- fTitlePopUp->AddItem( new HBTitleItem( title ) );
- }
- ((HBTitleItem*) fTitlePopUp->ItemAt( 0 ))->SetMarked( true );
-
- HBAudio * audio;
- title = (HBTitle*) volume->fTitleList->ItemAt( 0 );
- for( uint32_t i = 0;
- i < title->fAudioList->CountItems();
- i++ )
- {
- audio = (HBAudio*) title->fAudioList->ItemAt( i );
- fAudio1PopUp->AddItem( new HBAudioItem( audio ) );
- fAudio2PopUp->AddItem( new HBAudioItem( audio ) );
- }
- fAudio1PopUp->AddItem( new HBAudioItem( NULL ) );
- fAudio2PopUp->AddItem( new HBAudioItem( NULL ) );
- ((HBAudioItem*) fAudio1PopUp->ItemAt( 0 ))->SetMarked( true );
- ((HBAudioItem*) fAudio2PopUp->ItemAt(
- fAudio2PopUp->CountItems() - 1 ))->SetMarked( true );
-
- fStatusBar->Update( - fStatusBar->CurrentValue(),
- "Ready. Press 'Start' to rip." );
+ case HB_MODE_READY_TO_RIP:
+ RemoveChild( fScanView );
+ ResizeTo( fRipView->Bounds().Width(),
+ fRipView->Bounds().Height() );
+ AddChild( fRipView );
+ fRipView->UpdateIntf( status );
break;
- }
case HB_MODE_ENCODING:
- {
- char text[1024]; memset( text, 0, 1024 );
- sprintf( text,
- "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( status.fPosition -
- fStatusBar->CurrentValue(), text );
- break;
- }
-
case HB_MODE_SUSPENDED:
- {
- char text[1024]; memset( text, 0, 1024 );
- sprintf( text, "Encoding : %.2f %%, %.2f fps (Paused)",
- 100 * status.fPosition, status.fFrameRate );
- fStatusBar->Update( status.fPosition -
- fStatusBar->CurrentValue(), text );
- break;
- }
-
case HB_MODE_DONE:
- break;
-
case HB_MODE_CANCELED:
- break;
-
case HB_MODE_ERROR:
+ fRipView->UpdateIntf( status );
break;
default:
@@ -586,174 +157,3 @@ void HBWindow::_UpdateInterface()
Unlock();
}
-void HBWindow::EnableInterface( HBMode mode )
-{
- if( mode == fOldMode && mode != HB_MODE_UNDEF )
- {
- return;
- }
-
- switch( mode )
- {
- case HB_MODE_UNDEF:
- {
- fAdvancedButton->SetEnabled( false );
- fFileButton->SetEnabled( false );
- fPictureButton->SetEnabled( false );
- fStartButton->SetEnabled( false );
- fSuspendButton->SetEnabled( false );
- fAudio1Field->SetEnabled( false );
- fAudio2Field->SetEnabled( false );
- fTitleField->SetEnabled( false );
- fVolumeField->SetEnabled( false );
- fAudioSlider->SetEnabled( false );
- fVideoSlider->SetEnabled( false );
- fFileString->SetHighColor( 156, 156, 156 );
- fFileString->Invalidate();
- fFileControl->SetEnabled( false );
- break;
- }
-
- case HB_MODE_SCANNING:
- {
- fAdvancedButton->SetEnabled( true );
- fFileButton->SetEnabled( true );
- fPictureButton->SetEnabled( false );
- fStartButton->SetEnabled( false );
- fSuspendButton->SetEnabled( false );
- fAudio1Field->SetEnabled( false );
- fAudio2Field->SetEnabled( false );
- fTitleField->SetEnabled( false );
- fVolumeField->SetEnabled( false );
- fAudioSlider->SetEnabled( true );
- fVideoSlider->SetEnabled( true );
- fFileString->SetHighColor( 0, 0, 0 );
- fFileString->Invalidate();
- fFileControl->SetEnabled( true );
- break;
- }
-
- case HB_MODE_SCANDONE:
- {
- fAdvancedButton->SetEnabled( true );
- fFileButton->SetEnabled( true );
- fPictureButton->SetEnabled( true );
- fStartButton->SetLabel( "Start" );
- fStartButton->SetMessage( new BMessage( BUTTON_START ) );
- fStartButton->SetEnabled( true );
- fSuspendButton->SetEnabled( false );
- fAudio1Field->SetEnabled( true );
- fAudio2Field->SetEnabled( true );
- fTitleField->SetEnabled( true );
- fVolumeField->SetEnabled( true );
- fAudioSlider->SetEnabled( true );
- fVideoSlider->SetEnabled( true );
- fFileString->SetHighColor( 0, 0, 0 );
- fFileString->Invalidate();
- fFileControl->SetEnabled( true );
- break;
- }
-
- case HB_MODE_ENCODING:
- {
- fFileButton->SetEnabled( false );
- fPictureButton->SetEnabled( false );
- fStartButton->SetLabel( "Cancel" );
- fStartButton->SetMessage( new BMessage( BUTTON_CANCEL ) );
- fStartButton->SetEnabled( true );
- fSuspendButton->SetLabel( "Suspend" );
- fSuspendButton->SetMessage( new BMessage( BUTTON_SUSPEND ) );
- fSuspendButton->SetEnabled( true );
- fAudio1Field->SetEnabled( false );
- fAudio2Field->SetEnabled( false );
- fTitleField->SetEnabled( false );
- fVolumeField->SetEnabled( false );
- fAudioSlider->SetEnabled( false );
- fVideoSlider->SetEnabled( false );
- fFileString->SetHighColor( 156, 156, 156 );
- fFileString->Invalidate();
- fFileControl->SetEnabled( false );
- break;
- }
-
- case HB_MODE_SUSPENDED:
- {
- fFileButton->SetEnabled( false );
- fPictureButton->SetEnabled( false );
- fStartButton->SetLabel( "Cancel" );
- fStartButton->SetMessage( new BMessage( BUTTON_CANCEL ) );
- fStartButton->SetEnabled( true );
- fSuspendButton->SetLabel( "Resume" );
- fSuspendButton->SetMessage( new BMessage( BUTTON_RESUME ) );
- fSuspendButton->SetEnabled( true );
- fAudio1Field->SetEnabled( false );
- fAudio2Field->SetEnabled( false );
- fTitleField->SetEnabled( false );
- fVolumeField->SetEnabled( false );
- fAudioSlider->SetEnabled( false );
- fVideoSlider->SetEnabled( false );
- fFileString->SetHighColor( 156, 156, 156 );
- fFileString->Invalidate();
- fFileControl->SetEnabled( false );
- break;
- }
-
- case HB_MODE_DONE:
- {
- fFileButton->SetEnabled( false );
- fPictureButton->SetEnabled( false );
- fStartButton->SetEnabled( true );
- fSuspendButton->SetEnabled( true );
- fAudio1Field->SetEnabled( false );
- fAudio2Field->SetEnabled( false );
- fTitleField->SetEnabled( false );
- fVolumeField->SetEnabled( false );
- fAudioSlider->SetEnabled( false );
- fVideoSlider->SetEnabled( false );
- fFileString->SetHighColor( 156, 156, 156 );
- fFileString->Invalidate();
- fFileControl->SetEnabled( false );
- break;
- }
-
- case HB_MODE_CANCELED:
- {
- fFileButton->SetEnabled( false );
- fPictureButton->SetEnabled( false );
- fStartButton->SetEnabled( true );
- fSuspendButton->SetEnabled( true );
- fAudio1Field->SetEnabled( false );
- fAudio2Field->SetEnabled( false );
- fTitleField->SetEnabled( false );
- fVolumeField->SetEnabled( false );
- fAudioSlider->SetEnabled( false );
- fVideoSlider->SetEnabled( false );
- fFileString->SetHighColor( 156, 156, 156 );
- fFileString->Invalidate();
- fFileControl->SetEnabled( false );
- break;
- }
-
- case HB_MODE_ERROR:
- {
- fFileButton->SetEnabled( false );
- fPictureButton->SetEnabled( false );
- fStartButton->SetEnabled( true );
- fSuspendButton->SetEnabled( true );
- fAudio1Field->SetEnabled( false );
- fAudio2Field->SetEnabled( false );
- fTitleField->SetEnabled( false );
- fVolumeField->SetEnabled( false );
- fAudioSlider->SetEnabled( false );
- fVideoSlider->SetEnabled( false );
- fFileString->SetHighColor( 156, 156, 156 );
- fFileString->Invalidate();
- fFileControl->SetEnabled( false );
- break;
- }
-
- default:
- break;
- }
-}
-
diff --git a/beos/MainWindow.h b/beos/MainWindow.h
index e40c2587a..c4c32a711 100644
--- a/beos/MainWindow.h
+++ b/beos/MainWindow.h
@@ -1,4 +1,4 @@
-/* $Id: MainWindow.h,v 1.9 2003/09/30 14:38:15 titer Exp $
+/* $Id: MainWindow.h,v 1.10 2003/10/10 01:08:42 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -8,93 +8,29 @@
#ifndef HB_MAIN_WINDOW_H
#define HB_MAIN_WINDOW_H
-/* BeOS headers */
-#include <Box.h>
-#include <MenuItem.h>
#include <Window.h>
-class BButton;
-class BMenuField;
-class BPopUpMenu;
-class BSlider;
-class BStatusBar;
-class BStringView;
-class BTextControl;
+class ScanView;
+class RipView;
-/* libhb headers */
-#include "Manager.h"
+#include "Common.h"
-class HBVolumeItem : public BMenuItem
+class MainWindow : public BWindow
{
public:
- HBVolumeItem( HBVolume * volume );
-
- HBVolume * fVolume;
-};
-
-class HBTitleItem : public BMenuItem
-{
- public:
- HBTitleItem( HBTitle * title );
-
- HBTitle * fTitle;
-};
-
-class HBAudioItem : public BMenuItem
-{
- public:
- HBAudioItem( HBAudio * audio );
-
- HBAudio * fAudio;
-};
-
-class HBBox : public BBox
-{
- public:
- HBBox( BRect );
- void Draw( BRect );
-};
-
-class HBWindow : public BWindow
-{
- public:
- HBWindow( bool debug );
+ MainWindow();
virtual bool QuitRequested();
virtual void MessageReceived( BMessage * message );
- void ScanVolumes();
-
private:
- static void UpdateInterface( HBWindow * _this );
+ static void UpdateInterface( MainWindow * _this );
void _UpdateInterface();
- void EnableInterface( HBMode mode );
HBManager * fManager;
-
- /* GUI */
- HBBox * fBox;
- BButton * fAdvancedButton;
- BButton * fFileButton;
- BButton * fPictureButton;
- BButton * fStartButton;
- BButton * fSuspendButton;
- BMenuField * fAudio1Field;
- BMenuField * fAudio2Field;
- BMenuField * fTitleField;
- BMenuField * fVolumeField;
- BPopUpMenu * fAudio1PopUp;
- BPopUpMenu * fAudio2PopUp;
- BPopUpMenu * fTitlePopUp;
- BPopUpMenu * fVolumePopUp;
- BSlider * fAudioSlider;
- BSlider * fVideoSlider;
- BStatusBar * fStatusBar;
- BStringView * fFileString;
- BTextControl * fFileControl;
-
int fUpdateThread;
+ volatile bool fDie;
- /* Used to SetEnabled() GUI items only if needed */
- HBMode fOldMode;
+ ScanView * fScanView;
+ RipView * fRipView;
};
#endif
diff --git a/beos/RipView.cpp b/beos/RipView.cpp
new file mode 100644
index 000000000..180ba23ff
--- /dev/null
+++ b/beos/RipView.cpp
@@ -0,0 +1,616 @@
+/* $Id: RipView.cpp,v 1.6 2003/10/13 23:42:03 titer Exp $
+
+ This file is part of the HandBrake source code.
+ Homepage: <http://beos.titer.org/handbrake/>.
+ It may be used under the terms of the GNU General Public License. */
+
+#include <Box.h>
+#include <Button.h>
+#include <CheckBox.h>
+#include <FilePanel.h>
+#include <MenuField.h>
+#include <MenuItem.h>
+#include <Path.h>
+#include <PopUpMenu.h>
+#include <RadioButton.h>
+#include <StatusBar.h>
+#include <String.h>
+#include <TextControl.h>
+
+#include "RipView.h"
+#include "PictureWin.h"
+#include "Manager.h"
+
+#define DEFAULT_FILE "/boot/home/Desktop/Movie.avi"
+
+RipView::RipView( HBManager * manager )
+ : BView( BRect( 0,0,400,480 ), NULL, B_FOLLOW_ALL, B_WILL_DRAW )
+{
+ fManager = manager;
+
+ BRect r;
+ SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) );
+
+ /* Video box */
+ r = BRect( 10, 10, Bounds().Width() - 10, 160 );
+ fVideoBox = new BBox( r );
+ fVideoBox->SetLabel( "Video" );
+ AddChild( fVideoBox );
+
+ /* Title */
+ r = BRect( 10, 15, fVideoBox->Bounds().Width() - 10, 35 );
+ fTitlePopUp = new BPopUpMenu( "" );
+ fTitleField = new BMenuField( r, NULL, "Title:",
+ fTitlePopUp, true );
+ fVideoBox->AddChild( fTitleField );
+
+ /* Video codec */
+ r = BRect( 10, 40, fVideoBox->Bounds().Width() - 10, 60 );
+ fVideoCodecPopUp = new BPopUpMenu( "" );
+ fVideoCodecField = new BMenuField( r, NULL, "Codec:",
+ fVideoCodecPopUp, true );
+ fVideoBox->AddChild( fVideoCodecField );
+
+ /* Video bitrate */
+ r = BRect( 10, 65, fVideoBox->Bounds().Width() / 2, 85 );
+ fCustomBitrateRadio =
+ new BRadioButton( r, NULL, "Custom bitrate (kbps)",
+ new BMessage( RIP_BITRATE_RADIO ) );
+ fCustomBitrateRadio->SetValue( 1 );
+ fVideoBox->AddChild( fCustomBitrateRadio );
+ r = BRect( fVideoBox->Bounds().Width() - 80, 65,
+ fVideoBox->Bounds().Width() - 10, 85 );
+ fCustomBitrateControl = new BTextControl( r, NULL, NULL, "1024", NULL );
+ fCustomBitrateControl->SetDivider( 0 );
+ fVideoBox->AddChild( fCustomBitrateControl );
+ r = BRect( 10, 90, fVideoBox->Bounds().Width() / 2, 110 );
+ fTargetSizeRadio =
+ new BRadioButton( r, NULL, "Target size (MB)",
+ new BMessage( RIP_BITRATE_RADIO ) );
+ fVideoBox->AddChild( fTargetSizeRadio );
+ r = BRect( fVideoBox->Bounds().Width() - 80, 90,
+ fVideoBox->Bounds().Width() - 10, 110 );
+ fTargetSizeControl = new BTextControl( r, NULL, NULL, "700", NULL );
+ fTargetSizeControl->SetDivider( 0 );
+ fTargetSizeControl->SetEnabled( false );
+ fTargetSizeControl->SetModificationMessage(
+ new BMessage( RIP_TARGET_CONTROL ) );
+ fVideoBox->AddChild( fTargetSizeControl );
+
+ /* 2-pass */
+ r = BRect( 10, 125, fVideoBox->Bounds().Width() / 2, 140 );
+ fTwoPassCheck = new BCheckBox( r, NULL, "2-pass encoding", NULL );
+ fVideoBox->AddChild( fTwoPassCheck );
+
+ /* Crop */
+ r = BRect( fVideoBox->Bounds().Width() - 120, 120,
+ fVideoBox->Bounds().Width() - 10, 140 );
+ fCropButton = new BButton( r, NULL, "Crop & Resize...",
+ new BMessage( RIP_CROP_BUTTON ) );
+ fVideoBox->AddChild( fCropButton );
+
+ /* Audio box */
+ r = BRect( 10, 170, Bounds().Width() - 10, 290 );
+ fAudioBox = new BBox( r );
+ fAudioBox->SetLabel( "Audio" );
+ AddChild( fAudioBox );
+
+ /* Language */
+ r = BRect( 10, 15, fAudioBox->Bounds().Width() - 10, 35 );
+ fLanguagePopUp = new BPopUpMenu( "" );
+ fLanguageField = new BMenuField( r, NULL, "Language:",
+ fLanguagePopUp, true );
+ fAudioBox->AddChild( fLanguageField );
+
+ /* Secondary language */
+ r = BRect( 10, 40, fAudioBox->Bounds().Width() - 10, 60 );
+ fSecondaryLanguagePopUp = new BPopUpMenu( "" );
+ fSecondaryLanguageField = new BMenuField( r, NULL, "Secondary language:",
+ fSecondaryLanguagePopUp, true );
+ fAudioBox->AddChild( fSecondaryLanguageField );
+
+ /* Audio codec */
+ r = BRect( 10, 65, fAudioBox->Bounds().Width() - 10, 85 );
+ fAudioCodecPopUp = new BPopUpMenu( "" );
+ fAudioCodecField = new BMenuField( r, NULL, "Codec:",
+ fAudioCodecPopUp, true );
+ fAudioBox->AddChild( fAudioCodecField );
+
+ /* Audio bitrate */
+ r = BRect( 10, 90, fAudioBox->Bounds().Width() - 10, 110 );
+ fAudioBitratePopUp = new BPopUpMenu( "" );
+ fAudioBitrateField = new BMenuField( r, NULL, "Bitrate:",
+ fAudioBitratePopUp, true );
+ fAudioBox->AddChild( fAudioBitrateField );
+
+ /* Destination box */
+ r = BRect( 10, 300, Bounds().Width() - 10, 395 );
+ fDestinationBox = new BBox( r );
+ fDestinationBox->SetLabel( "Destination" );
+ AddChild( fDestinationBox );
+
+ /* File format */
+ r = BRect( 10, 15, fDestinationBox->Bounds().Width() - 10, 35 );
+ fFileFormatPopUp = new BPopUpMenu( "" );
+ fFileFormatField = new BMenuField( r, NULL, "File format:",
+ fFileFormatPopUp, true );
+ fDestinationBox->AddChild( fFileFormatField );
+
+ /* File location */
+ r = BRect( 10, 40, fDestinationBox->Bounds().Width() - 10, 60 );
+ fFileControl = new BTextControl( r, NULL, "Location:",
+ DEFAULT_FILE, NULL );
+ fFileControl->SetDivider( 100 );
+ fDestinationBox->AddChild( fFileControl );
+
+ /* Browse button */
+ r = BRect( fDestinationBox->Bounds().Width() - 80, 65,
+ fDestinationBox->Bounds().Width() - 10, 85 );
+ fFileButton = new BButton( r, NULL, "Browse...",
+ new BMessage( RIP_BROWSE_BUTTON ) );
+ fDestinationBox->AddChild( fFileButton );
+
+ fFilePanel = new BFilePanel( B_SAVE_PANEL, NULL, NULL, 0, false );
+
+ /* Status bar */
+ r = BRect( 10, 405, Bounds().Width() - 10, 435 );
+ fStatusBar = new BStatusBar( r, NULL );
+ AddChild( fStatusBar );
+
+ /* Suspend/Rip buttons */
+ r = BRect( Bounds().Width() - 180, 445,
+ Bounds().Width() - 100, 465 );
+ fSuspendButton = new BButton( r, NULL, "Suspend",
+ new BMessage( RIP_SUSPEND_BUTTON ) );
+ fSuspendButton->SetEnabled( false );
+ AddChild( fSuspendButton );
+ r = BRect( Bounds().Width() - 90, 445,
+ Bounds().Width() - 10, 465 );
+ fStartButton = new BButton( r, NULL, "Rip !",
+ new BMessage( RIP_RIP_BUTTON ) );
+ fStartButton->MakeDefault( true );
+ AddChild( fStartButton );
+
+ /* Fill popups */
+ fVideoCodecPopUp->AddItem( new BMenuItem( "MPEG-4", NULL ) );
+ fVideoCodecPopUp->ItemAt( 0 )->SetMarked( true );
+ fAudioCodecPopUp->AddItem( new BMenuItem( "MP3", NULL ) );
+ fAudioCodecPopUp->ItemAt( 0 )->SetMarked( true );
+ fAudioBitratePopUp->AddItem(
+ new BMenuItem( "32", new BMessage( RIP_TARGET_CONTROL ) ) );
+ fAudioBitratePopUp->AddItem(
+ new BMenuItem( "64", new BMessage( RIP_TARGET_CONTROL ) ) );
+ fAudioBitratePopUp->AddItem(
+ new BMenuItem( "96", new BMessage( RIP_TARGET_CONTROL ) ) );
+ fAudioBitratePopUp->AddItem(
+ new BMenuItem( "128", new BMessage( RIP_TARGET_CONTROL ) ) );
+ fAudioBitratePopUp->AddItem(
+ new BMenuItem( "160", new BMessage( RIP_TARGET_CONTROL ) ) );
+ fAudioBitratePopUp->AddItem(
+ new BMenuItem( "192", new BMessage( RIP_TARGET_CONTROL ) ) );
+ fAudioBitratePopUp->AddItem(
+ new BMenuItem( "224", new BMessage( RIP_TARGET_CONTROL ) ) );
+ fAudioBitratePopUp->AddItem(
+ new BMenuItem( "256", new BMessage( RIP_TARGET_CONTROL ) ) );
+ fAudioBitratePopUp->AddItem(
+ new BMenuItem( "288", new BMessage( RIP_TARGET_CONTROL ) ) );
+ fAudioBitratePopUp->AddItem(
+ new BMenuItem( "320", new BMessage( RIP_TARGET_CONTROL ) ) );
+ fAudioBitratePopUp->ItemAt( 3 )->SetMarked( true );
+ fFileFormatPopUp->AddItem( new BMenuItem( "AVI", NULL ) );
+ fFileFormatPopUp->ItemAt( 0 )->SetMarked( true );
+}
+
+void RipView::MessageReceived( BMessage * message )
+{
+ switch( message->what )
+ {
+ case RIP_TITLE_POPUP:
+ {
+ int index = fTitlePopUp->IndexOf( fTitlePopUp->FindMarked() );
+ HBTitle * title = (HBTitle*) fTitleList->ItemAt( index );
+
+ /* Empty current popups */
+ BMenuItem * item;
+ while( ( item = fLanguagePopUp->ItemAt( 0 ) ) )
+ {
+ fLanguagePopUp->RemoveItem( item );
+ delete item;
+ }
+ while( ( item = fSecondaryLanguagePopUp->ItemAt( 0 ) ) )
+ {
+ fSecondaryLanguagePopUp->RemoveItem( item );
+ delete item;
+ }
+
+ /* Show new languages */
+ HBAudio * audio;
+ for( uint32_t i = 0; i < title->fAudioList->CountItems(); i++ )
+ {
+ audio = (HBAudio*) title->fAudioList->ItemAt( i );
+ fLanguagePopUp->AddItem(
+ new BMenuItem( audio->fDescription, NULL ) );
+ fSecondaryLanguagePopUp->AddItem(
+ new BMenuItem( audio->fDescription,
+ new BMessage( RIP_TARGET_CONTROL ) ) );
+ }
+ fLanguagePopUp->ItemAt( 0 )->SetMarked( true );
+ fSecondaryLanguagePopUp->AddItem( new BMenuItem( "None",
+ new BMessage( RIP_TARGET_CONTROL ) ) );
+ fSecondaryLanguagePopUp->ItemAt(
+ fSecondaryLanguagePopUp->CountItems() - 1 )->SetMarked( true );
+
+ fSecondaryLanguageField->SetEnabled(
+ ( title->fAudioList->CountItems() > 1 ) );
+
+ break;
+ }
+
+ case RIP_BITRATE_RADIO:
+ {
+ if( fCustomBitrateRadio->Value() )
+ {
+ fCustomBitrateControl->SetEnabled( true );
+ fTargetSizeControl->SetEnabled( false );
+ }
+ else
+ {
+ fCustomBitrateControl->SetEnabled( false );
+ fTargetSizeControl->SetEnabled( true );
+ Window()->PostMessage( RIP_TARGET_CONTROL );
+ }
+ break;
+ }
+
+ case RIP_TARGET_CONTROL:
+ {
+ if( !fTargetSizeRadio->Value() )
+ {
+ break;
+ }
+
+ int64_t available;
+ int index = fTitlePopUp->IndexOf( fTitlePopUp->FindMarked() );
+ HBTitle * title = (HBTitle*) fTitleList->ItemAt( index );
+
+ available = (int64_t) 1024 * 1024 *
+ atoi( fTargetSizeControl->Text() );
+
+ /* AVI headers */
+ available -= 2048;
+
+ /* Video chunk headers (8 bytes / frame) and
+ and index (16 bytes / frame) */
+ available -= 24 * title->fLength * title->fRate /
+ title->fScale;
+
+ /* Audio tracks */
+ available -=
+ ( strcmp( fSecondaryLanguagePopUp->FindMarked()->Label(),
+ "None" ) ? 2 : 1 ) *
+ ( title->fLength *
+ atoi( fAudioBitratePopUp->FindMarked()->Label() ) * 128 +
+ 24 * title->fLength * 44100 / 1152 );
+
+ char string[1024]; memset( string, 0, 1024 );
+ if( available < 0 )
+ {
+ sprintf( string, "0" );
+ }
+ else
+ {
+ sprintf( string, "%lld", available /
+ ( 128 * title->fLength ) );
+ }
+ fCustomBitrateControl->SetText( string );
+ break;
+ }
+
+ case RIP_CROP_BUTTON:
+ {
+ int index = fTitlePopUp->IndexOf( fTitlePopUp->FindMarked() );
+ HBTitle * title = (HBTitle*) fTitleList->ItemAt( index );
+
+ HBPictureWin * win;
+ win = new HBPictureWin( fManager, title );
+ win->Show();
+ break;
+ }
+
+ case RIP_BROWSE_BUTTON:
+ {
+ fFilePanel->Show();
+ }
+
+ case B_SAVE_REQUESTED:
+ {
+ entry_ref ref;
+ BString string;
+ if( message->FindRef( "directory", 0, &ref ) == B_OK &&
+ message->FindString( "name", &string ) == B_OK )
+ {
+ BPath * path = new BPath( &ref );
+ string.Prepend( "/" );
+ string.Prepend( path->Path() );
+ fFileControl->SetText( string.String() );
+ }
+ break;
+ }
+
+ case RIP_SUSPEND_BUTTON:
+ {
+ if( strcmp( fSuspendButton->Label(), "Suspend" ) )
+ {
+ fManager->ResumeRip();
+ }
+ else
+ {
+ fManager->SuspendRip();
+ }
+
+ break;
+ }
+
+ case RIP_RIP_BUTTON:
+ {
+ if( strcmp( fStartButton->Label(), "Rip !" ) )
+ {
+ fManager->StopRip();
+ }
+ else
+ {
+ int index;
+
+ /* Get asked title & languages */
+ index = fTitlePopUp->IndexOf( fTitlePopUp->FindMarked() );
+ HBTitle * title = (HBTitle*) fTitleList->ItemAt( index );
+ index = fLanguagePopUp->IndexOf( fLanguagePopUp->FindMarked() );
+ HBAudio * audio1 =
+ (HBAudio*) title->fAudioList->ItemAt( index );
+ index = fSecondaryLanguagePopUp->IndexOf(
+ fSecondaryLanguagePopUp->FindMarked() );
+ HBAudio * audio2 =
+ (HBAudio*) title->fAudioList->ItemAt( index );
+
+ /* Use user settings */
+ title->fBitrate = atoi( fCustomBitrateControl->Text() );
+ title->fTwoPass = ( fTwoPassCheck->Value() != 0 );
+ audio1->fOutBitrate =
+ atoi( fAudioBitratePopUp->FindMarked()->Label() );
+ if( audio2 )
+ {
+ audio2->fOutBitrate =
+ atoi( fAudioBitratePopUp->FindMarked()->Label() );
+ }
+
+ /* Let libhb do the job */
+ fManager->StartRip( title, audio1, audio2,
+ (char*) fFileControl->Text() );
+ }
+ break;
+ }
+
+ default:
+ BView::MessageReceived( message );
+ break;
+ }
+}
+
+void RipView::UpdateIntf( HBStatus status )
+{
+ switch( status.fMode )
+ {
+ case HB_MODE_READY_TO_RIP:
+ {
+ fTitleList = status.fTitleList;
+
+ 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->AddItem(
+ new BMenuItem( string, new BMessage( RIP_TITLE_POPUP ) ) );
+ }
+ fTitlePopUp->ItemAt( 0 )->SetMarked( true );
+ Window()->PostMessage( RIP_TITLE_POPUP );
+ break;
+ }
+
+ 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 )
+ {
+ fStatusBar->Update( - fStatusBar->CurrentValue(),
+ "Starting..." );
+ }
+ else
+ {
+ 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 -
+ fStatusBar->CurrentValue(),
+ string );
+ }
+
+ fSuspendButton->SetLabel( "Suspend" );
+ fSuspendButton->SetEnabled( true );
+ fStartButton->SetLabel( "Cancel" );
+ fStartButton->SetEnabled( true );
+ break;
+ }
+
+ case HB_MODE_SUSPENDED:
+ {
+ 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" );
+
+ fSuspendButton->SetLabel( "Resume" );
+ fSuspendButton->SetEnabled( true );
+ fStartButton->SetLabel( "Cancel" );
+ fStartButton->SetEnabled( true );
+ 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 );
+
+ 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 );
+
+ 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 );
+
+ 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 );
+
+ fStatusBar->Update( - fStatusBar->CurrentValue(),
+ "Error." );
+
+ fSuspendButton->SetLabel( "Suspend" );
+ fSuspendButton->SetEnabled( false );
+ fStartButton->SetLabel( "Rip !" );
+ fStartButton->SetEnabled( true );
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
diff --git a/beos/RipView.h b/beos/RipView.h
new file mode 100644
index 000000000..d487b2b99
--- /dev/null
+++ b/beos/RipView.h
@@ -0,0 +1,77 @@
+/* $Id: RipView.h,v 1.5 2003/10/13 22:23:02 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_RIP_VIEW_H
+#define HB_RIP_VIEW_H
+
+#include <View.h>
+class BBox;
+class BButton;
+class BCheckBox;
+class BFilePanel;
+class BMenuField;
+class BPopUpMenu;
+class BRadioButton;
+class BStatusBar;
+class BTextControl;
+
+#include "Common.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'
+
+class RipView : public BView
+{
+ public:
+ RipView( HBManager * manager );
+ void MessageReceived( BMessage * message );
+ void UpdateIntf( HBStatus status );
+
+ private:
+ HBManager * fManager;
+ HBList * fTitleList;
+
+ BBox * fVideoBox;
+ BPopUpMenu * fTitlePopUp;
+ BMenuField * fTitleField;
+ BPopUpMenu * fVideoCodecPopUp;
+ BMenuField * fVideoCodecField;
+ BRadioButton * fCustomBitrateRadio;
+ BTextControl * fCustomBitrateControl;
+ BRadioButton * fTargetSizeRadio;
+ BTextControl * fTargetSizeControl;
+ BCheckBox * fTwoPassCheck;
+ BButton * fCropButton;
+
+ BBox * fAudioBox;
+ BPopUpMenu * fLanguagePopUp;
+ BMenuField * fLanguageField;
+ BPopUpMenu * fSecondaryLanguagePopUp;
+ BMenuField * fSecondaryLanguageField;
+ BPopUpMenu * fAudioCodecPopUp;
+ BMenuField * fAudioCodecField;
+ BPopUpMenu * fAudioBitratePopUp;
+ BMenuField * fAudioBitrateField;
+
+ BBox * fDestinationBox;
+ BPopUpMenu * fFileFormatPopUp;
+ BMenuField * fFileFormatField;
+ BTextControl * fFileControl;
+ BButton * fFileButton;
+ BFilePanel * fFilePanel;
+
+ BStatusBar * fStatusBar;
+ BButton * fSuspendButton;
+ BButton * fStartButton;
+};
+
+#endif
diff --git a/beos/ScanView.cpp b/beos/ScanView.cpp
new file mode 100644
index 000000000..fb5d722e8
--- /dev/null
+++ b/beos/ScanView.cpp
@@ -0,0 +1,280 @@
+/* $Id: ScanView.cpp,v 1.4 2003/10/13 23:42:03 titer Exp $
+
+ This file is part of the HandBrake source code.
+ Homepage: <http://beos.titer.org/handbrake/>.
+ It may be used under the terms of the GNU General Public License. */
+
+#include <fs_info.h>
+#include <sys/ioctl.h>
+#include <Box.h>
+#include <Button.h>
+#include <Directory.h>
+#include <Drivers.h>
+#include <FilePanel.h>
+#include <MenuField.h>
+#include <MenuItem.h>
+#include <Path.h>
+#include <PopUpMenu.h>
+#include <Query.h>
+#include <RadioButton.h>
+#include <StringView.h>
+#include <TextControl.h>
+#include <VolumeRoster.h>
+
+#include "Manager.h"
+#include "ScanView.h"
+
+ScanView::ScanView( HBManager * manager )
+ : BView( BRect( 0,0,400,190 ), NULL, B_FOLLOW_ALL, B_WILL_DRAW )
+{
+ fManager = manager;
+
+ BRect r;
+ SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) );
+
+ r = BRect( 10, 10, Bounds().Width() - 10, 115 );
+ BBox * box = new BBox( r );
+ box->SetLabel( "Select source:" );
+ AddChild( box );
+
+ r = BRect( 10, 15, box->Bounds().Width() / 2, 35 );
+ fRadioDetected = new BRadioButton( r, NULL, "Detected volume:",
+ new BMessage( SCAN_RADIO ) );
+ box->AddChild( fRadioDetected );
+
+ r = BRect( box->Bounds().Width() / 2, 15,
+ box->Bounds().Width() - 10, 35 );
+ fPopUp = new BPopUpMenu( "" );
+ fField = new BMenuField( r, NULL, NULL, fPopUp, true );
+ fField->SetDivider( 0 );
+ box->AddChild( fField );
+
+ r = BRect( 10, 45, box->Bounds().Width() / 3, 65 );
+ fRadioFolder = new BRadioButton( r, NULL, "DVD folder:",
+ new BMessage( SCAN_RADIO ) );
+ box->AddChild( fRadioFolder );
+
+ r = BRect( box->Bounds().Width() / 3, 45,
+ box->Bounds().Width() - 10, 65 );
+ fFolderControl = new BTextControl( r, NULL, NULL, NULL, NULL );
+ box->AddChild( fFolderControl );
+
+ r = BRect( box->Bounds().Width() - 80, 70,
+ box->Bounds().Width() - 10, 95 );
+ fBrowseButton = new BButton( r, NULL, "Browse...",
+ new BMessage( SCAN_BROWSE_BUTTON ) );
+ box->AddChild( fBrowseButton );
+
+ fFilePanel = new BFilePanel( B_OPEN_PANEL, NULL,
+ NULL, B_DIRECTORY_NODE );
+
+ r = BRect( 10, 125, Bounds().Width() - 10, 145 );
+ fStatusString = new BStringView( r, NULL, NULL );
+ AddChild( fStatusString );
+
+ r = BRect( Bounds().Width() - 70, 155,
+ Bounds().Width() - 10, 175 );
+ fOpenButton = new BButton( r, NULL, "Open", new BMessage( SCAN_OPEN ) );
+ fOpenButton->MakeDefault( true );
+ AddChild( fOpenButton );
+
+ DetectVolumes();
+}
+
+void ScanView::MessageReceived( BMessage * message )
+{
+ switch( message->what )
+ {
+ case SCAN_RADIO:
+ {
+ if( fRadioDetected->Value() )
+ {
+ fField->SetEnabled( true );
+ fFolderControl->SetEnabled( false );
+ fBrowseButton->SetEnabled( false );
+ fOpenButton->SetEnabled( fPopUp->CountItems() > 0 );
+ }
+ else
+ {
+ fField->SetEnabled( false );
+ fFolderControl->SetEnabled( true );
+ fBrowseButton->SetEnabled( true );
+ fOpenButton->SetEnabled( true );
+ }
+ break;
+ }
+
+ case SCAN_BROWSE_BUTTON:
+ {
+ fFilePanel->Show();
+ break;
+ }
+
+ case B_REFS_RECEIVED:
+ {
+ entry_ref ref;
+ if( message->FindRef( "refs", 0, &ref ) == B_OK )
+ {
+ BPath * path = new BPath( &ref );
+ fFolderControl->SetText( path->Path() );
+ }
+ break;
+ }
+
+ case SCAN_OPEN:
+ {
+ if( fRadioDetected->Value() )
+ {
+ fManager->ScanVolumes( (char*)
+ fPopUp->FindMarked()->Label() );
+ }
+ else
+ {
+ fManager->ScanVolumes( (char*) fFolderControl->Text() );
+ }
+ break;
+ }
+
+ default:
+ BView::MessageReceived( message );
+ }
+}
+
+void ScanView::UpdateIntf( HBStatus status )
+{
+ switch( status.fMode )
+ {
+ case HB_MODE_SCANNING:
+ {
+ 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 )
+ {
+ sprintf( string, "Opening %s...",
+ status.fScannedVolume );
+ }
+ else
+ {
+ sprintf( string, "Scanning %s, title %d...",
+ status.fScannedVolume, status.fScannedTitle );
+ }
+ fStatusString->SetText( string );
+ break;
+ }
+
+ case HB_MODE_INVALID_VOLUME:
+ {
+ fRadioDetected->SetEnabled( true );
+ fRadioFolder->SetEnabled( true );
+
+ if( fRadioDetected->Value() )
+ {
+ fField->SetEnabled( true );
+ fFolderControl->SetEnabled( false );
+ fBrowseButton->SetEnabled( false );
+ fOpenButton->SetEnabled( fPopUp->CountItems() > 0 );
+ }
+ else
+ {
+ fField->SetEnabled( false );
+ fFolderControl->SetEnabled( true );
+ fBrowseButton->SetEnabled( true );
+ fOpenButton->SetEnabled( true );
+ }
+
+ fStatusString->SetText( "Invalid volume." );
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+void ScanView::DetectVolumes()
+{
+ BVolumeRoster * roster = new BVolumeRoster();
+ BVolume * volume = new BVolume();
+ fs_info info;
+ int device;
+ device_geometry geometry;
+
+ /* Parse mounted volumes */
+ while( roster->GetNextVolume( volume ) == B_NO_ERROR )
+ {
+ /* open() and ioctl() for more informations */
+ fs_stat_dev( volume->Device(), &info );
+ if( ( device = open( info.device_name, O_RDONLY ) ) < 0 )
+ {
+ continue;
+ }
+
+ if( ioctl( device, B_GET_GEOMETRY, &geometry,
+ sizeof( geometry ) ) < 0 )
+
+ {
+ continue;
+ }
+
+ /* Get the volume name */
+ char volumeName[B_FILE_NAME_LENGTH];
+ volume->GetName( volumeName );
+
+ if( volume->IsReadOnly() && geometry.device_type == B_CD )
+ {
+ /* May be a DVD */
+ fPopUp->AddItem( new BMenuItem( info.device_name, NULL ) );
+ }
+ else if( geometry.device_type == B_DISK )
+ {
+ /* May be a hard drive. Look for VIDEO_TS folders on it */
+ BQuery * query = new BQuery();
+
+ if( query->SetVolume( volume ) != B_OK )
+ {
+ delete query;
+ continue;
+ }
+
+ if( query->SetPredicate( "name = VIDEO_TS.BUP" ) != B_OK )
+ {
+ delete query;
+ continue;
+ }
+
+ query->Fetch();
+
+ BEntry entry, parentEntry;
+ BPath path;
+ while( query->GetNextEntry( &entry ) == B_OK )
+ {
+ entry.GetParent( &parentEntry );
+ parentEntry.GetPath( &path );
+
+ fPopUp->AddItem( new BMenuItem( path.Path(), NULL ) );
+ }
+
+ delete query;
+ }
+ }
+
+ if( fPopUp->CountItems() > 0 )
+ {
+ fPopUp->ItemAt( 0 )->SetMarked( true );
+ fRadioDetected->SetValue( true );
+ fFolderControl->SetEnabled( false );
+ fBrowseButton->SetEnabled( false );
+ }
+ else
+ {
+ fRadioFolder->SetValue( true );
+ fField->SetEnabled( false );
+ }
+}
+
diff --git a/beos/ScanView.h b/beos/ScanView.h
new file mode 100644
index 000000000..5e2514b54
--- /dev/null
+++ b/beos/ScanView.h
@@ -0,0 +1,48 @@
+/* $Id: ScanView.h,v 1.2 2003/10/13 22:23:02 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_SCAN_VIEW_H
+#define HB_SCAN_VIEW_H
+
+#include <View.h>
+class BButton;
+class BFilePanel;
+class BMenuField;
+class BPopUpMenu;
+class BRadioButton;
+class BStringView;
+class BTextControl;
+
+#include "Common.h"
+
+#define SCAN_RADIO 'scra'
+#define SCAN_BROWSE_BUTTON 'sbrb'
+#define SCAN_OPEN 'scop'
+
+class ScanView : public BView
+{
+ public:
+ ScanView( HBManager * manager );
+ void MessageReceived( BMessage * message );
+ void UpdateIntf( HBStatus status );
+
+ private:
+ void DetectVolumes();
+
+ HBManager * fManager;
+
+ BRadioButton * fRadioDetected;
+ BRadioButton * fRadioFolder;
+ BMenuField * fField;
+ BPopUpMenu * fPopUp;
+ BTextControl * fFolderControl;
+ BButton * fBrowseButton;
+ BFilePanel * fFilePanel;
+ BStringView * fStatusString;
+ BButton * fOpenButton;
+};
+
+#endif
diff --git a/core/Ac3Decoder.cpp b/core/Ac3Decoder.cpp
index 12eed05df..95030d810 100644
--- a/core/Ac3Decoder.cpp
+++ b/core/Ac3Decoder.cpp
@@ -1,4 +1,4 @@
-/* $Id: Ac3Decoder.cpp,v 1.12 2003/09/30 14:38:15 titer Exp $
+/* $Id: Ac3Decoder.cpp,v 1.20 2003/10/13 10:58:24 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -13,101 +13,160 @@ extern "C" {
}
HBAc3Decoder::HBAc3Decoder( HBManager * manager, HBAudio * audio )
- : HBThread( "ac3decoder" )
{
- fManager = manager;
- fAudio = audio;
+ fManager = manager;
+ fAudio = audio;
+ fLock = new HBLock();
+ fUsed = false;
+
+ /* Init liba52 */
+ fState = a52_init( 0 );
+ fInFlags = 0;
+ fOutFlags = A52_STEREO;
+
+ /* Lame wants samples from -32768 to 32768 */
+ fSampleLevel = 32768.0;
+
/* Max size for a A52 frame is 3840 bytes */
- fAc3Frame = new HBBuffer( 3840 );
- fAc3Buffer = NULL;
- fPosInBuffer = 0;
- fPosition = 0;
+ fAc3Frame = new HBBuffer( 3840 );
+ fAc3Frame->fSize = 0;
+ fAc3Buffer = NULL;
+ fPosInBuffer = 0;
+ fRawBuffer = NULL;
}
HBAc3Decoder::~HBAc3Decoder()
{
+ if( fRawBuffer ) delete fRawBuffer;
+ if( fAc3Buffer ) delete fAc3Buffer;
delete fAc3Frame;
+ a52_free( fState );
+ delete fLock;
}
-void HBAc3Decoder::DoWork()
+bool HBAc3Decoder::Work()
{
- /* Init liba52 */
- a52_state_t * state = a52_init( 0 );
- int inFlags = 0;
- int outFlags = A52_STEREO;
-
- /* Lame wants samples from -32768 to 32768 */
- float sampleLevel = 32768;
-
- int frameSize;
- HBBuffer * rawBuffer;
- sample_t * samples;
-
- /* Main loop */
+ if( !Lock() )
+ {
+ return false;
+ }
+
+ bool didSomething = false;
+
+ sample_t * samples;
for( ;; )
{
- while( fSuspend )
+ /* Try to push the latest decoded buffer */
+ if( fRawBuffer )
{
- Snooze( 10000 );
+ if( fAudio->fRawFifo->Push( fRawBuffer ) )
+ {
+ fRawBuffer = NULL;
+ }
+ else
+ {
+ break;
+ }
}
- fAc3Frame->fSize = 0;
-
- /* Get a frame header (7 bytes) */
- if( !( GetBytes( 7 ) ) )
+ /* Get a new frame */
+ if( fAc3Frame->fSize < 7 )
{
- break;
- }
-
- /* Get the size of the current frame */
- frameSize = a52_syncinfo( fAc3Frame->fData, &inFlags,
- &fAudio->fInSampleRate,
- &fAudio->fInBitrate );
+ /* Get a frame header (7 bytes) */
+ if( !( GetBytes( 7 ) ) )
+ {
+ break;
+ }
- if( !frameSize )
- {
- Log( "HBAc3Decoder : a52_syncinfo failed" );
- fManager->Error();
- break;
+ /* Get the size of the current frame */
+ fFrameSize = a52_syncinfo( fAc3Frame->fData, &fInFlags,
+ &fAudio->fInSampleRate,
+ &fAudio->fInBitrate );
+ if( !fFrameSize )
+ {
+ Log( "HBAc3Decoder : a52_syncinfo failed" );
+ fManager->Error( HB_ERROR_A52_SYNC );
+ return false;
+ }
}
- /* Get the whole frame */
- if( !( GetBytes( (uint32_t) frameSize ) ) )
+ /* In case the audio should start later than the video,
+ insert some silence */
+ if( fAudio->fDelay > 3 * 256 * 1000 / fAudio->fInSampleRate )
{
- break;
+ fRawBuffer = new HBBuffer( 12 * 256 * sizeof( float ) );
+ for( uint32_t i = 0; i < 12 * 256; i++ )
+ {
+ ((float*)fRawBuffer->fData)[i] = 0;
+ }
+ fAudio->fDelay -= 6 * 256 * 1000 / fAudio->fInSampleRate;
+ continue;
}
+
+ if( fAc3Frame->fSize >= 7 )
+ {
+ /* Get the whole frame */
+ if( !( GetBytes( (uint32_t) fFrameSize ) ) )
+ {
+ break;
+ }
- /* Feed liba52 */
- a52_frame( state, fAc3Frame->fData, &outFlags, &sampleLevel, 0 );
+ /* Feed liba52 */
+ a52_frame( fState, fAc3Frame->fData, &fOutFlags,
+ &fSampleLevel, 0 );
- /* 6 blocks per frame, 256 samples per block */
- rawBuffer = new HBBuffer( 12 * 256 * sizeof( float ) );
- rawBuffer->fPosition = fPosition;
- for( int i = 0; i < 6; i++ )
- {
- /* Decode a block */
- a52_block( state );
+ /* 6 blocks per frame, 256 samples per block */
+ fRawBuffer = new HBBuffer( 12 * 256 * sizeof( float ) );
+ fRawBuffer->fPosition = fPosition;
+ for( int i = 0; i < 6; i++ )
+ {
+ /* Decode a block */
+ a52_block( fState );
- /* Get a pointer to the raw data */
- samples = a52_samples( state );
+ /* Get a pointer to the raw data */
+ samples = a52_samples( fState );
- /* Copy left channel data */
- memcpy( (float*) rawBuffer->fData + i * 256,
- samples,
- 256 * sizeof( float ) );
+ /* Copy left channel data */
+ memcpy( (float*) fRawBuffer->fData + i * 256,
+ samples,
+ 256 * sizeof( float ) );
- /* Copy right channel data */
- memcpy( (float*) rawBuffer->fData + ( 6 + i ) * 256,
- samples + 256,
- 256 * sizeof( float ) );
- }
+ /* Copy right channel data */
+ memcpy( (float*) fRawBuffer->fData + ( 6 + i ) * 256,
+ samples + 256,
+ 256 * sizeof( float ) );
+ }
- if( !Push( fAudio->fRawFifo, rawBuffer ) )
- {
- break;
+ fAc3Frame->fSize = 0;
+
+ didSomething = true;
}
}
+
+ Unlock();
+
+ return didSomething;
+}
+
+bool HBAc3Decoder::Lock()
+{
+ fLock->Lock();
+ if( fUsed )
+ {
+ fLock->Unlock();
+ return false;
+ }
+ fUsed = true;
+ fLock->Unlock();
+ return true;
+}
+
+void HBAc3Decoder::Unlock()
+{
+ fLock->Lock();
+ fUsed = false;
+ fLock->Unlock();
}
/* GetBytes() : pops buffers from the AC3 fifo until fAc3Frame
@@ -118,7 +177,7 @@ bool HBAc3Decoder::GetBytes( uint32_t size )
{
if( !fAc3Buffer )
{
- if( !( fAc3Buffer = Pop( fAudio->fAc3Fifo ) ) )
+ if( !( fAc3Buffer = fAudio->fAc3Fifo->Pop() ) )
{
return false;
}
diff --git a/core/Ac3Decoder.h b/core/Ac3Decoder.h
index 8226bb365..41ac48395 100644
--- a/core/Ac3Decoder.h
+++ b/core/Ac3Decoder.h
@@ -1,4 +1,4 @@
-/* $Id: Ac3Decoder.h,v 1.6 2003/09/30 14:38:15 titer Exp $
+/* $Id: Ac3Decoder.h,v 1.10 2003/10/07 20:58:12 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -8,26 +8,40 @@
#define HB_AC3_DECODER_H
#include "Common.h"
-#include "Thread.h"
-class HBAc3Decoder : public HBThread
+class HBAc3Decoder
{
public:
- HBAc3Decoder( HBManager * manager,
- HBAudio * audio );
- ~HBAc3Decoder();
+ HBAc3Decoder( HBManager * manager,
+ HBAudio * audio );
+ ~HBAc3Decoder();
+ bool Work();
private:
- void DoWork();
- bool GetBytes( uint32_t size );
-
- HBManager * fManager;
- HBAudio * fAudio;
-
- HBBuffer * fAc3Frame;
- HBBuffer * fAc3Buffer;
- uint32_t fPosInBuffer;
- float fPosition;
+ bool Lock();
+ void Unlock();
+ bool GetBytes( uint32_t size );
+
+ HBManager * fManager;
+ HBAudio * fAudio;
+
+ HBLock * fLock;
+ bool fUsed;
+
+ /* liba52 */
+ a52_state_t * fState;
+ int fInFlags;
+ int fOutFlags;
+ float fSampleLevel;
+
+ /* buffers */
+ HBBuffer * fAc3Frame;
+ HBBuffer * fAc3Buffer;
+ uint32_t fPosInBuffer;
+ HBBuffer * fRawBuffer;
+
+ float fPosition;
+ int fFrameSize;
};
#endif
diff --git a/core/AviMuxer.cpp b/core/AviMuxer.cpp
index 3b77b9c53..4a84fe8b8 100644
--- a/core/AviMuxer.cpp
+++ b/core/AviMuxer.cpp
@@ -1,4 +1,4 @@
-/* $Id: AviMuxer.cpp,v 1.14 2003/09/30 14:38:15 titer Exp $
+/* $Id: AviMuxer.cpp,v 1.17 2003/10/09 23:33:36 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -149,7 +149,7 @@ void HBAviIndex::WriteInt32( uint32_t val )
HBAviMuxer::HBAviMuxer( HBManager * manager, HBTitle * title,
HBAudio * audio1, HBAudio * audio2,
char * fileName )
- : HBThread( "avimuxer" )
+ : HBThread( "avimuxer", HB_NORMAL_PRIORITY )
{
fManager = manager;
fTitle = title;
@@ -163,6 +163,8 @@ HBAviMuxer::HBAviMuxer( HBManager * manager, HBTitle * title,
fRiffBytesCount = 2040;
fMoviBytesCount = 4;
+
+ Run();
}
void HBAviMuxer::DoWork()
@@ -171,7 +173,7 @@ void HBAviMuxer::DoWork()
if( !( fFile = fopen( fFileName, "w" ) ) )
{
Log( "HBAviMuxer: fopen failed" );
- fManager->Error();
+ fManager->Error( HB_ERROR_AVI_WRITE );
return;
}
diff --git a/core/Common.cpp b/core/Common.cpp
index b9bb3e062..4087a001d 100644
--- a/core/Common.cpp
+++ b/core/Common.cpp
@@ -1,4 +1,4 @@
-/* $Id: Common.cpp,v 1.29 2003/09/30 21:21:32 titer Exp $
+/* $Id: Common.cpp,v 1.31 2003/10/07 22:48:31 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -92,6 +92,74 @@ uint64_t GetDate()
return( (uint64_t) tv.tv_sec * 1000000 + (uint64_t) tv.tv_usec );
}
+int GetCPUCount()
+{
+ int CPUCount = 1;
+
+#if defined( SYS_BEOS )
+ system_info info;
+ get_system_info( &info );
+ CPUCount = info.cpu_count;
+
+#elif defined( SYS_MACOSX )
+ FILE * info;
+ char buffer[256];
+
+ if( ( info = popen( "/usr/sbin/sysctl hw.ncpu", "r" ) ) )
+ {
+ if( fgets( buffer, 256, info ) )
+ {
+ int count;
+ if( sscanf( buffer, "hw.ncpu: %d", &count ) == 1 )
+ {
+ CPUCount = count;
+ }
+ else
+ {
+ Log( "GetCPUCount: sscanf() failed" );
+ }
+ }
+ else
+ {
+ Log( "GetCPUCount: fgets() failed" );
+ }
+ fclose( info );
+ }
+ else
+ {
+ Log( "GetCPUCount: popen() failed" );
+ }
+
+#elif defined( SYS_LINUX )
+ FILE * info;
+ char buffer[256];
+
+ if( ( info = fopen( "/proc/cpuinfo", "r" ) ) )
+ {
+ int count = 0;
+ while( fgets( buffer, 256, info ) )
+ {
+ if( !memcmp( buffer, "processor",
+ sizeof( "processor" ) - 1 ) )
+ {
+ count++;
+ }
+ }
+ CPUCount = count;
+ fclose( info );
+ }
+ else
+ {
+ Log( "GetCPUCount: fopen() failed" );
+ }
+
+#endif
+ CPUCount = MAX( 1, CPUCount );
+ CPUCount = MIN( CPUCount, 8 );
+
+ return CPUCount;
+}
+
#define HBLIST_DEFAULT_SIZE 20
HBList::HBList()
diff --git a/core/Common.h b/core/Common.h
index f4d40c8bd..3c138e2a1 100644
--- a/core/Common.h
+++ b/core/Common.h
@@ -1,4 +1,4 @@
-/* $Id: Common.h,v 1.28 2003/10/03 16:18:08 titer Exp $
+/* $Id: Common.h,v 1.34 2003/10/13 17:49:58 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -16,6 +16,8 @@
typedef uint8_t byte_t;
/* Misc structures */
+typedef struct a52_state_s a52_state_t;
+typedef struct lame_global_struct lame_global_flags;
typedef struct dvdplay_s * dvdplay_ptr;
typedef struct mpeg2dec_s mpeg2dec_t;
typedef struct AVPicture AVPicture;
@@ -43,6 +45,7 @@ class HBScanner;
class HBStatus;
class HBThread;
class HBTitle;
+class HBWorker;
/* Handy macros */
#ifndef MIN
@@ -61,22 +64,36 @@ void Snooze( uint64_t time );
void Log( char * log, ... );
char * LanguageForCode( int code );
uint64_t GetDate();
+int GetCPUCount();
/* Possible states */
typedef enum
{
- HB_MODE_UNDEF = 0000,
- HB_MODE_NEED_VOLUME = 0001,
- HB_MODE_SCANNING = 0002,
- HB_MODE_INVALID_VOLUME = 0004,
- HB_MODE_READY_TO_RIP = 0010,
- HB_MODE_ENCODING = 0020,
- HB_MODE_SUSPENDED = 0040,
- HB_MODE_DONE = 0100,
- HB_MODE_CANCELED = 0200,
- HB_MODE_ERROR = 0400
+ HB_MODE_UNDEF = 00000,
+ HB_MODE_NEED_VOLUME = 00001,
+ HB_MODE_SCANNING = 00002,
+ HB_MODE_INVALID_VOLUME = 00004,
+ HB_MODE_READY_TO_RIP = 00010,
+ HB_MODE_ENCODING = 00020,
+ HB_MODE_SUSPENDED = 00040,
+ HB_MODE_STOPPING = 00100,
+ HB_MODE_DONE = 00200,
+ HB_MODE_CANCELED = 00400,
+ HB_MODE_ERROR = 01000
} HBMode;
+/* Possible errors */
+typedef enum
+{
+ HB_ERROR_A52_SYNC = 0,
+ HB_ERROR_AVI_WRITE,
+ HB_ERROR_DVD_OPEN,
+ HB_ERROR_DVD_READ,
+ HB_ERROR_MP3_INIT,
+ HB_ERROR_MP3_ENCODE,
+ HB_ERROR_MPEG4_INIT
+} HBError;
+
class HBStatus
{
public:
@@ -96,6 +113,9 @@ class HBStatus
uint64_t fStartDate;
uint32_t fRemainingTime; /* in seconds */
uint64_t fSuspendDate;
+
+ /* HB_MODE_ERROR */
+ HBError fError;
};
class HBList
@@ -130,6 +150,8 @@ class HBAudio
int fInBitrate;
int fOutBitrate;
+ int64_t fDelay; /* in ms */
+
/* Fifos */
HBFifo * fAc3Fifo;
HBFifo * fRawFifo;
@@ -187,6 +209,7 @@ class HBTitle
HBResizer * fResizer;
HBMpeg4Encoder * fMpeg4Encoder;
HBAviMuxer * fAviMuxer;
+ HBWorker * fWorkers[4];
};
#endif
diff --git a/core/DVDReader.cpp b/core/DVDReader.cpp
index 27c20d08a..8f7835f51 100644
--- a/core/DVDReader.cpp
+++ b/core/DVDReader.cpp
@@ -1,4 +1,4 @@
-/* $Id: DVDReader.cpp,v 1.12 2003/10/03 16:49:19 titer Exp $
+/* $Id: DVDReader.cpp,v 1.17 2003/10/09 23:33:36 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -15,10 +15,12 @@
#include <dvdplay/nav.h>
HBDVDReader::HBDVDReader( HBManager * manager, HBTitle * title )
- : HBThread( "dvdreader" )
+ : HBThread( "dvdreader", HB_NORMAL_PRIORITY )
{
fManager = manager;
fTitle = title;
+
+ Run();
}
void HBDVDReader::DoWork()
@@ -29,7 +31,7 @@ void HBDVDReader::DoWork()
if( !vmg )
{
Log( "HBDVDReader: dvdplay_open() failed" );
- fManager->Error();
+ fManager->Error( HB_ERROR_DVD_OPEN );
return;
}
@@ -69,7 +71,7 @@ void HBDVDReader::DoWork()
{
Log( "HBDVDReader: could not dvdplay_read()" );
delete dvdBuffer;
- fManager->Error();
+ fManager->Error( HB_ERROR_DVD_READ );
break;
}
diff --git a/core/Fifo.cpp b/core/Fifo.cpp
index 35bcb0449..d1d051c33 100644
--- a/core/Fifo.cpp
+++ b/core/Fifo.cpp
@@ -1,4 +1,4 @@
-/* $Id: Fifo.cpp,v 1.14 2003/10/02 15:44:52 titer Exp $
+/* $Id: Fifo.cpp,v 1.15 2003/10/13 14:12:18 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -51,7 +51,8 @@ HBFifo::HBFifo( int capacity )
HBFifo::~HBFifo()
{
- Log( "HBFifo::~HBFifo : trashing %d buffers", Size() );
+ Log( "HBFifo::~HBFifo: trashing %d buffer%s",
+ Size(), Size() ? "s" : "" );
/* Empty the fifo */
while( fWhereToPush != fWhereToPop )
diff --git a/core/Manager.cpp b/core/Manager.cpp
index 583bda36a..826ceea58 100644
--- a/core/Manager.cpp
+++ b/core/Manager.cpp
@@ -1,72 +1,103 @@
-/* $Id: Manager.cpp,v 1.47 2003/10/05 14:28:40 titer Exp $
+/* $Id: Manager.cpp,v 1.68 2003/10/13 23:42:03 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
It may be used under the terms of the GNU General Public License. */
-#include "Manager.h"
-#include "Fifo.h"
-#include "Scanner.h"
+#include "Ac3Decoder.h"
+#include "AviMuxer.h"
#include "DVDReader.h"
-#include "MpegDemux.h"
+#include "Fifo.h"
+#include "Manager.h"
+#include "Mp3Encoder.h"
#include "Mpeg2Decoder.h"
#include "Mpeg4Encoder.h"
-#include "Ac3Decoder.h"
-#include "Mp3Encoder.h"
-#include "AviMuxer.h"
+#include "MpegDemux.h"
#include "Resizer.h"
+#include "Scanner.h"
+#include "Worker.h"
#include <ffmpeg/avcodec.h>
/* Public methods */
-HBManager::HBManager( bool debug )
- : HBThread( "manager" )
+HBManager::HBManager( bool debug, int cpuCount )
+ : HBThread( "manager", HB_NORMAL_PRIORITY )
{
- fPid = 0;
-
- fStopScan = false;
- fStopRip = false;
- fRipDone = false;
- fError = false;
-
- fScanner = NULL;
-
- fStatus.fMode = HB_MODE_NEED_VOLUME;
- fNeedUpdate = true;
-
/* See Log() in Common.cpp */
if( debug )
{
- setenv( "HB_DEBUG", "1", 1 );
+ putenv( "HB_DEBUG=1" );
+ }
+
+ /* Check CPU count */
+ if( !cpuCount )
+ {
+ fCPUCount = GetCPUCount();
+ Log( "HBManager::HBManager: %d CPU%s detected", fCPUCount,
+ ( fCPUCount > 1 ) ? "s" : "" );
}
else
{
- unsetenv( "HB_DEBUG" );
+ fCPUCount = cpuCount;
+ if( fCPUCount < 1 )
+ {
+ Log( "HBManager::HBManager: invalid CPU count (%d), "
+ "using 1", fCPUCount );
+ fCPUCount = 1;
+ }
+ else if( fCPUCount > 8 )
+ {
+ Log( "HBManager::HBManager: invalid CPU count (%d), "
+ "using 8", fCPUCount );
+ fCPUCount = 8;
+ }
+ Log( "HBManager::HBManager: user specified %d CPU%s",
+ fCPUCount, ( fCPUCount > 1 ) ? "s" : "" );
}
- fCurTitle = NULL;
- fCurAudio1 = NULL;
- fCurAudio2 = NULL;
-
/* Init ffmpeg's libavcodec */
avcodec_init();
// register_avcodec( &mpeg4_encoder );
avcodec_register_all();
+ /* Initialization */
+ fStopScan = false;
+ fStopRip = false;
+ fRipDone = false;
+ fError = false;
+
+ fScanner = NULL;
+
+ fStatusLock = new HBLock();
+ fStatus.fMode = HB_MODE_NEED_VOLUME;
+ fNeedUpdate = true;
+
+ fCurTitle = NULL;
+ fCurAudio1 = NULL;
+ fCurAudio2 = NULL;
+
Run();
}
HBManager::~HBManager()
{
/* Stop ripping if needed */
- StopRip();
- while( fStopRip )
+ fStatusLock->Lock();
+ if( fStatus.fMode == HB_MODE_ENCODING )
{
- Snooze( 10000 );
- }
+ fStatusLock->Unlock();
- Stop();
+ StopRip();
+ while( fStopRip )
+ {
+ Snooze( 10000 );
+ }
+ }
+ else
+ {
+ fStatusLock->Unlock();
+ }
/* Stop scanning if needed */
if( fScanner )
@@ -76,24 +107,24 @@ HBManager::~HBManager()
/* Remove temp files */
char command[1024]; memset( command, 0, 1024 );
- sprintf( command, "rm -f /tmp/HB.%d.*", fPid );
+ sprintf( command, "rm -f /tmp/HB.%d.*", GetPid() );
system( command );
+
+ delete fStatusLock;
}
void HBManager::DoWork()
{
- fPid = (int) getpid();
-
while( !fDie )
{
- /* Terminate dying threads */
if( fStopScan )
{
- fStopScan = false;
-
+ /* Destroy the thread */
delete fScanner;
fScanner = NULL;
+ /* Update interface */
+ fStatusLock->Lock();
if( fStatus.fTitleList && fStatus.fTitleList->CountItems() )
{
fStatus.fMode = HB_MODE_READY_TO_RIP;
@@ -103,83 +134,47 @@ void HBManager::DoWork()
fStatus.fMode = HB_MODE_INVALID_VOLUME;
}
fNeedUpdate = true;
+ fStatusLock->Unlock();
+
+ fStopScan = false;
}
- if( fStopRip || fError )
+ if( fStopRip || fError || fRipDone )
{
- delete fCurTitle->fDVDReader;
- delete fCurTitle->fMpegDemux;
- delete fCurTitle->fMpeg2Decoder;
- delete fCurTitle->fResizer;
- delete fCurTitle->fMpeg4Encoder;
- delete fCurTitle->fAviMuxer;
-
- if( fCurAudio1 )
+ if( fRipDone )
{
- delete fCurAudio1->fAc3Decoder;
- delete fCurAudio1->fMp3Encoder;
+ /* Wait a bit to avoid trashing frames in fifos -
+ That's kinda ugly */
+ while( fCurTitle->fPSFifo->Size() ||
+ ( fCurTitle->fMpeg2Fifo->Size() &&
+ ( !fCurAudio1 || fCurAudio1->fAc3Fifo->Size() ) &&
+ ( !fCurAudio2 || fCurAudio2->fAc3Fifo->Size() ) ) )
+ {
+ Snooze( 10000 );
+ }
+ Snooze( 500000 );
}
-
- if( fCurAudio2 )
- {
- delete fCurAudio2->fAc3Decoder;
- delete fCurAudio2->fMp3Encoder;
- }
-
- delete fCurTitle->fPSFifo;
- delete fCurTitle->fMpeg2Fifo;
- delete fCurTitle->fRawFifo;
- delete fCurTitle->fResizedFifo;
- delete fCurTitle->fMpeg4Fifo;
-
- if( fCurAudio1 )
- {
- delete fCurAudio1->fAc3Fifo;
- delete fCurAudio1->fRawFifo;
- delete fCurAudio1->fMp3Fifo;
- }
-
- if( fCurAudio2 )
- {
- delete fCurAudio2->fAc3Fifo;
- delete fCurAudio2->fRawFifo;
- delete fCurAudio2->fMp3Fifo;
- }
-
- fStatus.fMode = fError ? HB_MODE_ERROR : HB_MODE_CANCELED;
- fStopRip = false;
- fError = false;
- fNeedUpdate = true;
- }
-
- if( fRipDone )
- {
- /* This is UGLY ! */
- while( fCurTitle->fPSFifo->Size() ||
- fCurTitle->fMpeg2Fifo->Size() ||
- fCurTitle->fRawFifo->Size() ||
- fCurTitle->fResizedFifo->Size() ||
- ( fCurAudio1 && fCurAudio1->fAc3Fifo->Size() ) ||
- ( fCurAudio1 && fCurAudio1->fRawFifo->Size() ) ||
- ( fCurAudio2 && fCurAudio2->fAc3Fifo->Size() ) ||
- ( fCurAudio2 && fCurAudio2->fRawFifo->Size() ) )
+ else
{
- Snooze( 10000 );
+ fStatusLock->Lock();
+ fStatus.fMode = HB_MODE_STOPPING;
+ fNeedUpdate = true;
+ fStatusLock->Unlock();
}
-
- while( fCurTitle->fMpeg4Fifo->Size() &&
- ( !fCurAudio1 || fCurAudio1->fMp3Fifo->Size() ) &&
- ( !fCurAudio2 || fCurAudio2->fMp3Fifo->Size() ) )
+
+ /* Stop threads */
+ delete fCurTitle->fDVDReader;
+ delete fCurTitle->fAviMuxer;
+ for( int i = 0; i < fCPUCount; i++ )
{
- Snooze( 10000 );
+ delete fCurTitle->fWorkers[i];
}
- delete fCurTitle->fDVDReader;
+ /* Clean up */
delete fCurTitle->fMpegDemux;
delete fCurTitle->fMpeg2Decoder;
delete fCurTitle->fResizer;
delete fCurTitle->fMpeg4Encoder;
- delete fCurTitle->fAviMuxer;
if( fCurAudio1 )
{
@@ -193,6 +188,7 @@ void HBManager::DoWork()
delete fCurAudio2->fMp3Encoder;
}
+ /* Destroy fifos */
delete fCurTitle->fPSFifo;
delete fCurTitle->fMpeg2Fifo;
delete fCurTitle->fRawFifo;
@@ -213,9 +209,16 @@ void HBManager::DoWork()
delete fCurAudio2->fMp3Fifo;
}
- fStatus.fMode = HB_MODE_DONE;
- fRipDone = false;
+ /* Update interface */
+ fStatusLock->Lock();
+ fStatus.fMode = fStopRip ? HB_MODE_CANCELED :
+ ( fError ? HB_MODE_ERROR : HB_MODE_DONE );
fNeedUpdate = true;
+ fStatusLock->Unlock();
+
+ fStopRip = false;
+ fError = false;
+ fRipDone = false;
}
Snooze( 10000 );
@@ -224,23 +227,25 @@ void HBManager::DoWork()
bool HBManager::NeedUpdate()
{
+ fStatusLock->Lock();
if( fNeedUpdate )
{
fNeedUpdate = false;
+ fStatusLock->Unlock();
return true;
}
-
+ fStatusLock->Unlock();
+
return false;
}
HBStatus HBManager::GetStatus()
{
- return fStatus;
-}
-
-int HBManager::GetPid()
-{
- return fPid;
+ fStatusLock->Lock();
+ HBStatus status = fStatus;
+ fStatusLock->Unlock();
+
+ return status;
}
void HBManager::ScanVolumes( char * device )
@@ -254,12 +259,13 @@ void HBManager::ScanVolumes( char * device )
}
fScanner = new HBScanner( this, device );
- fScanner->Run();
+ fStatusLock->Lock();
fStatus.fMode = HB_MODE_SCANNING;
fStatus.fScannedVolume = strdup( device );
fStatus.fScannedTitle = 0;
fNeedUpdate = true;
+ fStatusLock->Unlock();
}
void HBManager::StartRip( HBTitle * title, HBAudio * audio1,
@@ -282,86 +288,77 @@ void HBManager::StartRip( HBTitle * title, HBAudio * audio1,
FixPictureSettings( title );
- Log( "HBManager::StartRip : device: %s, title: %d",
- title->fDevice, title->fIndex );
- Log( " - video : %dx%d -> %dx%d, bitrate = %d, 2-pass = %s",
+ Log( "HBManager::StartRip:" );
+ Log( "- device: %s, title: %d", title->fDevice, title->fIndex );
+ Log( "- video: %dx%d->%dx%d, bitrate=%d, 2-pass=%s, deinterlace=%s",
title->fInWidth, title->fInHeight,
title->fOutWidth, title->fOutHeight,
- title->fBitrate, title->fTwoPass ? "yes" : "no" );
- Log( " - cropping: top=%d, bottom=%d, left=%d, right=%d",
+ title->fBitrate, title->fTwoPass ? "yes" : "no",
+ title->fDeinterlace ? "yes" : "no" );
+ Log( "- cropping: top=%d, bottom=%d, left=%d, right=%d",
title->fTopCrop, title->fBottomCrop,
title->fLeftCrop, title->fRightCrop );
if( audio1 )
{
- Log( " - audio 1: lang = %s (%x), bitrate = %d",
- audio1->fDescription, audio1->fId, audio1->fOutBitrate );
+ Log( "- audio 1: lang = %s (%x), bitrate = %d",
+ audio1->fDescription, audio1->fId, audio1->fOutBitrate );
}
if( audio2 )
{
- Log( " - audio 2: lang = %s (%x), bitrate = %d",
- audio2->fDescription, audio1->fId, audio2->fOutBitrate );
+ Log( "- audio 2: lang = %s (%x), bitrate = %d",
+ audio2->fDescription, audio2->fId, audio2->fOutBitrate );
}
- /* Create fifos & threads */
-
- title->fPSFifo = new HBFifo();
- title->fMpeg2Fifo = new HBFifo();
- title->fRawFifo = new HBFifo();
- title->fResizedFifo = new HBFifo();
- title->fMpeg4Fifo = new HBFifo();
+ /* Create fifos */
+ title->fPSFifo = new HBFifo( 256 );
+ title->fMpeg2Fifo = new HBFifo( 256 );
+ title->fRawFifo = new HBFifo( 4 );
+ title->fResizedFifo = new HBFifo( 4 );
+ title->fMpeg4Fifo = new HBFifo( 4 );
+ if( audio1 )
+ {
+ audio1->fAc3Fifo = new HBFifo( 256 );
+ audio1->fRawFifo = new HBFifo( 4 );
+ audio1->fMp3Fifo = new HBFifo( 4 );
+ }
+ if( audio2 )
+ {
+ audio2->fAc3Fifo = new HBFifo( 256 );
+ audio2->fRawFifo = new HBFifo( 4 );
+ audio2->fMp3Fifo = new HBFifo( 4 );
+ }
- title->fDVDReader = new HBDVDReader( this, title );
+ /* Create decoders & encoders objects */
title->fMpegDemux = new HBMpegDemux( this, title, audio1,
audio2 );
title->fMpeg2Decoder = new HBMpeg2Decoder( this, title );
title->fResizer = new HBResizer( this, title );
title->fMpeg4Encoder = new HBMpeg4Encoder( this, title );
- title->fAviMuxer = new HBAviMuxer( this, title, audio1, audio2,
- file );
-
if( audio1 )
{
- audio1->fAc3Fifo = new HBFifo();
- audio1->fRawFifo = new HBFifo();
- audio1->fMp3Fifo = new HBFifo();
audio1->fAc3Decoder = new HBAc3Decoder( this, audio1 );
audio1->fMp3Encoder = new HBMp3Encoder( this, audio1 );
}
-
if( audio2 )
{
- audio2->fAc3Fifo = new HBFifo();
- audio2->fRawFifo = new HBFifo();
- audio2->fMp3Fifo = new HBFifo();
audio2->fAc3Decoder = new HBAc3Decoder( this, audio2 );
audio2->fMp3Encoder = new HBMp3Encoder( this, audio2 );
}
- /* Launch the threads */
-
- title->fDVDReader->Run();
- title->fMpegDemux->Run();
- title->fMpeg2Decoder->Run();
- title->fResizer->Run();
- title->fMpeg4Encoder->Run();
- title->fAviMuxer->Run();
-
- if( audio1 )
- {
- audio1->fAc3Decoder->Run();
- audio1->fMp3Encoder->Run();
- }
-
- if( audio2 )
+ /* Create and launch the threads */
+ title->fDVDReader = new HBDVDReader( this, title );
+ title->fAviMuxer = new HBAviMuxer( this, title, audio1, audio2,
+ file );
+ for( int i = 0; i < fCPUCount; i++ )
{
- audio2->fAc3Decoder->Run();
- audio2->fMp3Encoder->Run();
+ title->fWorkers[i] = new HBWorker( title, audio1, audio2 );
}
-
+
fCurTitle = title;
fCurAudio1 = audio1;
fCurAudio2 = audio2;
+ fStatusLock->Lock();
fStatus.fMode = HB_MODE_ENCODING;
fStatus.fPosition = 0;
fStatus.fFrameRate = 0;
@@ -370,6 +367,7 @@ void HBManager::StartRip( HBTitle * title, HBAudio * audio1,
fStatus.fRemainingTime = 0;
fStatus.fSuspendDate = 0;
fNeedUpdate = true;
+ fStatusLock->Unlock();
}
void HBManager::SuspendRip()
@@ -382,27 +380,17 @@ void HBManager::SuspendRip()
}
fCurTitle->fDVDReader->Suspend();
- fCurTitle->fMpegDemux->Suspend();
- fCurTitle->fMpeg2Decoder->Suspend();
- fCurTitle->fResizer->Suspend();
- fCurTitle->fMpeg4Encoder->Suspend();
fCurTitle->fAviMuxer->Suspend();
-
- if( fCurAudio1 )
+ for( int i = 0; i < fCPUCount; i++ )
{
- fCurAudio1->fAc3Decoder->Suspend();
- fCurAudio1->fMp3Encoder->Suspend();
- }
-
- if( fCurAudio2 )
- {
- fCurAudio2->fAc3Decoder->Suspend();
- fCurAudio2->fMp3Encoder->Suspend();
+ fCurTitle->fWorkers[i]->Suspend();
}
+ fStatusLock->Lock();
fStatus.fMode = HB_MODE_SUSPENDED;
fStatus.fSuspendDate = GetDate();
fNeedUpdate = true;
+ fStatusLock->Unlock();
}
void HBManager::ResumeRip()
@@ -415,27 +403,17 @@ void HBManager::ResumeRip()
}
fCurTitle->fDVDReader->Resume();
- fCurTitle->fMpegDemux->Resume();
- fCurTitle->fMpeg2Decoder->Resume();
- fCurTitle->fResizer->Resume();
- fCurTitle->fMpeg4Encoder->Resume();
fCurTitle->fAviMuxer->Resume();
-
- if( fCurAudio1 )
- {
- fCurAudio1->fAc3Decoder->Resume();
- fCurAudio1->fMp3Encoder->Resume();
- }
-
- if( fCurAudio2 )
+ for( int i = 0; i < fCPUCount; i++ )
{
- fCurAudio2->fAc3Decoder->Resume();
- fCurAudio2->fMp3Encoder->Resume();
+ fCurTitle->fWorkers[i]->Resume();
}
+ fStatusLock->Lock();
fStatus.fMode = HB_MODE_ENCODING;
fStatus.fStartDate += GetDate() - fStatus.fSuspendDate;
fNeedUpdate = true;
+ fStatusLock->Unlock();
}
void HBManager::StopRip()
@@ -448,25 +426,6 @@ void HBManager::StopRip()
}
/* Stop the threads */
-
- fCurTitle->fDVDReader->Stop();
- fCurTitle->fMpegDemux->Stop();
- fCurTitle->fMpeg2Decoder->Stop();
- fCurTitle->fMpeg4Encoder->Stop();
- fCurTitle->fAviMuxer->Stop();
-
- if( fCurAudio1 )
- {
- fCurAudio1->fAc3Decoder->Stop();
- fCurAudio1->fMp3Encoder->Stop();
- }
-
- if( fCurAudio2 )
- {
- fCurAudio2->fAc3Decoder->Stop();
- fCurAudio2->fMp3Encoder->Stop();
- }
-
fStopRip = true;
}
@@ -545,7 +504,7 @@ uint8_t * HBManager::GetPreview( HBTitle * title, uint32_t image )
/* Get the original image from the temp file */
char fileName[1024]; memset( fileName, 0, 1024 );
- sprintf( fileName, "/tmp/HB.%d.%x.%d", fPid, (uint32_t) title,
+ sprintf( fileName, "/tmp/HB.%d.%x.%d", GetPid(), (uint32_t) title,
image);
FILE * file = fopen( fileName, "r" );
fread( buf1, 3 * fInWidth * fInHeight / 2, 1, file );
@@ -632,10 +591,12 @@ uint8_t * HBManager::GetPreview( HBTitle * title, uint32_t image )
void HBManager::Scanning( char * volume, int title )
{
+ fStatusLock->Lock();
fStatus.fMode = HB_MODE_SCANNING;
fStatus.fScannedVolume = volume;
fStatus.fScannedTitle = title;
fNeedUpdate = true;
+ fStatusLock->Unlock();
}
void HBManager::ScanDone( HBList * titleList )
@@ -650,34 +611,14 @@ void HBManager::Done()
fRipDone = true;
}
-void HBManager::Error()
+void HBManager::Error( HBError error )
{
if( fStatus.fMode != HB_MODE_ENCODING )
{
return;
}
- /* Stop the threads */
-
- fCurTitle->fDVDReader->Stop();
- fCurTitle->fMpegDemux->Stop();
- fCurTitle->fMpeg2Decoder->Stop();
- fCurTitle->fResizer->Stop();
- fCurTitle->fMpeg4Encoder->Stop();
- fCurTitle->fAviMuxer->Stop();
-
- if( fCurAudio1 )
- {
- fCurAudio1->fAc3Decoder->Stop();
- fCurAudio1->fMp3Encoder->Stop();
- }
-
- if( fCurAudio2 )
- {
- fCurAudio2->fAc3Decoder->Stop();
- fCurAudio2->fMp3Encoder->Stop();
- }
-
+ fStatus.fError = error;
fError = true;
}
@@ -695,6 +636,7 @@ void HBManager::SetPosition( float pos )
return;
}
+ fStatusLock->Lock();
fStatus.fPosition = pos;
fStatus.fFrameRate = (float) fStatus.fFrames /
( ( (float) ( GetDate() - fStatus.fStartDate ) ) / 1000000 ) ;
@@ -703,5 +645,6 @@ void HBManager::SetPosition( float pos )
( 1 - fStatus.fPosition ) /
( 1000000 * fStatus.fPosition ) );
fNeedUpdate = true;
+ fStatusLock->Unlock();
}
diff --git a/core/Manager.h b/core/Manager.h
index 8aa6cec3a..dc885e5f5 100644
--- a/core/Manager.h
+++ b/core/Manager.h
@@ -1,4 +1,4 @@
-/* $Id: Manager.h,v 1.27 2003/09/30 21:21:32 titer Exp $
+/* $Id: Manager.h,v 1.32 2003/10/08 22:20:36 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -13,7 +13,8 @@
class HBManager : public HBThread
{
public:
- HBManager( bool debug = false );
+ HBManager( bool debug = false,
+ int cpuCount = 0 );
~HBManager();
void DoWork();
@@ -29,17 +30,17 @@ class HBManager : public HBThread
uint8_t * GetPreview( HBTitle * title, uint32_t image );
/* Methods called by the working threads */
- int GetPid();
void Scanning( char * volume, int title );
void ScanDone( HBList * titleList );
void Done();
- void Error();
+ void Error( HBError error );
void SetPosition( float pos );
private:
void FixPictureSettings( HBTitle * title );
int fPid;
+ int fCPUCount;
/* Booleans used in DoWork() */
bool fStopScan;
@@ -51,8 +52,10 @@ class HBManager : public HBThread
HBScanner * fScanner;
/* Status infos */
+ HBLock * fStatusLock;
bool fNeedUpdate;
HBStatus fStatus;
+
HBTitle * fCurTitle;
HBAudio * fCurAudio1;
HBAudio * fCurAudio2;
diff --git a/core/Mp3Encoder.cpp b/core/Mp3Encoder.cpp
index b4e9fe860..06d96af29 100644
--- a/core/Mp3Encoder.cpp
+++ b/core/Mp3Encoder.cpp
@@ -1,4 +1,4 @@
-/* $Id: Mp3Encoder.cpp,v 1.7 2003/09/30 14:38:15 titer Exp $
+/* $Id: Mp3Encoder.cpp,v 1.13 2003/10/08 15:00:20 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -11,113 +11,153 @@
#include <lame/lame.h>
HBMp3Encoder::HBMp3Encoder( HBManager * manager, HBAudio * audio )
- : HBThread( "mp3encoder" )
{
- fManager = manager;
- fAudio = audio;
+ fManager = manager;
+ fAudio = audio;
+
+ fLock = new HBLock();
+ fUsed = false;
fRawBuffer = NULL;
fPosInBuffer = 0;
+ fSamplesNb = 0;
fLeftSamples = NULL;
fRightSamples = NULL;
fPosition = 0;
+ fInitDone = false;
+ fMp3Buffer = NULL;
}
-void HBMp3Encoder::DoWork()
+bool HBMp3Encoder::Work()
{
- /* Wait a first buffer so we are sure that
- fAudio->fInSampleRate (set the AC3 decoder) is not garbage */
- while( !fDie && !fAudio->fRawFifo->Size() )
+ if( !Lock() )
{
- Snooze( 5000 );
+ return false;
}
-
- if( fDie )
+
+ if( !fInitDone )
{
- return;
- }
+ /* Wait for a first buffer so we know fAudio->fInSampleRate
+ is correct */
+ if( !fAudio->fRawFifo->Size() )
+ {
+ Unlock();
+ return false;
+ }
+
+ /* The idea is to have exactly one mp3 frame (i.e. 1152 samples) by
+ output buffer. As we are resampling from fInSampleRate to
+ fOutSampleRate, we will give ( 1152 * fInSampleRate ) /
+ ( 2 * fOutSampleRate ) to libmp3lame so we are sure we will
+ never get more than 1 frame at a time */
+ fCount = ( 1152 * fAudio->fInSampleRate ) /
+ ( 2 * fAudio->fOutSampleRate );
+
+ /* Init libmp3lame */
+ fGlobalFlags = lame_init();
+ lame_set_in_samplerate( fGlobalFlags, fAudio->fInSampleRate );
+ lame_set_out_samplerate( fGlobalFlags, fAudio->fOutSampleRate );
+ lame_set_brate( fGlobalFlags, fAudio->fOutBitrate );
+
+ if( lame_init_params( fGlobalFlags ) == -1 )
+ {
+ Log( "HBMp3Encoder: lame_init_params() failed" );
+ fManager->Error( HB_ERROR_MP3_INIT );
+ return false;
+ }
- /* The idea is to have exactly one mp3 frame (i.e. 1152 samples) by
- output buffer. As we are resampling from fInSampleRate to
- fOutSampleRate, we will give ( 1152 * fInSampleRate ) /
- ( 2 * fOutSampleRate ) to libmp3lame so we are sure we will
- never get more than 1 frame at a time */
- uint32_t count = ( 1152 * fAudio->fInSampleRate ) /
- ( 2 * fAudio->fOutSampleRate );
-
- /* Init libmp3lame */
- lame_global_flags * globalFlags = lame_init();
- lame_set_in_samplerate( globalFlags, fAudio->fInSampleRate );
- lame_set_out_samplerate( globalFlags, fAudio->fOutSampleRate );
- lame_set_brate( globalFlags, fAudio->fOutBitrate );
-
- if( lame_init_params( globalFlags ) == -1 )
- {
- Log( "HBMp3Encoder::DoWork() : lame_init_params() failed" );
- fManager->Error();
- return;
- }
+ fLeftSamples = (float*) malloc( fCount * sizeof( float ) );
+ fRightSamples = (float*) malloc( fCount * sizeof( float ) );
- fLeftSamples = (float*) malloc( count * sizeof( float ) );
- fRightSamples = (float*) malloc( count * sizeof( float ) );
+ fInitDone = true;
+ }
- HBBuffer * mp3Buffer = new HBBuffer( LAME_MAXMP3BUFFER );
+ bool didSomething = false;
- int ret;
for( ;; )
{
- while( fSuspend )
+ if( fMp3Buffer )
{
- Snooze( 10000 );
+ if( fAudio->fMp3Fifo->Push( fMp3Buffer ) )
+ {
+ fMp3Buffer = NULL;
+ }
+ else
+ {
+ break;
+ }
}
-
+
/* Get new samples */
- if( !GetSamples( count ) )
+ if( !GetSamples() )
{
break;
}
- ret = lame_encode_buffer_float( globalFlags,
- fLeftSamples, fRightSamples,
- count, mp3Buffer->fData,
- mp3Buffer->fSize );
+ int ret;
+ fMp3Buffer = new HBBuffer( LAME_MAXMP3BUFFER );
+ ret = lame_encode_buffer_float( fGlobalFlags, fLeftSamples,
+ fRightSamples, fCount,
+ fMp3Buffer->fData,
+ fMp3Buffer->fSize );
if( ret < 0 )
{
/* Something wrong happened */
- Log( "HBMp3Encoder : lame_encode_buffer_float() failed (%d)", ret );
- fManager->Error();
- break;
+ Log( "HBMp3Encoder : lame_encode_buffer_float() failed "
+ "(%d)", ret );
+ fManager->Error( HB_ERROR_MP3_ENCODE );
+ return false;
}
else if( ret > 0 )
{
/* We got something, send it to the muxer */
- mp3Buffer->fSize = ret;
- mp3Buffer->fKeyFrame = true;
- mp3Buffer->fPosition = fPosition;
- Push( fAudio->fMp3Fifo, mp3Buffer );
- mp3Buffer = new HBBuffer( LAME_MAXMP3BUFFER );
+ fMp3Buffer->fSize = ret;
+ fMp3Buffer->fKeyFrame = true;
+ fMp3Buffer->fPosition = fPosition;
}
+ else
+ {
+ delete fMp3Buffer;
+ fMp3Buffer = NULL;
+ }
+ fSamplesNb = 0;
+
+ didSomething = true;
}
- /* Clean up */
- delete mp3Buffer;
- free( fLeftSamples );
- free( fRightSamples );
+ Unlock();
+ return didSomething;
+}
- lame_close( globalFlags );
+bool HBMp3Encoder::Lock()
+{
+ fLock->Lock();
+ if( fUsed )
+ {
+ fLock->Unlock();
+ return false;
+ }
+ fUsed = true;
+ fLock->Unlock();
+ return true;
}
-bool HBMp3Encoder::GetSamples( uint32_t count )
+void HBMp3Encoder::Unlock()
{
- uint32_t samplesNb = 0;
+ fLock->Lock();
+ fUsed = false;
+ fLock->Unlock();
+}
- while( samplesNb < count )
+bool HBMp3Encoder::GetSamples()
+{
+ while( fSamplesNb < fCount )
{
if( !fRawBuffer )
{
- if( !( fRawBuffer = Pop( fAudio->fRawFifo ) ) )
+ if( !( fRawBuffer = fAudio->fRawFifo->Pop() ) )
{
return false;
}
@@ -126,16 +166,16 @@ bool HBMp3Encoder::GetSamples( uint32_t count )
fPosition = fRawBuffer->fPosition;
}
- int willCopy = MIN( count - samplesNb, 6 * 256 - fPosInBuffer );
+ int willCopy = MIN( fCount - fSamplesNb, 6 * 256 - fPosInBuffer );
- memcpy( fLeftSamples + samplesNb,
+ memcpy( fLeftSamples + fSamplesNb,
(float*) fRawBuffer->fData + fPosInBuffer,
willCopy * sizeof( float ) );
- memcpy( fRightSamples + samplesNb,
+ memcpy( fRightSamples + fSamplesNb,
(float*) fRawBuffer->fData + 6 * 256 + fPosInBuffer,
willCopy * sizeof( float ) );
- samplesNb += willCopy;
+ fSamplesNb += willCopy;
fPosInBuffer += willCopy;
if( fPosInBuffer == 6 * 256 )
diff --git a/core/Mp3Encoder.h b/core/Mp3Encoder.h
index 67b8647d5..fb8348961 100644
--- a/core/Mp3Encoder.h
+++ b/core/Mp3Encoder.h
@@ -1,4 +1,4 @@
-/* $Id: Mp3Encoder.h,v 1.5 2003/09/30 14:38:15 titer Exp $
+/* $Id: Mp3Encoder.h,v 1.9 2003/10/07 22:48:31 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -8,27 +8,36 @@
#define HB_MP3_ENCODER_H
#include "Common.h"
-#include "Thread.h"
-class HBMp3Encoder : public HBThread
+class HBMp3Encoder
{
public:
HBMp3Encoder( HBManager * manager,
HBAudio * audio );
+ bool Work();
private:
- void DoWork();
- bool GetSamples( uint32_t count );
+ bool Lock();
+ void Unlock();
+ bool GetSamples();
HBManager * fManager;
HBAudio * fAudio;
+ HBLock * fLock;
+ bool fUsed;
+
HBBuffer * fRawBuffer;
uint32_t fPosInBuffer; /* in samples */
+ uint32_t fSamplesNb;
float * fLeftSamples;
float * fRightSamples;
float fPosition;
+ lame_global_flags * fGlobalFlags;
+ bool fInitDone;
+ HBBuffer * fMp3Buffer;
+ uint32_t fCount;
};
#endif
diff --git a/core/Mpeg2Decoder.cpp b/core/Mpeg2Decoder.cpp
index 1ba4945bc..3149931e8 100644
--- a/core/Mpeg2Decoder.cpp
+++ b/core/Mpeg2Decoder.cpp
@@ -1,4 +1,4 @@
-/* $Id: Mpeg2Decoder.cpp,v 1.14 2003/09/30 14:38:15 titer Exp $
+/* $Id: Mpeg2Decoder.cpp,v 1.21 2003/10/09 14:21:21 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -14,55 +14,91 @@ extern "C" {
#include <ffmpeg/avcodec.h>
HBMpeg2Decoder::HBMpeg2Decoder( HBManager * manager, HBTitle * title )
- : HBThread( "mpeg2decoder" )
{
- fManager = manager;
- fTitle = title;
+ fManager = manager;
+ fTitle = title;
+
+ fLock = new HBLock();
+ fUsed = false;
+
+ fPass = 42;
+ fRawBuffer = NULL;
+ fRawBufferList = new HBList();
+ fHandle = NULL;
}
-void HBMpeg2Decoder::DoWork()
+bool HBMpeg2Decoder::Work()
{
- if( !( fMpeg2Buffer = Pop( fTitle->fMpeg2Fifo ) ) )
+ fLock->Lock();
+ if( fUsed )
{
- return;
+ fLock->Unlock();
+ return true;
}
+ fUsed = true;
+ fLock->Unlock();
- fPass = fMpeg2Buffer->fPass;
- Init();
-
- do
+ bool didSomething = false;
+
+ for( ;; )
{
- while( fSuspend )
+ /* Push decoded buffers */
+ while( ( fRawBuffer =
+ (HBBuffer*) fRawBufferList->ItemAt( 0 ) ) )
+ {
+ if( fTitle->fRawFifo->Push( fRawBuffer ) )
+ {
+ fRawBufferList->RemoveItem( fRawBuffer );
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if( fRawBufferList->CountItems() )
{
- Snooze( 10000 );
+ break;
+ }
+
+ /* Get a new buffer to decode */
+ if( !( fMpeg2Buffer = fTitle->fMpeg2Fifo->Pop() ) )
+ {
+ break;
}
+ /* (Re)init if needed */
if( fMpeg2Buffer->fPass != fPass )
{
- Close();
fPass = fMpeg2Buffer->fPass;
Init();
}
+ /* Do the job */
DecodeBuffer();
+
+ didSomething = true;
}
- while( ( fMpeg2Buffer = Pop( fTitle->fMpeg2Fifo ) ) );
+
+ fLock->Lock();
+ fUsed = false;
+ fLock->Unlock();
+
+ return didSomething;
}
void HBMpeg2Decoder::Init()
{
+ if( fHandle )
+ {
+ mpeg2_close( fHandle );
+ }
+
fLateField = false;
- /* Init libmpeg2 */
fHandle = mpeg2_init();
}
-void HBMpeg2Decoder::Close()
-{
- /* Close libmpeg2 */
- mpeg2_close( fHandle );
-}
-
void HBMpeg2Decoder::DecodeBuffer()
{
const mpeg2_info_t * info = mpeg2_info( fHandle );
@@ -83,55 +119,52 @@ void HBMpeg2Decoder::DecodeBuffer()
else if( ( state == STATE_SLICE || state == STATE_END ) &&
info->display_fbuf )
{
- HBBuffer * rawBuffer = new HBBuffer( 3 * fTitle->fInWidth *
- fTitle->fInHeight / 2 );
+ fRawBuffer = new HBBuffer( 3 * fTitle->fInWidth *
+ fTitle->fInHeight / 2 );
/* TODO : make libmpeg2 write directly in our buffer */
- memcpy( rawBuffer->fData,
+ memcpy( fRawBuffer->fData,
info->display_fbuf->buf[0],
fTitle->fInWidth * fTitle->fInHeight );
- memcpy( rawBuffer->fData + fTitle->fInWidth *
+ memcpy( fRawBuffer->fData + fTitle->fInWidth *
fTitle->fInHeight,
info->display_fbuf->buf[1],
fTitle->fInWidth * fTitle->fInHeight / 4 );
- memcpy( rawBuffer->fData + fTitle->fInWidth *
+ memcpy( fRawBuffer->fData + fTitle->fInWidth *
fTitle->fInHeight + fTitle->fInWidth *
fTitle->fInHeight / 4,
info->display_fbuf->buf[2],
fTitle->fInWidth * fTitle->fInHeight / 4 );
- rawBuffer->fPosition = fMpeg2Buffer->fPosition;
- rawBuffer->fPass = fPass;
+ fRawBuffer->fPosition = fMpeg2Buffer->fPosition;
+ fRawBuffer->fPass = fMpeg2Buffer->fPass;
+
+ fRawBufferList->AddItem( fRawBuffer );
/* NTSC pulldown kludge */
if( info->display_picture->nb_fields == 3 )
{
if( fLateField )
{
- HBBuffer * buffer =
- new HBBuffer( rawBuffer->fSize );
- buffer->fPosition = rawBuffer->fPosition;
- buffer->fPass = rawBuffer->fPass;
- memcpy( buffer->fData, rawBuffer->fData,
- buffer->fSize );
- Push( fTitle->fRawFifo, buffer );
+ HBBuffer * pulldownBuffer;
+ pulldownBuffer = new HBBuffer( fRawBuffer->fSize );
+ pulldownBuffer->fPosition = fRawBuffer->fPosition;
+ pulldownBuffer->fPass = fRawBuffer->fPass;
+ memcpy( pulldownBuffer->fData, fRawBuffer->fData,
+ pulldownBuffer->fSize );
+ fRawBufferList->AddItem( pulldownBuffer );
}
fLateField = !fLateField;
}
-
- /* Send it to the encoder */
- if( !( Push( fTitle->fRawFifo, rawBuffer ) ) )
- {
- break;
- }
}
else if( state == STATE_INVALID )
{
/* Shouldn't happen on a DVD */
- Log( "HBMpeg2Decoder : STATE_INVALID" );
+ Log( "HBMpeg2Decoder: STATE_INVALID" );
}
}
delete fMpeg2Buffer;
+ fMpeg2Buffer = NULL;
}
diff --git a/core/Mpeg2Decoder.h b/core/Mpeg2Decoder.h
index 2e1a46b3d..9d1f27f8f 100644
--- a/core/Mpeg2Decoder.h
+++ b/core/Mpeg2Decoder.h
@@ -1,4 +1,4 @@
-/* $Id: Mpeg2Decoder.h,v 1.10 2003/09/30 14:38:15 titer Exp $
+/* $Id: Mpeg2Decoder.h,v 1.15 2003/10/09 14:21:21 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -8,25 +8,28 @@
#define HB_MPEG2_DECODER_H
#include "Common.h"
-#include "Thread.h"
-class HBMpeg2Decoder : public HBThread
+class HBMpeg2Decoder
{
public:
HBMpeg2Decoder( HBManager * manager,
HBTitle * title );
+ bool Work();
private:
- void DoWork();
void Init();
- void Close();
void DecodeBuffer();
HBManager * fManager;
HBTitle * fTitle;
+ HBLock * fLock;
+ bool fUsed;
+
uint32_t fPass;
HBBuffer * fMpeg2Buffer;
+ HBBuffer * fRawBuffer;
+ HBList * fRawBufferList;
mpeg2dec_t * fHandle;
bool fLateField;
};
diff --git a/core/Mpeg4Encoder.cpp b/core/Mpeg4Encoder.cpp
index 42fb38b9e..4ef0a4c3f 100644
--- a/core/Mpeg4Encoder.cpp
+++ b/core/Mpeg4Encoder.cpp
@@ -1,4 +1,4 @@
-/* $Id: Mpeg4Encoder.cpp,v 1.15 2003/09/30 14:38:15 titer Exp $
+/* $Id: Mpeg4Encoder.cpp,v 1.23 2003/10/09 13:24:48 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -11,49 +11,97 @@
#include <ffmpeg/avcodec.h>
HBMpeg4Encoder::HBMpeg4Encoder( HBManager * manager, HBTitle * title )
- : HBThread( "mpeg4encoder" )
{
fManager = manager;
fTitle = title;
+
+ fLock = new HBLock();
+ fUsed = false;
+
+ fPass = 42;
+ fMpeg4Buffer = NULL;
+ fFile = NULL;
+ fFrame = avcodec_alloc_frame();
+ fLog = NULL;
}
-void HBMpeg4Encoder::DoWork()
+bool HBMpeg4Encoder::Work()
{
- if( !( fResizedBuffer = Pop( fTitle->fResizedFifo ) ) )
+ if( !Lock() )
{
- return;
+ return false;
}
- fPass = fResizedBuffer->fPass;
- Init();
+ bool didSomething = false;
- do
+ for( ;; )
{
- while( fSuspend )
+ if( fMpeg4Buffer )
{
- Snooze( 10000 );
+ if( fTitle->fMpeg4Fifo->Push( fMpeg4Buffer ) )
+ {
+ fMpeg4Buffer = NULL;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if( !( fResizedBuffer = fTitle->fResizedFifo->Pop() ) )
+ {
+ break;
}
if( fResizedBuffer->fPass != fPass )
{
- Close();
fPass = fResizedBuffer->fPass;
Init();
}
fManager->SetPosition( fResizedBuffer->fPosition );
EncodeBuffer();
+
+ didSomething = true;
+ }
+
+ Unlock();
+ return didSomething;
+}
+
+bool HBMpeg4Encoder::Lock()
+{
+ fLock->Lock();
+ if( fUsed )
+ {
+ fLock->Unlock();
+ return false;
}
- while( ( fResizedBuffer = Pop( fTitle->fResizedFifo ) ) );
+ fUsed = true;
+ fLock->Unlock();
+ return true;
+}
+
+void HBMpeg4Encoder::Unlock()
+{
+ fLock->Lock();
+ fUsed = false;
+ fLock->Unlock();
}
void HBMpeg4Encoder::Init()
{
+ /* Clean up if needed */
+ if( fFile )
+ {
+ fclose( fFile );
+ }
+
AVCodec * codec = avcodec_find_encoder( CODEC_ID_MPEG4 );
if( !codec )
{
Log( "HBMpeg4Encoder: avcodec_find_encoder() failed" );
- fManager->Error();
+ fManager->Error( HB_ERROR_MPEG4_INIT );
return;
}
@@ -94,19 +142,9 @@ void HBMpeg4Encoder::Init()
if( avcodec_open( fContext, codec ) < 0 )
{
Log( "HBMpeg4Encoder: avcodec_open() failed" );
- fManager->Error();
+ fManager->Error( HB_ERROR_MPEG4_INIT );
return;
}
-
- fFrame = avcodec_alloc_frame();
-}
-
-void HBMpeg4Encoder::Close()
-{
- if( fPass == 1 )
- {
- fclose( fFile );
- }
}
void HBMpeg4Encoder::EncodeBuffer()
@@ -120,31 +158,27 @@ void HBMpeg4Encoder::EncodeBuffer()
fFrame->linesize[1] = fTitle->fOutWidth / 2;
fFrame->linesize[2] = fTitle->fOutWidth / 2;
- HBBuffer * mpeg4Buffer;
- mpeg4Buffer = new HBBuffer( 3 * fTitle->fOutWidth *
+ fMpeg4Buffer = new HBBuffer( 3 * fTitle->fOutWidth *
fTitle->fOutHeight / 2 );
/* Should be really too much... */
- mpeg4Buffer->fPosition = fResizedBuffer->fPosition;
- mpeg4Buffer->fSize =
- avcodec_encode_video( fContext, mpeg4Buffer->fData,
- mpeg4Buffer->fAllocSize, fFrame );
- mpeg4Buffer->fKeyFrame = ( fContext->coded_frame->key_frame != 0 );
-
- delete fResizedBuffer;
+ fMpeg4Buffer->fPosition = fResizedBuffer->fPosition;
+ fMpeg4Buffer->fSize =
+ avcodec_encode_video( fContext, fMpeg4Buffer->fData,
+ fMpeg4Buffer->fAllocSize, fFrame );
+ fMpeg4Buffer->fKeyFrame = ( fContext->coded_frame->key_frame != 0 );
- if( fPass == 1 )
+ if( fResizedBuffer->fPass == 1 )
{
if( fContext->stats_out )
{
fprintf( fFile, "%s", fContext->stats_out );
}
- delete mpeg4Buffer;
- }
- else
- {
- /* Mux it */
- Push( fTitle->fMpeg4Fifo, mpeg4Buffer );
+ delete fMpeg4Buffer;
+ fMpeg4Buffer = NULL;
}
+
+ delete fResizedBuffer;
+ fResizedBuffer = NULL;
}
diff --git a/core/Mpeg4Encoder.h b/core/Mpeg4Encoder.h
index 1bdb29434..3d20f315a 100644
--- a/core/Mpeg4Encoder.h
+++ b/core/Mpeg4Encoder.h
@@ -1,4 +1,4 @@
-/* $Id: Mpeg4Encoder.h,v 1.8 2003/09/30 14:38:15 titer Exp $
+/* $Id: Mpeg4Encoder.h,v 1.11 2003/10/08 11:56:40 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -8,29 +8,34 @@
#define HB_MPEG4_ENCODER_H
#include "Common.h"
-#include "Thread.h"
-class HBMpeg4Encoder : public HBThread
+class HBMpeg4Encoder
{
public:
HBMpeg4Encoder( HBManager * manager,
HBTitle * title );
+ bool Work();
private:
- void DoWork();
+ bool Lock();
+ void Unlock();
+
void Init();
- void Close();
void EncodeBuffer();
HBManager * fManager;
HBTitle * fTitle;
+ HBLock * fLock;
+ bool fUsed;
+
uint32_t fPass;
HBBuffer * fResizedBuffer;
AVCodecContext * fContext;
AVFrame * fFrame;
FILE * fFile;
char * fLog;
+ HBBuffer * fMpeg4Buffer;
};
#endif
diff --git a/core/MpegDemux.cpp b/core/MpegDemux.cpp
index d3fd6b089..c01647a3a 100644
--- a/core/MpegDemux.cpp
+++ b/core/MpegDemux.cpp
@@ -1,4 +1,4 @@
-/* $Id: MpegDemux.cpp,v 1.10 2003/10/04 12:12:48 titer Exp $
+/* $Id: MpegDemux.cpp,v 1.18 2003/10/13 15:14:01 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -14,146 +14,176 @@ extern "C" {
HBMpegDemux::HBMpegDemux( HBManager * manager, HBTitle * title,
HBAudio * audio1, HBAudio * audio2 )
- : HBThread( "mpegdemux" )
{
- fManager = manager;
- fTitle = title;
- fAudio1 = audio1;
- fAudio2 = audio2;
+ fManager = manager;
+ fTitle = title;
+ fAudio1 = audio1;
+ fAudio2 = audio2;
- fPSBuffer = NULL;
- fESBuffer = NULL;
- fESBufferList = NULL;
+ fLock = new HBLock();
+ fUsed = false;
+
+ fPSBuffer = NULL;
+ fESBuffer = NULL;
+ fESBufferList = NULL;
fFirstVideoPTS = -1;
fFirstAudio1PTS = -1;
fFirstAudio2PTS = -1;
}
-void HBMpegDemux::DoWork()
+HBMpegDemux::~HBMpegDemux()
{
- for( ;; )
+ /* Free memory */
+ if( fESBufferList )
{
- while( fSuspend )
- {
- Snooze( 10000 );
- }
-
- /* Get a PS packet */
- if( !( fPSBuffer = Pop( fTitle->fPSFifo ) ) )
+ while( ( fESBuffer = (HBBuffer*) fESBufferList->ItemAt( 0 ) ) )
{
- break;
+ fESBufferList->RemoveItem( fESBuffer );
+ delete fESBuffer;
}
+ }
+ delete fLock;
+}
- /* Get the ES data in it */
- PStoES( fPSBuffer, &fESBufferList );
-
- if( !fESBufferList )
- {
- continue;
- }
+bool HBMpegDemux::Work()
+{
+ if( !Lock() )
+ {
+ return false;
+ }
+
+ bool didSomething = false;
- while( ( fESBuffer = (HBBuffer*) fESBufferList->ItemAt( 0 ) ) )
+ for( ;; )
+ {
+ /* If we have buffers waiting, try to push them */
+ if( fESBufferList )
{
- fESBufferList->RemoveItem( fESBuffer );
-
- if( fESBuffer->fPass == 1 && fESBuffer->fStreamId != 0xE0 )
+ for( uint32_t i = 0; i < fESBufferList->CountItems(); )
{
- delete fESBuffer;
- continue;
- }
+ fESBuffer = (HBBuffer*) fESBufferList->ItemAt( i );
+
+ if( fESBuffer->fPass == 1 && fESBuffer->fStreamId != 0xE0 )
+ {
+ fESBufferList->RemoveItem( fESBuffer );
+ delete fESBuffer;
+ continue;
+ }
- /* Look for a decoder for this ES */
- if( fESBuffer->fStreamId == 0xE0 )
- {
- if( fFirstVideoPTS < 0 )
+ /* Look for a decoder for this ES */
+
+ if( fESBuffer->fStreamId == 0xE0 )
{
- fFirstVideoPTS = fESBuffer->fPTS;
+ if( fFirstVideoPTS < 0 )
+ {
+ fFirstVideoPTS = fESBuffer->fPTS;
+ Log( "HBMpegDemux: got first 0xE0 packet (%lld)",
+ fFirstVideoPTS );
+ }
+ if( fTitle->fMpeg2Fifo->Push( fESBuffer ) )
+ {
+ fESBufferList->RemoveItem( fESBuffer );
+ }
+ else
+ {
+ i++;
+ }
}
- Push( fTitle->fMpeg2Fifo, fESBuffer );
- }
- else if( fAudio1 &&
- fESBuffer->fStreamId == fAudio1->fId )
- {
- /* If the audio track starts later than the video,
- repeat the first frame as long as needed */
- if( fFirstAudio1PTS < 0 )
+ else if( fAudio1 &&
+ fESBuffer->fStreamId == fAudio1->fId )
{
- fFirstAudio1PTS = fESBuffer->fPTS;
+ if( fFirstAudio1PTS < 0 )
+ {
+ fFirstAudio1PTS = fESBuffer->fPTS;
+ Log( "HBMpegDemux: got first 0x%x packet (%lld)",
+ fAudio1->fId, fFirstAudio1PTS );
- if( fFirstAudio1PTS > fFirstVideoPTS )
+ fAudio1->fDelay =
+ ( fFirstAudio1PTS - fFirstVideoPTS ) / 90;
+ }
+ if( fAudio1->fAc3Fifo->Push( fESBuffer ) )
+ {
+ fESBufferList->RemoveItem( fESBuffer );
+ }
+ else
{
- Log( "HBMpegDemux::DoWork() : audio track %x "
- "is late (%lld)", fAudio1->fId,
- fFirstAudio1PTS - fFirstVideoPTS );
- InsertSilence( fFirstAudio1PTS - fFirstVideoPTS,
- fAudio1->fAc3Fifo,
- fESBuffer );
+ i++;
}
}
- Push( fAudio1->fAc3Fifo, fESBuffer );
- }
- else if( fAudio2 &&
- fESBuffer->fStreamId == fAudio2->fId )
- {
- if( fFirstAudio2PTS < 0 )
+ else if( fAudio2 &&
+ fESBuffer->fStreamId == fAudio2->fId )
{
- fFirstAudio2PTS = fESBuffer->fPTS;
+ if( fFirstAudio2PTS < 0 )
+ {
+ fFirstAudio2PTS = fESBuffer->fPTS;
+ Log( "HBMpegDemux: got first 0x%x packet (%lld)",
+ fAudio2->fId, fFirstAudio2PTS );
- if( fFirstAudio2PTS > fFirstVideoPTS )
+ fAudio2->fDelay =
+ ( fFirstAudio2PTS - fFirstVideoPTS ) / 90;
+ }
+ if( fAudio2->fAc3Fifo->Push( fESBuffer ) )
{
- Log( "HBMpegDemux::DoWork() : audio track %x "
- "is late (%lld)", fAudio2->fId,
- fFirstAudio2PTS - fFirstVideoPTS );
- InsertSilence( fFirstAudio2PTS - fFirstVideoPTS,
- fAudio2->fAc3Fifo,
- fESBuffer );
+ fESBufferList->RemoveItem( fESBuffer );
}
+ else
+ {
+ i++;
+ }
+ }
+ else
+ {
+ fESBufferList->RemoveItem( fESBuffer );
+ delete fESBuffer;
}
- Push( fAudio2->fAc3Fifo, fESBuffer );
+ }
+
+ if( !fESBufferList->CountItems() )
+ {
+ delete fESBufferList;
+ fESBufferList = NULL;
}
else
{
- delete fESBuffer;
+ break;
}
}
- delete fESBufferList;
- }
-}
-void HBMpegDemux::InsertSilence( int64_t time, HBFifo * fifo,
- HBBuffer * buffer )
-{
- int flags = 0;
- int sampleRate = 0;
- int bitrate = 0;
- int frameSize = a52_syncinfo( buffer->fData, &flags,
- &sampleRate, &bitrate );
-
- if( !frameSize )
- {
- Log( "HBMpegDemux::InsertSilence() : a52_syncinfo() failed" );
- return;
- }
+ /* Get a PS packet */
+ if( !( fPSBuffer = fTitle->fPSFifo->Pop() ) )
+ {
+ break;
+ }
- uint32_t frames = ( ( sampleRate * time / 90000 ) + ( 3 * 256 ) )
- / ( 6 * 256 );
+ /* Get the ES data in it */
+ PStoES( fPSBuffer, &fESBufferList );
- if( !frames )
- {
- return;
+ didSomething = true;
}
- Log( "HBMpegDemux::InsertSilence() : adding %d frames", frames );
+ Unlock();
+ return didSomething;
+}
- HBBuffer * buffer2;
- for( uint32_t i = 0; i < frames; i++ )
+bool HBMpegDemux::Lock()
+{
+ fLock->Lock();
+ if( fUsed )
{
- buffer2 = new HBBuffer( frameSize );
- buffer2->fPosition = buffer->fPosition;
- memcpy( buffer2->fData, buffer->fData, frameSize );
- Push( fifo, buffer2 );
- }
+ fLock->Unlock();
+ return false;
+ }
+ fUsed = true;
+ fLock->Unlock();
+ return true;
+}
+
+void HBMpegDemux::Unlock()
+{
+ fLock->Lock();
+ fUsed = false;
+ fLock->Unlock();
}
bool PStoES( HBBuffer * psBuffer, HBList ** _esBufferList )
diff --git a/core/MpegDemux.h b/core/MpegDemux.h
index ef5b1b3d9..187a08de9 100644
--- a/core/MpegDemux.h
+++ b/core/MpegDemux.h
@@ -1,4 +1,4 @@
-/* $Id: MpegDemux.h,v 1.6 2003/10/04 12:12:48 titer Exp $
+/* $Id: MpegDemux.h,v 1.11 2003/10/09 13:24:48 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -8,26 +8,29 @@
#define HB_MPEG_DEMUX_H
#include "Common.h"
-#include "Thread.h"
bool PStoES( HBBuffer * psBuffer, HBList ** _esBufferList );
-class HBMpegDemux : public HBThread
+class HBMpegDemux
{
public:
- HBMpegDemux( HBManager * manager, HBTitle * title,
- HBAudio * audio1, HBAudio * audio2 );
+ HBMpegDemux( HBManager * manager, HBTitle * title,
+ HBAudio * audio1, HBAudio * audio2 );
+ ~HBMpegDemux();
+ bool Work();
private:
- void DoWork();
- void InsertSilence( int64_t time, HBFifo * fifo,
- HBBuffer * buffer );
+ bool Lock();
+ void Unlock();
HBManager * fManager;
HBTitle * fTitle;
HBAudio * fAudio1;
HBAudio * fAudio2;
+ HBLock * fLock;
+ bool fUsed;
+
HBBuffer * fPSBuffer;
HBBuffer * fESBuffer;
HBList * fESBufferList;
diff --git a/core/Resizer.cpp b/core/Resizer.cpp
index e3cae3986..0b9c794db 100644
--- a/core/Resizer.cpp
+++ b/core/Resizer.cpp
@@ -1,4 +1,4 @@
-/* $Id: Resizer.cpp,v 1.3 2003/09/30 14:38:15 titer Exp $
+/* $Id: Resizer.cpp,v 1.8 2003/10/09 13:24:48 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -11,79 +11,131 @@
#include <ffmpeg/avcodec.h>
HBResizer::HBResizer( HBManager * manager, HBTitle * title )
- : HBThread( "resizer" )
{
- fManager = manager;
- fTitle = title;
-}
+ fManager = manager;
+ fTitle = title;
+
+ /* Lock */
+ fLock = new HBLock();
+ fUsed = false;
-void HBResizer::DoWork()
-{
/* Init libavcodec */
- ImgReSampleContext * resampleContext =
+ fResampleContext =
img_resample_full_init( fTitle->fOutWidth, fTitle->fOutHeight,
fTitle->fInWidth, fTitle->fInHeight,
fTitle->fTopCrop, fTitle->fBottomCrop,
fTitle->fLeftCrop, fTitle->fRightCrop );
/* Buffers & pictures */
- HBBuffer * rawBuffer, * deinterlacedBuffer, * resizedBuffer;
- AVPicture rawPicture, deinterlacedPicture, resizedPicture;
-
- deinterlacedBuffer = new HBBuffer( 3 * fTitle->fInWidth *
- fTitle->fInHeight / 2 );
- avpicture_fill( &deinterlacedPicture, deinterlacedBuffer->fData,
+ fRawBuffer = NULL;
+ fDeinterlacedBuffer = new HBBuffer( 3 * fTitle->fInWidth *
+ fTitle->fInHeight / 2 );
+ fResizedBuffer = NULL;
+ fRawPicture = (AVPicture*) malloc( sizeof( AVPicture ) );
+ fDeinterlacedPicture = (AVPicture*) malloc( sizeof( AVPicture ) );
+ fResizedPicture = (AVPicture*) malloc( sizeof( AVPicture ) );
+
+ avpicture_fill( fDeinterlacedPicture, fDeinterlacedBuffer->fData,
PIX_FMT_YUV420P, fTitle->fInWidth,
fTitle->fInHeight );
+}
+
+HBResizer::~HBResizer()
+{
+ /* Free memory */
+ free( fResizedPicture );
+ free( fDeinterlacedPicture );
+ free( fRawPicture );
+ if( fResizedBuffer ) delete fResizedBuffer;
+ delete fDeinterlacedBuffer;
+ img_resample_close( fResampleContext );
+ delete fLock;
+}
+bool HBResizer::Work()
+{
+ if( !Lock() )
+ {
+ return false;
+ }
+
+ bool didSomething = false;
+
for( ;; )
{
- while( fSuspend )
+ /* Push the latest resized buffer */
+ if( fResizedBuffer )
{
- Snooze( 10000 );
+ if( fTitle->fResizedFifo->Push( fResizedBuffer ) )
+ {
+ fResizedBuffer = NULL;
+ }
+ else
+ {
+ break;
+ }
}
-
- if( !( rawBuffer = Pop( fTitle->fRawFifo ) ) )
+
+ /* Get a new raw picture */
+ if( !( fRawBuffer = fTitle->fRawFifo->Pop() ) )
{
break;
}
- avpicture_fill( &rawPicture, rawBuffer->fData,
+ /* Do the job */
+ avpicture_fill( fRawPicture, fRawBuffer->fData,
PIX_FMT_YUV420P, fTitle->fInWidth,
fTitle->fInHeight );
- resizedBuffer = new HBBuffer( 3 * fTitle->fOutWidth *
+ fResizedBuffer = new HBBuffer( 3 * fTitle->fOutWidth *
fTitle->fOutHeight / 2 );
- resizedBuffer->fPosition = rawBuffer->fPosition;
- resizedBuffer->fPass = rawBuffer->fPass;
- avpicture_fill( &resizedPicture, resizedBuffer->fData,
+ fResizedBuffer->fPosition = fRawBuffer->fPosition;
+ fResizedBuffer->fPass = fRawBuffer->fPass;
+ avpicture_fill( fResizedPicture, fResizedBuffer->fData,
PIX_FMT_YUV420P, fTitle->fOutWidth,
fTitle->fOutHeight );
-
if( fTitle->fDeinterlace )
{
- avpicture_deinterlace( &deinterlacedPicture, &rawPicture,
+ avpicture_deinterlace( fDeinterlacedPicture, fRawPicture,
PIX_FMT_YUV420P,
fTitle->fInWidth,
fTitle->fInHeight );
- img_resample( resampleContext, &resizedPicture,
- &deinterlacedPicture );
+ img_resample( fResampleContext, fResizedPicture,
+ fDeinterlacedPicture );
}
else
{
- img_resample( resampleContext, &resizedPicture,
- &rawPicture );
+ img_resample( fResampleContext, fResizedPicture,
+ fRawPicture );
}
+ delete fRawBuffer;
+ fRawBuffer = NULL;
- Push( fTitle->fResizedFifo, resizedBuffer );
- delete rawBuffer;
+ didSomething = true;
}
- /* Free memory */
- delete deinterlacedBuffer;
+ Unlock();
+ return didSomething;
+}
- /* Close libavcodec */
- img_resample_close( resampleContext );
+bool HBResizer::Lock()
+{
+ fLock->Lock();
+ if( fUsed )
+ {
+ fLock->Unlock();
+ return false;
+ }
+ fUsed = true;
+ fLock->Unlock();
+ return true;
+}
+
+void HBResizer::Unlock()
+{
+ fLock->Lock();
+ fUsed = false;
+ fLock->Unlock();
}
diff --git a/core/Resizer.h b/core/Resizer.h
index 1fdde85d3..f6d4a4568 100644
--- a/core/Resizer.h
+++ b/core/Resizer.h
@@ -1,4 +1,4 @@
-/* $Id: Resizer.h,v 1.2 2003/09/30 14:38:15 titer Exp $
+/* $Id: Resizer.h,v 1.5 2003/10/07 22:48:31 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -8,18 +8,31 @@
#define HB_RESIZER_H
#include "Common.h"
-#include "Thread.h"
-class HBResizer : public HBThread
+class HBResizer
{
public:
HBResizer( HBManager * manager, HBTitle * title );
+ ~HBResizer();
+ bool Work();
private:
- void DoWork();
-
+ bool Lock();
+ void Unlock();
+
HBManager * fManager;
HBTitle * fTitle;
+
+ HBLock * fLock;
+ bool fUsed;
+
+ ImgReSampleContext * fResampleContext;
+ HBBuffer * fRawBuffer;
+ HBBuffer * fDeinterlacedBuffer;
+ HBBuffer * fResizedBuffer;
+ AVPicture * fRawPicture;
+ AVPicture * fDeinterlacedPicture;
+ AVPicture * fResizedPicture;
};
#endif
diff --git a/core/Scanner.cpp b/core/Scanner.cpp
index 575b25573..44ff6be3a 100644
--- a/core/Scanner.cpp
+++ b/core/Scanner.cpp
@@ -1,4 +1,4 @@
-/* $Id: Scanner.cpp,v 1.18 2003/10/04 12:12:48 titer Exp $
+/* $Id: Scanner.cpp,v 1.23 2003/10/13 14:12:18 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -20,21 +20,23 @@ extern "C" {
}
HBScanner::HBScanner( HBManager * manager, char * device )
- : HBThread( "scanner" )
+ : HBThread( "scanner", HB_NORMAL_PRIORITY )
{
fManager = manager;
fDevice = strdup( device );
+
+ Run();
}
void HBScanner::DoWork()
{
- Log( "HBScanner::DoWork() : opening device %s", fDevice );
+ Log( "HBScanner: opening device %s", fDevice );
dvdplay_ptr vmg;
vmg = dvdplay_open( fDevice, NULL, NULL );
if( !vmg )
{
- Log( "HBScanner::DoWork() : dvdplay_open() failed (%s)",
+ Log( "HBScanner: dvdplay_open() failed (%s)",
fDevice );
fManager->ScanDone( NULL );
return;
@@ -50,7 +52,7 @@ void HBScanner::DoWork()
break;
}
- Log( "HBScanner::DoWork() : scanning title %d", i + 1 );
+ Log( "HBScanner: scanning title %d", i + 1 );
fManager->Scanning( fDevice, i + 1 );
title = new HBTitle( fDevice, i + 1 );
@@ -61,12 +63,12 @@ void HBScanner::DoWork()
}
else
{
- Log( "HBScanner::DoWork() : ignoring title %d", i + 1 );
+ Log( "HBScanner: ignoring title %d", i + 1 );
delete title;
}
}
- Log( "HBScanner::DoWork() : closing device %s", fDevice );
+ Log( "HBScanner: closing device %s", fDevice );
dvdplay_close( vmg );
fManager->ScanDone( titleList );
@@ -78,7 +80,7 @@ bool HBScanner::ScanTitle( HBTitle * title, dvdplay_ptr vmg )
/* Length */
title->fLength = dvdplay_title_time( vmg );
- Log( "HBScanner::ScanTitle() : title length is %lld seconds",
+ Log( "HBScanner::ScanTitle: title length is %lld seconds",
title->fLength );
/* Discard titles under 10 seconds */
@@ -101,20 +103,46 @@ bool HBScanner::ScanTitle( HBTitle * title, dvdplay_ptr vmg )
}
int id = dvdplay_audio_id( vmg, i );
- if( id > 0 )
+
+ if( id < 1 )
{
- if( ( id & 0xFF ) != 0xBD )
+ continue;
+ }
+
+ if( ( id & 0xFF ) != 0xBD )
+ {
+ Log( "HBScanner::ScanTitle: non-AC3 audio track "
+ "detected, ignoring" );
+ continue;
+ }
+
+ /* Check if we don't already found an track with the same id */
+ audio = NULL;
+ for( uint32_t j = 0; j < title->fAudioList->CountItems(); j++ )
+ {
+ audio = (HBAudio*) title->fAudioList->ItemAt( j );
+ if( (uint32_t) id == audio->fId )
+ {
+ break;
+ }
+ else
{
- Log( "HBScanner::ScanTitle() : non-AC3 audio track "
- "detected, ignoring" );
- continue;
+ audio = NULL;
}
- attr = dvdplay_audio_attr( vmg, i );
- audio = new HBAudio( id, LanguageForCode( attr->lang_code ) );
- Log( "HBScanner::ScanTitle() : new language (%x, %s)",
- id, audio->fDescription );
- title->fAudioList->AddItem( audio );
}
+
+ if( audio )
+ {
+ Log( "HBScanner::ScanTitle: discarding duplicate track %x",
+ id );
+ continue;
+ }
+
+ attr = dvdplay_audio_attr( vmg, i );
+ audio = new HBAudio( id, LanguageForCode( attr->lang_code ) );
+ Log( "HBScanner::ScanTitle: new language (%x, %s)",
+ id, audio->fDescription );
+ title->fAudioList->AddItem( audio );
}
/* Discard titles with no audio tracks */
@@ -206,7 +234,7 @@ bool HBScanner::DecodeFrame( HBTitle * title, dvdplay_ptr vmg, int i )
if( dvdplay_read( vmg, psBuffer->fData, 1 ) != 1 ||
!PStoES( psBuffer, &esBufferList ) )
{
- Log( "HBScanner::DecodeFrame : failed to get "
+ Log( "HBScanner::DecodeFrame: failed to get "
"a valid PS packet" );
mpeg2_close( handle );
fclose( file );
diff --git a/core/Thread.cpp b/core/Thread.cpp
index 43f058cad..8f7e6c971 100644
--- a/core/Thread.cpp
+++ b/core/Thread.cpp
@@ -1,4 +1,4 @@
-/* $Id: Thread.cpp,v 1.19 2003/10/01 21:17:17 titer Exp $
+/* $Id: Thread.cpp,v 1.23 2003/10/09 23:33:36 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -34,61 +34,35 @@ HBThread::~HBThread()
pthread_join( fThread, NULL );
#endif
- Log( "Thread %d stopped (\"%s\")", fThread, fName );
+ Log( "HBThread: thread %d stopped (\"%s\")", fThread, fName );
free( fName );
}
-void HBThread::Run()
+void HBThread::Suspend()
{
-#if defined( SYS_BEOS )
- fThread = spawn_thread( (int32 (*)(void *)) ThreadFunc,
- fName, fPriority, this );
- resume_thread( fThread );
-#elif defined( SYS_MACOSX ) || defined( SYS_LINUX )
- pthread_create( &fThread, NULL,
- (void * (*)(void *)) ThreadFunc, this );
-#if 0
-#if defined( SYS_MACOSX )
- int policy;
- struct sched_param param;
- memset( &param, 0, sizeof( struct sched_param ) );
- if( fPriority < 0 )
- {
- param.sched_priority = (-1) * fPriority;
- policy = SCHED_OTHER;
- }
- else
- {
- param.sched_priority = fPriority;
- policy = SCHED_RR;
- }
- if ( pthread_setschedparam( fThread, policy, &param ) )
- {
- Log( "HBThread::Run : couldn't set thread priority" );
- }
-#endif
-#endif
-#endif
-
- Log( "Thread %d started (\"%s\")", fThread, fName );
+ fSuspend = true;
}
-void HBThread::Stop()
+void HBThread::Resume()
{
- Log( "Stopping thread %d (\"%s\")", fThread, fName );
-
- fDie = true;
fSuspend = false;
}
-void HBThread::Suspend()
+int HBThread::GetPid()
{
- fSuspend = true;
+ return fPid;
}
-void HBThread::Resume()
+void HBThread::Run()
{
- fSuspend = false;
+#if defined( SYS_BEOS )
+ fThread = spawn_thread( (int32 (*)(void *)) ThreadFunc,
+ fName, fPriority, this );
+ resume_thread( fThread );
+#elif defined( SYS_MACOSX ) || defined( SYS_LINUX )
+ pthread_create( &fThread, NULL,
+ (void * (*)(void *)) ThreadFunc, this );
+#endif
}
bool HBThread::Push( HBFifo * fifo, HBBuffer * buffer )
@@ -126,6 +100,21 @@ HBBuffer * HBThread::Pop( HBFifo * fifo )
void HBThread::ThreadFunc( HBThread * _this )
{
+#if defined( SYS_MACOSX )
+ struct sched_param param;
+ memset( &param, 0, sizeof( struct sched_param ) );
+ param.sched_priority = _this->fPriority;
+ if ( pthread_setschedparam( _this->fThread, SCHED_OTHER, &param ) )
+ {
+ Log( "HBThread: couldn't set thread priority" );
+ }
+#endif
+
+ _this->fPid = (int) getpid();
+
+ Log( "HBThread: thread %d started (\"%s\")",
+ _this->fThread, _this->fName );
+
_this->DoWork();
}
diff --git a/core/Thread.h b/core/Thread.h
index 6afd59f53..0a09fabc9 100644
--- a/core/Thread.h
+++ b/core/Thread.h
@@ -1,4 +1,4 @@
-/* $Id: Thread.h,v 1.16 2003/10/01 21:17:17 titer Exp $
+/* $Id: Thread.h,v 1.19 2003/10/09 16:03:51 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -13,8 +13,8 @@
# define HB_LOW_PRIORITY 5
# define HB_NORMAL_PRIORITY 10
#elif defined( SYS_MACOSX )
-# define HB_LOW_PRIORITY (-47)
-# define HB_NORMAL_PRIORITY (-47) /* FIXME */
+# define HB_LOW_PRIORITY 0
+# define HB_NORMAL_PRIORITY 31
#elif defined( SYS_LINUX )
/* Actually unused */
# define HB_LOW_PRIORITY 0
@@ -27,12 +27,12 @@ class HBThread
HBThread( char * name,
int priority = HB_LOW_PRIORITY );
virtual ~HBThread();
- void Run();
- void Stop();
void Suspend();
void Resume();
+ int GetPid();
protected:
+ void Run();
bool Push( HBFifo * fifo, HBBuffer * buffer );
HBBuffer * Pop( HBFifo * fifo );
@@ -51,6 +51,7 @@ class HBThread
#elif defined( SYS_MACOSX ) || defined( SYS_LINUX )
pthread_t fThread;
#endif
+ int fPid;
};
#if defined( SYS_BEOS )
diff --git a/core/Worker.cpp b/core/Worker.cpp
new file mode 100644
index 000000000..5f1352026
--- /dev/null
+++ b/core/Worker.cpp
@@ -0,0 +1,150 @@
+/* $Id: Worker.cpp,v 1.9 2003/10/13 17:59:40 titer Exp $
+
+ This file is part of the HandBrake source code.
+ Homepage: <http://beos.titer.org/handbrake/>.
+ It may be used under the terms of the GNU General Public License. */
+
+#include "Ac3Decoder.h"
+#include "Mp3Encoder.h"
+#include "Mpeg2Decoder.h"
+#include "Mpeg4Encoder.h"
+#include "MpegDemux.h"
+#include "Resizer.h"
+#include "Worker.h"
+
+HBWorker::HBWorker( HBTitle * title, HBAudio * audio1,
+ HBAudio * audio2 )
+ : HBThread( "worker")
+{
+ fTitle = title;
+ fAudio1 = audio1;
+ fAudio2 = audio2;
+
+ Run();
+}
+
+void HBWorker::DoWork()
+{
+ bool didSomething;
+ uint64_t mpegDemux = 0;
+ uint64_t mpeg2Decoder = 0;
+ uint64_t resizer = 0;
+ uint64_t mpeg4Encoder = 0;
+ uint64_t ac3Decoder1 = 0;
+ uint64_t mp3Encoder1 = 0;
+ uint64_t ac3Decoder2 = 0;
+ uint64_t mp3Encoder2 = 0;
+ uint64_t tmpDate;
+
+ while( !fDie )
+ {
+ didSomething = false;
+
+ tmpDate = GetDate();
+ if( fTitle->fMpegDemux->Work() )
+ {
+ mpegDemux += ( GetDate() - tmpDate );
+ didSomething = true;
+ }
+
+ if( fDie ) break;
+
+ tmpDate = GetDate();
+ if( fTitle->fMpeg2Decoder->Work() )
+ {
+ mpeg2Decoder += ( GetDate() - tmpDate );
+ didSomething = true;
+ }
+
+ if( fDie ) break;
+
+ tmpDate = GetDate();
+ if( fTitle->fResizer->Work() )
+ {
+ resizer += ( GetDate() - tmpDate );
+ didSomething = true;
+ }
+
+ if( fDie ) break;
+
+ tmpDate = GetDate();
+ if( fTitle->fMpeg4Encoder->Work() )
+ {
+ mpeg4Encoder += ( GetDate() - tmpDate );
+ didSomething = true;
+ }
+
+ if( fDie ) break;
+
+ if( fAudio1 )
+ {
+ tmpDate = GetDate();
+ if( fAudio1->fAc3Decoder->Work() )
+ {
+ ac3Decoder1 += ( GetDate() - tmpDate );
+ didSomething = true;
+ }
+
+ if( fDie ) break;
+
+ tmpDate = GetDate();
+ if( fAudio1->fMp3Encoder->Work() )
+ {
+ mp3Encoder1 += ( GetDate() - tmpDate );
+ didSomething = true;
+ }
+
+ if( fDie ) break;
+ }
+
+ if( fAudio2 )
+ {
+ tmpDate = GetDate();
+ if( fAudio2->fAc3Decoder->Work() )
+ {
+ ac3Decoder2 += ( GetDate() - tmpDate );
+ didSomething = true;
+ }
+
+ if( fDie ) break;
+
+ tmpDate = GetDate();
+ if( fAudio2->fMp3Encoder->Work() )
+ {
+ mp3Encoder2 += ( GetDate() - tmpDate );
+ didSomething = true;
+ }
+
+ if( fDie ) break;
+ }
+
+ if( !didSomething )
+ {
+ Snooze( 10000 );
+ }
+
+ while( fSuspend )
+ {
+ Snooze( 10000 );
+ }
+ }
+
+ tmpDate = mpegDemux + mpeg2Decoder + resizer + mpeg4Encoder +
+ ac3Decoder1 + mp3Encoder1 + ac3Decoder2 + mp3Encoder2;
+ Log( "HBWorker stopped. CPU utilization:" );
+ Log( "- MPEG demuxer: %.2f %%", 100 * (float) mpegDemux / tmpDate );
+ Log( "- MPEG-2 decoder: %.2f %%", 100 * (float) mpeg2Decoder / tmpDate );
+ Log( "- Resizer: %.2f %%", 100 * (float) resizer / tmpDate );
+ Log( "- MPEG-4 encoder: %.2f %%", 100 * (float) mpeg4Encoder / tmpDate );
+ if( fAudio1 )
+ {
+ Log( "- AC3 decoder 1: %.2f %%", 100 * (float) ac3Decoder1 / tmpDate );
+ Log( "- MP3 encoder 1: %.2f %%", 100 * (float) mp3Encoder1 / tmpDate );
+ }
+ if( fAudio2 )
+ {
+ Log( "- AC3 decoder 2: %.2f %%", 100 * (float) ac3Decoder2 / tmpDate );
+ Log( "- MP3 encoder 2: %.2f %%", 100 * (float) mp3Encoder2 / tmpDate );
+ }
+}
+
diff --git a/core/Worker.h b/core/Worker.h
new file mode 100644
index 000000000..d2d0324d8
--- /dev/null
+++ b/core/Worker.h
@@ -0,0 +1,27 @@
+/* $Id: Worker.h,v 1.1 2003/10/07 17:40:06 titer Exp $
+
+ This file is part of the HandBrake source code.
+ Homepage: <http://beos.titer.org/handbrake/>.
+ It may be used under the terms of the GNU General Public License. */
+
+#ifndef HB_WORKER_H
+#define HB_WORKER_H
+
+#include "Common.h"
+#include "Thread.h"
+
+class HBWorker : public HBThread
+{
+ public:
+ HBWorker( HBTitle * title, HBAudio * audio1,
+ HBAudio * audio2 );
+
+ private:
+ void DoWork();
+
+ HBTitle * fTitle;
+ HBAudio * fAudio1;
+ HBAudio * fAudio2;
+};
+
+#endif
diff --git a/macosx/HBController.h b/macosx/Controller.h
index 2e3339c74..4759a1d5b 100644
--- a/macosx/HBController.h
+++ b/macosx/Controller.h
@@ -1,4 +1,4 @@
-/* $Id: HBController.h,v 1.19 2003/10/06 21:13:45 titer Exp $
+/* $Id: Controller.h,v 1.6 2003/10/13 23:09:56 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -6,14 +6,19 @@
#include <Cocoa/Cocoa.h>
-#include "Manager.h"
+#include "Common.h"
#include "PictureGLView.h"
+#include "TargetSizeField.h"
@interface HBController : NSObject
{
+ bool fDie;
+
IBOutlet NSWindow * fWindow;
+ /* Scan view */
+ uint64_t fLastDVDDetection;
IBOutlet NSView * fScanView;
IBOutlet NSMatrix * fScanMatrix;
IBOutlet NSPopUpButton * fDVDPopUp;
@@ -23,25 +28,44 @@
IBOutlet NSProgressIndicator * fScanProgress;
IBOutlet NSButton * fScanButton;
+ IBOutlet NSView * fTempView;
+
+ /* Rip view */
IBOutlet NSView * fRipView;
+
+ /* Video box */
IBOutlet NSPopUpButton * fTitlePopUp;
- IBOutlet NSPopUpButton * fAudioPopUp;
- IBOutlet NSTextField * fVideoField;
- IBOutlet NSStepper * fVideoStepper;
- IBOutlet NSTextField * fAudioField;
- IBOutlet NSStepper * fAudioStepper;
+ IBOutlet NSPopUpButton * fVideoCodecPopUp;
+ IBOutlet NSMatrix * fVideoMatrix;
+ IBOutlet NSTextField * fCustomBitrateField;
+ IBOutlet HBTargetSizeField * fTargetSizeField;
IBOutlet NSButton * fTwoPassCheck;
IBOutlet NSButton * fCropButton;
+
+ /* Audio box */
+ IBOutlet NSPopUpButton * fLanguagePopUp;
+ IBOutlet NSPopUpButton * fSecondaryLanguagePopUp;
+ IBOutlet NSPopUpButton * fAudioCodecPopUp;
+ IBOutlet NSPopUpButton * fAudioBitratePopUp;
+
+ /* Destination box */
+ IBOutlet NSPopUpButton * fFileFormatPopUp;
IBOutlet NSTextField * fFileField;
- IBOutlet NSButton * fRipBrowseButton;
+ IBOutlet NSButton * fFileBrowseButton;
+
+ /* Bottom */
IBOutlet NSTextField * fRipStatusField;
+ IBOutlet NSTextField * fRipInfoField;
IBOutlet NSProgressIndicator * fRipProgress;
IBOutlet NSButton * fSuspendButton;
IBOutlet NSButton * fRipButton;
+
+ /* "Done" alert panel */
IBOutlet NSPanel * fDonePanel;
+ /* Crop & resize panel */
IBOutlet NSPanel * fPicturePanel;
- IBOutlet PictureGLView * fPictureGLView;
+ IBOutlet HBPictureGLView * fPictureGLView;
IBOutlet NSTextField * fWidthField;
IBOutlet NSStepper * fWidthStepper;
IBOutlet NSButton * fDeinterlaceCheck;
@@ -56,22 +80,28 @@
IBOutlet NSTextField * fInfoField;
int fPicture;
- IBOutlet NSView * fBlankView;
HBManager * fManager;
HBList * fTitleList;
}
+- (IBAction) ScanMatrixChanged: (id) sender;
- (IBAction) BrowseDVD: (id) sender;
- (void) BrowseDVDDone: (NSOpenPanel *) sheet
returnCode: (int) returnCode contextInfo: (void *) contextInfo;
- (IBAction) Scan: (id) sender;
+- (IBAction) TitlePopUpChanged: (id) sender;
+- (IBAction) VideoMatrixChanged: (id) sender;
+- (IBAction) AudioPopUpChanged: (id) sender;
- (IBAction) BrowseFile: (id) sender;
- (void) BrowseFileDone: (NSSavePanel *) sheet
returnCode: (int) returnCode contextInfo: (void *) contextInfo;
- (IBAction) ShowPicturePanel: (id) sender;
- (IBAction) ClosePanel: (id) sender;
- (IBAction) Rip: (id) sender;
+- (void) OverwriteAlertDone: (NSWindow *) sheet
+ returnCode: (int) returnCode contextInfo: (void *) contextInfo;
+- (void) _Rip;
- (IBAction) Cancel: (id) sender;
- (IBAction) Suspend: (id) sender;
- (IBAction) Resume: (id) sender;
@@ -82,7 +112,5 @@
- (void) UpdateIntf: (NSTimer *) timer;
- (void) DetectDrives;
-- (void) ScanEnableIntf: (id) sender;
-- (void) UpdatePopUp: (id) sender;
@end
diff --git a/macosx/HBController.mm b/macosx/Controller.mm
index f46d0221a..402d721fa 100644
--- a/macosx/HBController.mm
+++ b/macosx/Controller.mm
@@ -1,4 +1,4 @@
-/* $Id: HBController.mm,v 1.24 2003/10/06 21:13:45 titer Exp $
+/* $Id: Controller.mm,v 1.10 2003/10/13 23:09:56 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://beos.titer.org/handbrake/>.
@@ -10,7 +10,7 @@
#include <IOKit/storage/IOMedia.h>
#include <IOKit/storage/IODVDMedia.h>
-#include "HBController.h"
+#include "Controller.h"
#include "Manager.h"
@implementation HBController
@@ -21,15 +21,17 @@
fManager = new HBManager( true );
/* Update the GUI every 1/10 sec */
+ fDie = false;
[NSTimer scheduledTimerWithTimeInterval: 0.1
target: self selector: @selector( UpdateIntf: )
- userInfo: nil repeats: FALSE];
+ userInfo: nil repeats: YES];
}
- (NSApplicationTerminateReply) applicationShouldTerminate:
(NSApplication *) app
{
/* Clean up */
+ fDie = true;
delete fManager;
return NSTerminateNow;
@@ -37,17 +39,21 @@
- (void) awakeFromNib
{
- [[fScanMatrix cellAtRow: 0 column: 0]
- setAction: @selector( ScanEnableIntf: )];
- [[fScanMatrix cellAtRow: 0 column: 0] setTarget: self];
- [[fScanMatrix cellAtRow: 1 column: 0]
- setAction: @selector( ScanEnableIntf: )];
- [[fScanMatrix cellAtRow: 1 column: 0] setTarget: self];
+ [fDVDPopUp removeAllItems];
[fScanProgress setStyle: NSProgressIndicatorSpinningStyle];
[fScanProgress setDisplayedWhenStopped: NO];
- [fRipProgress setIndeterminate: NO];
- [fTitlePopUp removeAllItems];
- [fAudioPopUp removeAllItems];
+ [fAudioBitratePopUp removeAllItems];
+ [fAudioBitratePopUp addItemWithTitle: @"32"];
+ [fAudioBitratePopUp addItemWithTitle: @"64"];
+ [fAudioBitratePopUp addItemWithTitle: @"96"];
+ [fAudioBitratePopUp addItemWithTitle: @"128"];
+ [fAudioBitratePopUp addItemWithTitle: @"160"];
+ [fAudioBitratePopUp addItemWithTitle: @"192"];
+ [fAudioBitratePopUp addItemWithTitle: @"224"];
+ [fAudioBitratePopUp addItemWithTitle: @"256"];
+ [fAudioBitratePopUp addItemWithTitle: @"288"];
+ [fAudioBitratePopUp addItemWithTitle: @"320"];
+ [fAudioBitratePopUp selectItemWithTitle: @"128"];
char string[1024]; memset( string, 0, 1024 );
snprintf( string, 1024, "%s/Desktop/Movie.avi", getenv( "HOME" ) );
@@ -59,11 +65,9 @@
[fWindow center];
/* Detect DVD drives */
+ fLastDVDDetection = GetDate();
[self DetectDrives];
- [self ScanEnableIntf: self];
-
- /* Init a blank view, used in window resizing animation */
- fBlankView = [[NSView alloc] init];
+ [self ScanMatrixChanged: self];
}
- (BOOL) windowShouldClose: (id) sender
@@ -98,6 +102,21 @@
}
}
+- (IBAction) VideoMatrixChanged: (id) sender;
+{
+ if( ![fVideoMatrix selectedRow] )
+ {
+ [fCustomBitrateField setEnabled: YES];
+ [fTargetSizeField setEnabled: NO];
+ }
+ else
+ {
+ [fCustomBitrateField setEnabled: NO];
+ [fTargetSizeField setEnabled: YES];
+ [fTargetSizeField UpdateBitrate];
+ }
+}
+
- (IBAction) BrowseFile: (id) sender
{
/* Open a panel to let the user choose and update the text field */
@@ -188,15 +207,12 @@
/* XXX */
newSize.width = 762 /*fPicturePanelSize.width*/ +
title->fOutWidthMax - 720;
- newSize.height = 754 /*fPicturePanelSize.height*/ +
+ newSize.height = 740 /*fPicturePanelSize.height*/ +
title->fOutHeightMax - 576;
[fPicturePanel setContentSize: newSize];
- [NSApp beginSheet: fPicturePanel
- modalForWindow: fWindow
- modalDelegate: nil
- didEndSelector: nil
- contextInfo: nil];
+ [NSApp beginSheet: fPicturePanel modalForWindow: fWindow
+ modalDelegate: nil didEndSelector: nil contextInfo: nil];
[NSApp runModalForWindow: fPicturePanel];
[NSApp endSheet: fPicturePanel];
[fPicturePanel orderOut: self];
@@ -216,19 +232,78 @@
return;
}
+ if( [fCustomBitrateField intValue] < 256 )
+ {
+ NSBeginCriticalAlertSheet( @"Invalid video bitrate", @"Ooops",
+ nil, nil, fWindow, self, nil, nil, nil,
+ @"Video bitrate is too low !" );
+ return;
+ }
+ if( [fCustomBitrateField intValue] > 8192 )
+ {
+ NSBeginCriticalAlertSheet( @"Invalid video bitrate", @"Ooops",
+ nil, nil, fWindow, self, nil, nil, nil,
+ @"Video bitrate is too high !" );
+ return;
+ }
+ if( [fLanguagePopUp indexOfSelectedItem] ==
+ [fSecondaryLanguagePopUp indexOfSelectedItem] )
+ {
+ NSBeginCriticalAlertSheet( @"Invalid secondary language",
+ @"Ooops", nil, nil, fWindow, self, nil, nil, nil,
+ @"Do you _really_ want to encode the same audio track twice?" );
+ return;
+ }
+
+ FILE * file;
+ if( ( file = fopen( [[fFileField stringValue] cString], "r" ) ) )
+ {
+ fclose( file );
+ NSBeginCriticalAlertSheet( @"File already exists",
+ @"Nooo", @"Yes, go ahead!", nil, fWindow, self,
+ @selector( OverwriteAlertDone:returnCode:contextInfo: ),
+ nil, nil,
+ [NSString stringWithFormat: @"Do you want to overwrite %s ?",
+ [[fFileField stringValue] cString]] );
+ return;
+ }
+
+ [self _Rip];
+}
+
+- (void) OverwriteAlertDone: (NSWindow *) sheet
+ returnCode: (int) returnCode contextInfo: (void *) contextInfo
+{
+ if( returnCode == NSAlertAlternateReturn )
+ {
+ [self _Rip];
+ }
+}
+
+- (void) _Rip
+{
/* Get the specified title & audio track(s) */
HBTitle * title = (HBTitle*)
fTitleList->ItemAt( [fTitlePopUp indexOfSelectedItem] );
- HBAudio * audio = (HBAudio*)
- title->fAudioList->ItemAt( [fAudioPopUp indexOfSelectedItem] );
+ HBAudio * audio1 = (HBAudio*)
+ title->fAudioList->ItemAt( [fLanguagePopUp indexOfSelectedItem] );
+ HBAudio * audio2 = (HBAudio*)
+ title->fAudioList->ItemAt( [fSecondaryLanguagePopUp
+ indexOfSelectedItem] );
/* Use user settings */
- title->fBitrate = [fVideoStepper intValue];
- audio->fOutBitrate = [fAudioStepper intValue];
- title->fTwoPass = ( [fTwoPassCheck state] == NSOnState );
+ title->fBitrate = [fCustomBitrateField intValue];
+ title->fTwoPass = ( [fTwoPassCheck state] == NSOnState );
+ audio1->fOutBitrate = [[fAudioBitratePopUp titleOfSelectedItem]
+ intValue];
+ if( audio2 )
+ {
+ audio2->fOutBitrate =
+ [[fAudioBitratePopUp titleOfSelectedItem] intValue];
+ }
/* Let libhb do the job */
- fManager->StartRip( title, audio, NULL,
+ fManager->StartRip( title, audio1, audio2,
(char*) [[fFileField stringValue] cString] );
}
@@ -303,6 +378,20 @@
- (void) UpdateIntf: (NSTimer *) timer
{
+ if( fDie )
+ {
+ [timer invalidate];
+ 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() )
{
@@ -343,7 +432,7 @@
case HB_MODE_INVALID_VOLUME:
{
[fScanMatrix setEnabled: YES];
- [self ScanEnableIntf: self];
+ [self ScanMatrixChanged: self];
[fScanProgress stopAnimation: self];
[fScanButton setEnabled: YES];
@@ -358,7 +447,7 @@
/* Show a temporary empty view while the window
resizing animation */
- [fWindow setContentView: fBlankView ];
+ [fWindow setContentView: fTempView ];
/* Actually resize it */
NSRect newFrame;
@@ -376,6 +465,7 @@
[fWindow setContentView: fRipView ];
[fSuspendButton setEnabled: NO];
+ [fTitlePopUp removeAllItems];
HBTitle * title;
for( uint32_t i = 0; i < fTitleList->CountItems(); i++ )
{
@@ -387,29 +477,31 @@
title->fLength % 60 );
[[fTitlePopUp menu] addItemWithTitle:
[NSString stringWithCString: string]
- action: @selector( UpdatePopUp: )
- keyEquivalent: @""];
+ action: nil keyEquivalent: @""];
}
- [self UpdatePopUp: self];
+ [self TitlePopUpChanged: self];
break;
}
case HB_MODE_ENCODING:
{
- [fTitlePopUp setEnabled: NO];
- [fAudioPopUp setEnabled: NO];
- [fVideoField setEnabled: NO];
- [fVideoStepper setEnabled: NO];
- [fAudioField setEnabled: NO];
- [fAudioStepper setEnabled: NO];
- [fTwoPassCheck setEnabled: NO];
- [fCropButton setEnabled: NO];
- [fFileField setEnabled: NO];
- [fRipBrowseButton setEnabled: NO];
- [fRipButton setTitle: @"Cancel"];
- [fSuspendButton setEnabled: YES];
- [fSuspendButton setTitle: @"Suspend"];
+ [fTitlePopUp setEnabled: NO];
+ [fVideoCodecPopUp setEnabled: NO];
+ [fVideoMatrix setEnabled: NO];
+ [fCustomBitrateField setEnabled: NO];
+ [fTargetSizeField setEnabled: NO];
+ [fTwoPassCheck setEnabled: NO];
+ [fCropButton setEnabled: NO];
+ [fLanguagePopUp setEnabled: NO];
+ [fSecondaryLanguagePopUp setEnabled: NO];
+ [fAudioCodecPopUp setEnabled: NO];
+ [fAudioBitratePopUp setEnabled: NO];
+ [fFileFormatPopUp setEnabled: NO];
+ [fFileBrowseButton setEnabled: NO];
+ [fSuspendButton setEnabled: YES];
+ [fSuspendButton setTitle: @"Suspend"];
+ [fRipButton setTitle: @"Cancel"];
if( !status.fPosition )
{
@@ -419,15 +511,22 @@
}
else
{
- char string[1024]; memset( string, 0, 1024 );
- sprintf( string, "Encoding: %.2f %%, %.2f fps "
- "(%02d:%02d:%02d remaining)",
- 100 * status.fPosition, status.fFrameRate,
+ 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 );
- [fRipStatusField setStringValue:
+ [fRipInfoField setStringValue:
[NSString stringWithCString: string]];
+
[fRipProgress setIndeterminate: NO];
[fRipProgress setDoubleValue: 100 * status.fPosition];
}
@@ -438,10 +537,11 @@
case HB_MODE_SUSPENDED:
{
char string[1024]; memset( string, 0, 1024 );
- sprintf( string, "Encoding: %.2f %%, %.2f fps (PAUSED)",
- 100 * status.fPosition, status.fFrameRate) ;
+ sprintf( string, "Encoding: %.2f %% (PAUSED)",
+ 100 * status.fPosition ) ;
[fRipStatusField setStringValue:
[NSString stringWithCString: string]];
+ [fRipInfoField setStringValue: @""];
[fRipProgress setDoubleValue: 100 * status.fPosition];
@@ -449,50 +549,91 @@
break;
}
+ case HB_MODE_STOPPING:
+ [fRipStatusField setStringValue: @"Stopping..."];
+ [fRipInfoField setStringValue: @""];
+ [fRipProgress setIndeterminate: YES];
+ [fRipProgress startAnimation: self];;
+ break;
+
case HB_MODE_DONE:
case HB_MODE_CANCELED:
case HB_MODE_ERROR:
- [fTitlePopUp setEnabled: YES];
- [fAudioPopUp setEnabled: YES];
- [fVideoField setEnabled: YES];
- [fVideoStepper setEnabled: YES];
- [fAudioField setEnabled: YES];
- [fAudioStepper setEnabled: YES];
- [fTwoPassCheck setEnabled: YES];
- [fCropButton setEnabled: YES];
- [fFileField setEnabled: YES];
- [fRipBrowseButton setEnabled: YES];
- [fRipButton setEnabled: YES];
- [fRipButton setTitle: @"Rip"];
- [fSuspendButton setEnabled: NO];
- [fSuspendButton setTitle: @"Suspend"];
+ [fRipProgress setIndeterminate: NO];
if( status.fMode == HB_MODE_DONE )
{
- [fRipStatusField setStringValue: @"Done." ];
[fRipProgress setDoubleValue: 100];
+ [fRipStatusField setStringValue: @"Done." ];
NSBeep();
[NSApp requestUserAttention: NSInformationalRequest];
[NSApp beginSheet: fDonePanel
- modalForWindow: fWindow
- modalDelegate: nil
- didEndSelector: nil
- contextInfo: nil];
+ modalForWindow: fWindow modalDelegate: nil
+ didEndSelector: nil contextInfo: nil];
[NSApp runModalForWindow: fDonePanel];
[NSApp endSheet: fDonePanel];
[fDonePanel orderOut: self];
}
else if( status.fMode == HB_MODE_CANCELED )
{
- [fRipStatusField setStringValue: @"Canceled." ];
[fRipProgress setDoubleValue: 0];
+ [fRipStatusField setStringValue: @"Canceled." ];
}
else
{
- [fRipStatusField setStringValue: @"An error occured." ];
[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;
+ }
}
+ [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"];
+
+ [self VideoMatrixChanged: self];
+
/* Warn the finder to update itself */
[[NSWorkspace sharedWorkspace] noteFileSystemChanged:
[fFileField stringValue]];
@@ -502,18 +643,10 @@
break;
}
}
-
- /* Do it again 1/10 second later */
- [NSTimer scheduledTimerWithTimeInterval: 0.1
- target: self selector: @selector( UpdateIntf: )
- userInfo: nil repeats: FALSE];
}
- (void) DetectDrives
{
- /* Empty the current popup */
- [fDVDPopUp removeAllItems];
-
/* Scan DVD drives (stolen from VLC) */
io_object_t next_media;
mach_port_t master_port;
@@ -544,6 +677,9 @@
return;
}
+ NSMutableArray * drivesList;
+ drivesList = [NSMutableArray arrayWithCapacity: 1];
+
next_media = IOIteratorNext( media_iterator );
if( next_media != NULL )
{
@@ -571,9 +707,8 @@
sizeof(psz_buf) - dev_path_length,
kCFStringEncodingASCII ) )
{
- [[fDVDPopUp menu] addItemWithTitle:
- [NSString stringWithCString: psz_buf]
- action: nil keyEquivalent: @""];
+ [drivesList addObject:
+ [NSString stringWithCString: psz_buf]];
}
CFRelease( str_bsd_path );
@@ -584,9 +719,37 @@
}
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++ )
+ {
+ [[fDVDPopUp menu] addItemWithTitle:
+ [drivesList objectAtIndex: i] action: nil
+ keyEquivalent: @""];
+ }
+ [self ScanMatrixChanged: self];
}
-- (void) ScanEnableIntf: (id) sender
+- (IBAction) ScanMatrixChanged: (id) sender
{
if( ![fScanMatrix selectedRow] )
{
@@ -604,12 +767,13 @@
}
}
-- (void) UpdatePopUp: (id) sender
+- (IBAction) TitlePopUpChanged: (id) sender
{
HBTitle * title = (HBTitle*)
fTitleList->ItemAt( [fTitlePopUp indexOfSelectedItem] );
- [fAudioPopUp removeAllItems];
+ [fLanguagePopUp removeAllItems];
+ [fSecondaryLanguagePopUp removeAllItems];
HBAudio * audio;
for( uint32_t i = 0; i < title->fAudioList->CountItems(); i++ )
@@ -618,9 +782,30 @@
/* We cannot use NSPopUpButton's addItemWithTitle because
it checks for duplicate entries */
- [[fAudioPopUp menu] addItemWithTitle:
+ [[fLanguagePopUp menu] addItemWithTitle:
[NSString stringWithCString: audio->fDescription]
action: nil keyEquivalent: @""];
+ [[fSecondaryLanguagePopUp menu] addItemWithTitle:
+ [NSString stringWithCString: audio->fDescription]
+ action: nil keyEquivalent: @""];
+ }
+ [fSecondaryLanguagePopUp addItemWithTitle: @"None"];
+ [fSecondaryLanguagePopUp selectItemWithTitle: @"None"];
+ [fSecondaryLanguagePopUp setEnabled:
+ ( title->fAudioList->CountItems() > 1 )];
+
+ [fTargetSizeField SetHBTitle: title];
+ if( [fVideoMatrix selectedRow] )
+ {
+ [fTargetSizeField UpdateBitrate];
+ }
+}
+
+- (IBAction) AudioPopUpChanged: (id) sender
+{
+ if( [fVideoMatrix selectedRow] )
+ {
+ [fTargetSizeField UpdateBitrate];
}
}
diff --git a/macosx/English.lproj/InfoPlist.strings b/macosx/English.lproj/InfoPlist.strings
index ae4f04858..5ed7ca9e2 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 df2438f40..38429950c 100644
--- a/macosx/English.lproj/MainMenu.nib/classes.nib
+++ b/macosx/English.lproj/MainMenu.nib/classes.nib
@@ -3,6 +3,7 @@
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
{
ACTIONS = {
+ AudioPopUpChanged = id;
BrowseDVD = id;
BrowseFile = id;
Cancel = id;
@@ -12,36 +13,39 @@
Resume = id;
Rip = id;
Scan = id;
- ScanEnableIntf = id;
+ ScanMatrixChanged = id;
ShowPicturePanel = id;
Suspend = id;
+ TitlePopUpChanged = id;
UpdatePicture = id;
- UpdatePopUp = id;
+ VideoMatrixChanged = id;
};
CLASS = HBController;
LANGUAGE = ObjC;
OUTLETS = {
- fAudioField = NSTextField;
- fAudioPopUp = NSPopUpButton;
- fAudioStepper = NSStepper;
- fBlankView = NSView;
+ fAudioBitratePopUp = NSPopUpButton;
+ fAudioCodecPopUp = NSPopUpButton;
fBottomField = NSTextField;
fBottomStepper = NSStepper;
fCropButton = NSButton;
+ fCustomBitrateField = NSTextField;
fDVDFolderField = NSTextField;
fDVDPopUp = NSPopUpButton;
fDeinterlaceCheck = NSButton;
fDonePanel = NSPanel;
+ fFileBrowseButton = NSButton;
fFileField = NSTextField;
+ fFileFormatPopUp = NSPopUpButton;
fInfoField = NSTextField;
+ fLanguagePopUp = NSPopUpButton;
fLeftField = NSTextField;
fLeftStepper = NSStepper;
- fPictureGLView = PictureGLView;
+ fPictureGLView = HBPictureGLView;
fPicturePanel = NSPanel;
fRightField = NSTextField;
fRightStepper = NSStepper;
- fRipBrowseButton = NSButton;
fRipButton = NSButton;
+ fRipInfoField = NSTextField;
fRipProgress = NSProgressIndicator;
fRipStatusField = NSTextField;
fRipView = NSView;
@@ -51,19 +55,33 @@
fScanProgress = NSProgressIndicator;
fScanStatusField = NSTextField;
fScanView = NSView;
+ fSecondaryLanguagePopUp = NSPopUpButton;
fSuspendButton = NSButton;
+ fTargetSizeField = HBTargetSizeField;
+ fTempView = NSView;
fTitlePopUp = NSPopUpButton;
fTopField = NSTextField;
fTopStepper = NSStepper;
fTwoPassCheck = NSButton;
- fVideoField = NSTextField;
- fVideoStepper = NSStepper;
+ fVideoCodecPopUp = NSPopUpButton;
+ fVideoMatrix = NSMatrix;
fWidthField = NSTextField;
fWidthStepper = NSStepper;
fWindow = NSWindow;
};
SUPERCLASS = NSObject;
},
+ {CLASS = HBPictureGLView; LANGUAGE = ObjC; SUPERCLASS = NSOpenGLView; },
+ {
+ CLASS = HBTargetSizeField;
+ LANGUAGE = ObjC;
+ OUTLETS = {
+ fAudioBitratePopUp = NSPopUpButton;
+ fBitrateField = NSTextField;
+ fSecondaryLanguagePopUp = NSPopUpButton;
+ };
+ SUPERCLASS = NSTextField;
+ },
{CLASS = PictureGLView; LANGUAGE = ObjC; SUPERCLASS = NSOpenGLView; }
);
IBVersion = 1;
diff --git a/macosx/English.lproj/MainMenu.nib/info.nib b/macosx/English.lproj/MainMenu.nib/info.nib
index 0dbd97023..af41a1429 100644
--- a/macosx/English.lproj/MainMenu.nib/info.nib
+++ b/macosx/English.lproj/MainMenu.nib/info.nib
@@ -3,25 +3,29 @@
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
- <string>109 136 381 380 0 0 1440 878 </string>
+ <string>29 16 381 380 0 0 1440 878 </string>
<key>IBEditorPositions</key>
<dict>
- <key>249</key>
- <string>510 472 420 258 0 0 1440 878 </string>
- <key>256</key>
- <string>454 372 420 466 0 0 1440 878 </string>
<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>
+ <key>583</key>
+ <string>648 516 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>
<key>IBOpenObjects</key>
<array>
- <integer>249</integer>
- <integer>256</integer>
+ <integer>583</integer>
<integer>21</integer>
+ <integer>589</integer>
+ <integer>365</integer>
<integer>434</integer>
<integer>29</integer>
+ <integer>556</integer>
</array>
<key>IBSystem Version</key>
<string>6R73</string>
diff --git a/macosx/English.lproj/MainMenu.nib/objects.nib b/macosx/English.lproj/MainMenu.nib/objects.nib
index a7849eb54..9fe323510 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 b4ea5fef5..5f4045553 100644
--- a/macosx/HandBrake.pbproj/project.pbxproj
+++ b/macosx/HandBrake.pbproj/project.pbxproj
@@ -17,6 +17,8 @@
4DF3C8CC052889CD00A80101,
4D85758E052B78E300C39CA9,
4D85758F052B78E300C39CA9,
+ 4D358C000534A91300D654EB,
+ 4D358C010534A91300D654EB,
);
isa = PBXGroup;
name = Classes;
@@ -156,6 +158,7 @@
29B97315FDCFA39411CA2CEA = {
children = (
29B97316FDCFA39411CA2CEA,
+ 4D358C040534AB8100D654EB,
4D929FEB0527903D00A80101,
);
isa = PBXGroup;
@@ -260,7 +263,7 @@
<key>CFBundleExecutable</key>
<string>HandBrake</string>
<key>CFBundleGetInfoString</key>
- <string>HandBrake 0.3 - By Eric Petit &lt;[email protected]&gt;</string>
+ <string>HandBrake 0.4 - By Eric Petit &lt;[email protected]&gt;</string>
<key>CFBundleIconFile</key>
<string>HandBrake.icns</string>
<key>CFBundleIdentifier</key>
@@ -272,11 +275,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
- <string>0.3</string>
+ <string>0.4</string>
<key>CFBundleSignature</key>
<string>HB##</string>
<key>CFBundleVersion</key>
- <string>0.3</string>
+ <string>0.4</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
@@ -291,6 +294,8 @@
4D929FEC0527903D00A80101,
4D6615EA05288C2300A80101,
4D857591052B78E300C39CA9,
+ 4D358C020534A91300D654EB,
+ 4D358C050534AB8100D654EB,
);
isa = PBXHeadersBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
@@ -311,6 +316,7 @@
29B9732CFDCFA39411CA2CEA,
4DF3C8CE052889CD00A80101,
4D857590052B78E300C39CA9,
+ 4D358C030534A91300D654EB,
);
isa = PBXSourcesBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
@@ -391,6 +397,43 @@
settings = {
};
};
+ 4D358C000534A91300D654EB = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ path = TargetSizeField.h;
+ refType = 4;
+ };
+ 4D358C010534A91300D654EB = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ path = TargetSizeField.mm;
+ refType = 4;
+ };
+ 4D358C020534A91300D654EB = {
+ fileRef = 4D358C000534A91300D654EB;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ 4D358C030534A91300D654EB = {
+ fileRef = 4D358C010534A91300D654EB;
+ isa = PBXBuildFile;
+ 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;
@@ -557,13 +600,13 @@
4DF3C8CB052889CD00A80101 = {
fileEncoding = 30;
isa = PBXFileReference;
- path = HBController.h;
+ path = Controller.h;
refType = 4;
};
4DF3C8CC052889CD00A80101 = {
fileEncoding = 30;
isa = PBXFileReference;
- path = HBController.mm;
+ path = Controller.mm;
refType = 4;
};
4DF3C8CE052889CD00A80101 = {
diff --git a/macosx/PictureGLView.h b/macosx/PictureGLView.h
index effbf3ee2..06e5a16e1 100644
--- a/macosx/PictureGLView.h
+++ b/macosx/PictureGLView.h
@@ -4,7 +4,7 @@
#include "Manager.h"
-@interface PictureGLView : NSOpenGLView
+@interface HBPictureGLView : NSOpenGLView
{
HBManager * fManager;
diff --git a/macosx/PictureGLView.mm b/macosx/PictureGLView.mm
index 72e564141..79103f6b6 100644
--- a/macosx/PictureGLView.mm
+++ b/macosx/PictureGLView.mm
@@ -2,7 +2,7 @@
#include "PictureGLView.h"
-@implementation PictureGLView
+@implementation HBPictureGLView
- (void) SetManager: (HBManager*) manager
{
diff --git a/macosx/TargetSizeField.h b/macosx/TargetSizeField.h
new file mode 100644
index 000000000..12224cae7
--- /dev/null
+++ b/macosx/TargetSizeField.h
@@ -0,0 +1,23 @@
+/* $Id: TargetSizeField.h,v 1.2 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 <Cocoa/Cocoa.h>
+
+#include "Common.h"
+
+@interface HBTargetSizeField : NSTextField
+
+{
+ HBTitle * fTitle;
+ IBOutlet NSTextField * fBitrateField;
+ IBOutlet NSPopUpButton * fSecondaryLanguagePopUp;
+ IBOutlet NSPopUpButton * fAudioBitratePopUp;
+}
+
+- (void) SetHBTitle: (HBTitle *) title;
+- (void) UpdateBitrate;
+
+@end
diff --git a/macosx/TargetSizeField.mm b/macosx/TargetSizeField.mm
new file mode 100644
index 000000000..0c43701fb
--- /dev/null
+++ b/macosx/TargetSizeField.mm
@@ -0,0 +1,64 @@
+/* $Id: TargetSizeField.mm,v 1.4 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 "TargetSizeField.h"
+
+@implementation HBTargetSizeField
+
+- (void) textDidBeginEditing: (NSNotification *) notification
+{
+ [self UpdateBitrate];
+ [super textDidBeginEditing: notification];
+}
+
+- (void) textDidEndEditing: (NSNotification *) notification
+{
+ [self UpdateBitrate];
+ [super textDidEndEditing: notification];
+}
+
+- (void) textDidChange: (NSNotification *) notification
+{
+ [self UpdateBitrate];
+ [super textDidChange: notification];
+}
+
+- (void) SetHBTitle: (HBTitle*) title
+{
+ fTitle = title;
+}
+
+- (void) UpdateBitrate
+{
+ int64_t available;
+ available = (int64_t) [self intValue] * 1024 * 1024;
+
+ /* AVI headers */
+ available -= 2048;
+
+ /* Video chunk headers (8 bytes / frame)
+ and index (16 bytes / frame) */
+ available -= 24 * fTitle->fLength * fTitle->fRate / fTitle->fScale;
+
+ /* Audio tracks */
+ available -= ( ( [[fSecondaryLanguagePopUp titleOfSelectedItem]
+ compare: @"None"] == NSOrderedSame ) ? 1 : 2 ) *
+ ( fTitle->fLength *
+ [[fAudioBitratePopUp titleOfSelectedItem] intValue] *
+ 128 + 24 * fTitle->fLength * 44100 / 1152 );
+
+ if( available < 0 )
+ {
+ [fBitrateField setIntValue: 0];
+ }
+ else
+ {
+ [fBitrateField setIntValue:
+ available / ( 128 * fTitle->fLength )];
+ }
+}
+
+@end
diff --git a/test/Test.cpp b/test/Test.cpp
index d0d5ec9ea..4567f74b6 100644
--- a/test/Test.cpp
+++ b/test/Test.cpp
@@ -1,4 +1,4 @@
-/* $Id: Test.cpp,v 1.5 2003/10/05 14:28:40 titer Exp $
+/* $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/>.
@@ -27,6 +27,8 @@ int main( int argc, char ** argv )
char * device = NULL;
char * outputFile = NULL;
int titleIdx = 1;
+ int audio1Idx = 1;
+ int audio2Idx = 0;
bool twoPass = false;
bool deinterlace = false;
int width = 0;
@@ -34,10 +36,13 @@ int main( int argc, char ** argv )
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:piw:j:k:l:m:" ) ) != -1 )
+ while( ( c = getopt( argc, argv, "vd:o:t:a:b:piw:j:k:l:m:c:e:f:" ) ) != -1 )
{
switch( c )
{
@@ -57,6 +62,14 @@ int main( int argc, char ** argv )
titleIdx = atoi( optarg );
break;
+ case 'a':
+ audio1Idx = atoi( optarg );
+ break;
+
+ case 'b':
+ audio2Idx = atoi( optarg );
+ break;
+
case 'p':
twoPass = true;
break;
@@ -85,6 +98,18 @@ int main( int argc, char ** argv )
rightCrop = atoi( optarg );
break;
+ case 'c':
+ cpuCount = atoi( optarg );
+ break;
+
+ case 'e':
+ vBitrate = atoi( optarg );
+ break;
+
+ case 'f':
+ aBitrate = atoi( optarg );
+ break;
+
default:
break;
}
@@ -96,20 +121,25 @@ int main( int argc, char ** argv )
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"
- " -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" );
+ " -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 );
+ HBManager * manager = new HBManager( debug, cpuCount );
/* Tell the manager to scan the specified volume */
manager->ScanVolumes( device );
@@ -183,10 +213,16 @@ int main( int argc, char ** argv )
title->fBottomCrop = bottomCrop;
title->fLeftCrop = leftCrop;
title->fRightCrop = rightCrop;
+ title->fBitrate = vBitrate;
- HBAudio * audio = (HBAudio*) title->fAudioList->ItemAt( 0 );
+ 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, audio, NULL, outputFile );
+ manager->StartRip( title, audio1, audio2, outputFile );
break;
}