OSDN Git Service

Corrected small EOL marker issue.
[handbrake-jp/handbrake-jp-git.git] / wx / wxHB.cpp
1 /*****************************************************************************
2  * wxHB:
3  *****************************************************************************
4  * Copyright (C)
5  * $Id: wxHB.cpp,v 1.8 2005/03/26 23:04:17 titer Exp $
6  *
7  * Authors:
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 #include "wxHB.h"
25 #include "hbWizard.h"
26
27 #ifdef SYS_CYGWIN
28 #   include <windows.h>
29 #endif
30
31 /****************************************************************************
32  * Definitions / Variables
33  ****************************************************************************/
34 class hbApp *g_hbApp = NULL;
35
36 IMPLEMENT_APP( hbApp )
37
38 /****************************************************************************
39  * Helpers class
40  ****************************************************************************/
41 class hbAppTimer: public wxTimer
42 {
43 public:
44     hbAppTimer()
45     {
46         Start( 50, wxTIMER_CONTINUOUS );
47     }
48     virtual void Notify()
49     {
50         g_hbApp->Update();
51     }
52 };
53
54 class hbAppProgress: public wxDialog
55 {
56 public:
57     hbAppProgress( wxWindow *parent, wxString title, wxString msg ) :
58         wxDialog( parent, -1, title, wxDefaultPosition, wxSize( 250, 300),
59                   wxDEFAULT_DIALOG_STYLE )
60     {
61         /* Create widgets */
62         txt = new wxStaticText( this, -1, msg );
63         gauge = new wxGauge( this, -1, 100 );
64         button = new wxButton( this, wxID_CANCEL, wxU("Cancel") );
65
66         /* Add evrything in a sizer */
67         wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
68         sizer->Add( txt, 1, wxEXPAND|wxALIGN_CENTER|wxALL, 5 );
69
70         wxBoxSizer *sizerH = new wxBoxSizer( wxHORIZONTAL );
71         sizerH->Add( gauge, 1, wxALIGN_CENTER|wxALL, 5 );
72         sizer->Add( sizerH, 0, wxALIGN_CENTER|wxALL, 5 );
73
74         sizer->Add( button, 0, wxALIGN_CENTER_HORIZONTAL|
75                                wxALIGN_BOTTOM|wxALL, 5 );
76         //SetSizerAndFit( sizer );
77         SetSizer( sizer );
78     }
79
80     void SetProgress( int i_percent, wxString msg )
81     {
82         gauge->SetValue( i_percent );
83         txt->SetLabel( msg );
84     }
85
86     void OnClose( wxCloseEvent &event )
87     {
88         EndModal( wxID_CANCEL );
89     }
90
91 private:
92     wxStaticText *txt;
93     wxGauge      *gauge;
94     wxButton     *button;
95
96     DECLARE_EVENT_TABLE()
97 };
98
99 BEGIN_EVENT_TABLE( hbAppProgress, wxDialog )
100     EVT_CLOSE( hbAppProgress::OnClose )
101 END_EVENT_TABLE()
102
103 /****************************************************************************
104  * hbApp class
105  ****************************************************************************/
106
107 /* OnInit: Call at the very start and put every in place
108  */
109 bool hbApp::OnInit()
110 {
111     /* Export hbApp */
112     g_hbApp = this;
113
114
115     /* Init all variables */
116     isEnd = false;
117
118     progress = NULL;
119
120     i_title = -1;
121     titles  = NULL;
122     title = NULL;
123
124     audios = NULL;
125     subs = NULL;
126
127     systemDrive = NULL;
128
129     /* Start HB */
130     if( Init() )
131         return false;
132
133     /* Start out timer */
134     timer = new hbAppTimer();
135
136     /* Create and Start the wizard */
137     wizard = new hbWizard( NULL );
138     wizard->Run();
139
140     /* Special hack FIXME */
141     isEnd = true;
142
143     return true;
144 }
145
146 /* OnExit:
147  */
148 int hbApp::OnExit()
149 {
150     delete timer;
151     delete wizard;
152
153     /* End hb */
154     End();
155
156     /* Delete others FIXME */
157
158     return 0;
159 }
160
161 /* Init:
162  */
163 int hbApp::Init()
164 {
165     /* Create a hb instance */
166     hbHandle = hb_init( HB_DEBUG_NONE, 1 );
167     if( hbHandle == NULL )
168         return -1;
169
170     return 0;
171 }
172 /* Scan:
173  */
174 int hbApp::Scan( wxString sDevice )
175 {
176     if( sDevice.IsEmpty() )
177         return -1;
178
179     /* Reset state */
180     i_title = -1;
181     if( titles ) delete titles; titles  = NULL;
182     if( audios ) delete audios; audios = NULL;
183     if( subs ) delete subs; subs = NULL;
184     title = NULL;
185
186     /* Append a \ if needed */
187     if( sDevice.Length() == 2 && sDevice.Last() == ':' )
188         sDevice.Append( '\\' );
189
190     /* Launch the scan (all titles) */
191     hb_scan( hbHandle, sDevice.ToAscii(), 0 );
192
193     /* Create a progress report */
194     progress = new hbAppProgress( wizard, wxU("Scanning..."), wxU("Opening ")+sDevice);
195     progress->ShowModal();
196
197     if( !hb_list_count( hb_get_titles( hbHandle ) ) )
198     {
199         hbError( wizard, wxU("Scanning failed") );
200         return -1;
201     }
202
203     /* FIXME test if the scan is complete */
204
205
206     return 0;
207 }
208 /* Encode:
209  */
210 int hbApp::Encode()
211 {
212     hb_state_t s;
213
214     /* Maybe check a few things like:
215      *  - compatible muxer and codecs */
216
217     /* Start the encoding */
218     hb_add( hbHandle, title->job );
219     hb_start( hbHandle );
220
221     /* FIXME use the wizard instead */
222     /* Create a progress report */
223     progress = new hbAppProgress( wizard, wxU("Encoding..."), wxU("0%"));
224     progress->ShowModal();
225
226     hb_get_state( hbHandle, &s );
227     if( s.param.workdone.error != HB_ERROR_NONE )
228     {
229         hb_stop( hbHandle );    /* FIXME to a proper handling */
230         hbError( wizard, wxU("Encoding failed/stopped") );
231         return -1;
232     }
233
234     /* bad */
235     return 0;
236 }
237
238 /* End:
239  */
240 void hbApp::End()
241 {
242     hb_close( &hbHandle );
243 }
244
245
246 wxArrayString *hbApp::GetTitles()
247 {
248     hb_list_t *list;
249     int i_count;
250     int i;
251
252     if( titles )
253         return titles;
254
255     /* Create the title list */
256     list = hb_get_titles( hbHandle );
257
258     i_count = hb_list_count( list );
259     if( i_count <= 0 )
260         return NULL;
261
262     titles = new wxArrayString();
263     for( i = 0; i < i_count; i++ )
264     {
265         hb_title_t *t = (hb_title_t*)hb_list_item( list, i );
266         wxString name = wxString::Format( wxU("%d  - %d:%02d:%02d"),
267                                           t->index,
268                                           t->hours, t->minutes, t->seconds );
269         titles->Add( name );
270     }
271
272     return titles;
273 }
274
275 void hbApp::SetTitle( int _i_title )
276 {
277     int i;
278
279     if( i_title == _i_title )
280         return;
281
282     i_title = _i_title;
283     title = (hb_title_t*)hb_list_item( hb_get_titles( hbHandle ), i_title );
284     if( audios ) delete audios; audios = NULL;
285     if( subs ) delete subs; subs = NULL;
286
287     for( i = 0; i < 8; i++ )
288         title->job->audios[i] = -1;
289     title->job->subtitle = -1;
290 }
291
292 int hbApp::GetDefaultTitle()
293 {
294     hb_list_t *list;
295     int i_best = -1;
296     int i_best_length = 0;
297     int i;
298
299     list = hb_get_titles( hbHandle );
300     for( i = 0; i < hb_list_count( list ); i++ )
301     {
302         hb_title_t *t = (hb_title_t*)hb_list_item( list, i );
303         int i_length = t->hours * 3600 + t->minutes*60 + t->seconds;
304
305         if( i_best < 0 || i_length > i_best_length )
306         {
307             i_best = i;
308             i_best_length = i_length;
309         }
310     }
311
312     return i_best;
313 }
314
315
316
317 int hbApp::GetChaptersCount()
318 {
319     if( i_title < 0 )
320         return 0;
321
322     return hb_list_count( title->list_chapter );
323 }
324
325 void hbApp::SetChapterStart( int i_chapter )
326 {
327     title->job->chapter_start = i_chapter;
328 }
329
330 void hbApp::SetChapterEnd( int i_chapter )
331 {
332     title->job->chapter_end = i_chapter;
333 }
334
335 wxArrayString *hbApp::GetTracksAudio()
336 {
337     int i;
338     if( audios )
339         return audios;
340
341     audios = new wxArrayString();
342     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
343     {
344         hb_audio_t *a = (hb_audio_t*)hb_list_item( title->list_audio, i );
345
346         audios->Add( wxU(a->lang) );
347     }
348     audios->Add( wxU("None") );
349
350     return audios;
351 }
352 void hbApp::SetTrackAudio( int i_track, int i_pos )
353 {
354     if( i_pos >= 0 && i_pos < hb_list_count( title->list_audio ) )
355         title->job->audios[i_pos] = i_track;
356     else
357         title->job->audios[i_pos] = -1;
358 }
359
360 wxArrayString *hbApp::GetTracksSubtitle()
361 {
362     int i;
363
364     if( subs )
365         return subs;
366
367     subs = new wxArrayString();
368     for( i = 0; i < hb_list_count( title->list_subtitle ); i++ )
369     {
370         hb_subtitle_t *s =
371             (hb_subtitle_t*)hb_list_item( title->list_subtitle, i );
372
373         subs->Add( wxU(s->lang) );
374     }
375     subs->Add( wxU("None") );
376
377     return subs;
378 }
379
380 void hbApp::SetTrackSubtitle( int i_track )
381 {
382     if( i_track >= 0 && i_track < hb_list_count( title->list_subtitle ) )
383         title->job->subtitle = i_track;
384     else
385         title->job->subtitle = -1;
386 }
387
388 void hbApp::SetOutputFile( wxString sFile )
389 {
390     char *psz;
391
392     title->job->file = strdup( sFile.ToAscii() ); /* FIXME do we need strdup ? */
393
394     psz = strrchr( title->job->file, '.' );
395     if( psz == NULL )
396         title->job->mux = HB_MUX_AVI; /* By default, FIXME */
397     else if( !strcasecmp( psz, ".avi" ) )
398         title->job->mux = HB_MUX_AVI;
399     else if( !strcasecmp( psz, ".mp4" ) || !strcasecmp( psz, ".mov") )
400         title->job->mux = HB_MUX_MP4;
401     else if( !strcasecmp( psz, ".ogg" ) || !strcasecmp( psz, ".ogm") )
402         title->job->mux = HB_MUX_OGM;
403     else
404         title->job->mux = HB_MUX_AVI; /* By default */
405
406     /* Fix acodec value */
407     switch( title->job->mux )
408     {
409         case HB_MUX_AVI:
410             title->job->acodec = HB_ACODEC_LAME;
411             break;
412         case HB_MUX_MP4:
413             title->job->acodec = HB_ACODEC_FAAC;
414             break;
415         case HB_MUX_OGM:
416             title->job->acodec = HB_ACODEC_VORBIS;
417             break;
418     }
419 }
420
421 void hbApp::SetAudioBitrate( int i_bitrate )
422 {
423     int i_old = title->job->abitrate;
424
425     title->job->abitrate = i_bitrate;
426
427     if( title->job->vbitrate > 0 )
428         title->job->vbitrate = title->job->vbitrate + (i_old - i_bitrate);
429 }
430
431 void hbApp::SetTotalBitrate( int i_bitrate )
432 {
433     title->job->vbitrate = i_bitrate - title->job->abitrate;
434
435     if( title->job->vbitrate <= 0 )
436         title->job->vbitrate = 1;
437 }
438
439 void hbApp::SetTotalSize( int i_size )
440 {
441     /* XXX */
442 }
443
444 void hbApp::SetVideoPass( int i_pass )
445 {
446     /* FIXME is 0 or 1 valid for 1 pass ? */
447     if( i_pass <= 1 )
448         title->job->pass = 0;
449     else if( i_pass == 2 )
450         title->job->pass = 2;
451 }
452
453 void hbApp::SetVideoCodec( wxString sCodec )
454 {
455     if( sCodec.Lower() == wxU("ffmpeg") )
456         title->job->vcodec = HB_VCODEC_FFMPEG;
457     else if( sCodec.Lower() == wxU("xvid") )
458         title->job->vcodec = HB_VCODEC_XVID;
459     else if( sCodec.Lower() == wxU("x264") )
460         title->job->vcodec = HB_VCODEC_XVID;
461 }
462
463 void hbApp::SetVideoDeinterlace( bool b_deinterlace )
464 {
465     title->job->deinterlace = b_deinterlace ? 1 : 0;
466 }
467
468 void hbApp::SetPriority( int i_priority )
469 {
470     /* Doesn't work :(( */
471 #ifdef SYS_CYGWIN
472     switch( i_priority )
473     {
474         case HB_PRIORITY_ABOVE_NORMAL:
475             i_priority = THREAD_PRIORITY_ABOVE_NORMAL;
476             break;
477         case HB_PRIORITY_BELOW_NORMAL:
478             i_priority = THREAD_PRIORITY_BELOW_NORMAL;
479             break;
480         case HB_PRIORITY_LOWEST:
481             i_priority = THREAD_PRIORITY_LOWEST;
482             break;
483         case HB_PRIORITY_HIGHEST:
484             i_priority = THREAD_PRIORITY_HIGHEST;
485             break;
486
487         case HB_PRIORITY_NORMAL:
488         default:
489             i_priority = THREAD_PRIORITY_NORMAL;
490             break;
491     }
492     ::SetThreadPriority( GetCurrentThread(), i_priority );
493 #else
494     /* TODO */
495 #endif
496 }
497
498 void hbApp::SetCpuCount( int i_cpu )
499 {
500     hb_set_cpu_count( hbHandle, i_cpu );
501 }
502
503 int hbApp::GetVideoRateBase()
504 {
505     return title->rate_base;
506 }
507
508 void hbApp::SetVideoRateBase( int i_base )
509 {
510     title->job->vrate_base = i_base;
511     title->job->vrate = HB_VIDEO_RATE_BASE;
512 }
513 void hbApp::GetVideoAutocrop( int crop[4] )
514 {
515     int i;
516     for( i = 0; i < 4; i++ )
517         crop[i] = title->crop[i];
518 }
519 void hbApp::SetVideoCrop( int crop[4] )
520 {
521     int i;
522     for( i = 0; i < 4; i++ )
523         title->job->crop[i] = crop ? crop[i] : 0;
524 }
525 void hbApp::GetVideoSize( int *pi_width, int *pi_height )
526 {
527     *pi_width = title->width;
528     *pi_height = title->height;
529 }
530 void hbApp::SetVideoSize( int i_width, int i_height )
531 {
532     title->job->width = i_width;
533     title->job->height = i_height;
534 }
535
536
537 int hbApp::GetAudioSamplerate()
538 {
539     int idx = title->job->audios[0];
540     if( idx >= 0 && idx < hb_list_count( title->list_audio ) )
541     {
542         hb_audio_t *a = (hb_audio_t*)hb_list_item( title->list_audio, 0 );
543         return a->rate;
544     }
545
546     /* FIXME not good */
547     return title->job->arate;
548 }
549
550 void hbApp::SetAudioSamplerate( int i_rate )
551 {
552     title->job->arate = i_rate;
553 }
554
555 wxString hbApp::GetDefaultAudio()
556 {
557     return wxU("English");
558 }
559
560 wxString hbApp::GetDefaultSubtitle()
561 {
562     return wxU("None");
563 }
564
565 int hbApp::GetDefaultCpuCount()
566 {
567     return GetSystemCpuCount();
568 }
569
570 int hbApp::GetDefaultPriority()
571 {
572     return HB_PRIORITY_NORMAL;
573 }
574
575 int hbApp::GetDefaultVideoRateBase()
576 {
577     return 0;
578 }
579
580 int hbApp::GetDefaultAudioSamplerate()
581 {
582     return 0;
583 }
584
585 /* Drive */
586 wxArrayString *hbApp::GetSystemDrive()
587 {
588     if( systemDrive )
589         return systemDrive;
590
591     systemDrive = new wxArrayString();
592 #ifdef SYS_CYGWIN
593     char c;
594     for( c = 'A'; c <= 'Z'; c++ )
595     {
596         char pszDrive[4];
597         pszDrive[0] = c;
598         pszDrive[1] = ':';
599         pszDrive[2] = '\\';
600         pszDrive[3] = '\0';
601
602         if( GetDriveType( pszDrive ) == DRIVE_CDROM )
603             systemDrive->Add( wxString::Format( wxU("%c:"), c ) );
604     }
605 #else
606     /* TODO true detection */
607     systemDrive->Add( wxU("/dev/dvd") );
608     systemDrive->Add( wxU("/dev/cdrom") );
609 #endif
610
611     return systemDrive;
612 }
613
614 int hbApp::GetSystemCpuCount()
615 {
616     return hb_get_cpu_count();
617 }
618
619 void hbApp::Update()
620 {
621     hb_state_t s;
622
623     /* Special hack FIXME */
624     if( isEnd )
625     {
626         g_hbApp->ExitMainLoop();
627         return;
628     }
629
630     /* */
631     hb_get_state( hbHandle, &s );
632     switch( s.state )
633     {
634         case HB_STATE_IDLE:
635             break;
636
637         case HB_STATE_SCANNING:
638         {
639             int i_cur = s.param.scanning.title_cur;
640             int i_cnt = s.param.scanning.title_count;
641
642             if( i_cnt > 0 )
643             {
644                 progress->SetProgress( 100*(i_cur-1)/i_cnt,
645                                    wxString::Format(wxU("Scanning title %d of %d."),
646                                                     i_cur, i_cnt) );
647             }
648             break;
649         }
650
651         case HB_STATE_SCANDONE:
652             if( progress )
653             {
654                 progress->SetProgress( 100, wxU("Scanning complete.") );
655                 progress->Close( TRUE );
656                 //delete progress;
657                 progress = NULL;
658             }
659             break;
660
661         case HB_STATE_WORKING:
662         {
663             float f_progress = s.param.working.progress;
664             float f_rate_cur = s.param.working.rate_cur;
665             float f_rate_avg = s.param.working.rate_avg;
666
667             progress->SetProgress( (int)(100 * f_progress),
668                 wxString::Format(wxU("Encoding: %.2f %% (%.2f fps, avg %.2f fps)\n"),
669                                  100.0 * f_progress, f_rate_cur, f_rate_avg ));
670             break;
671         }
672
673         case HB_STATE_WORKDONE:
674             if( progress )
675             {
676                 progress->SetProgress( 100, wxU("Encoding complete.") );
677                 progress->Close( TRUE );
678                 //delete progress;
679                 progress = NULL;
680             }
681             break;
682     }
683 }
684