OSDN Git Service

Theora.
[handbrake-jp/handbrake-jp-git.git] / libhb / hb.c
1 #include "hb.h"
2
3 #include "ffmpeg/avcodec.h"
4 #include "ffmpeg/swscale.h"
5
6 struct hb_handle_s
7 {
8     /* The "Check for update" thread */
9     int            build;
10     char           version[16];
11     hb_thread_t  * update_thread;
12
13     /* This thread's only purpose is to check other threads'
14        states */
15     volatile int   die;
16     hb_thread_t  * main_thread;
17     int            pid;
18
19     /* DVD/file scan thread */
20     hb_list_t    * list_title;
21     hb_thread_t  * scan_thread;
22
23     /* The thread which processes the jobs. Others threads are launched
24        from this one (see work.c) */
25     hb_list_t    * jobs;
26     hb_job_t     * current_job;
27     int            job_count;
28     int            job_count_permanent;
29     volatile int   work_die;
30     int            work_error;
31     hb_thread_t  * work_thread;
32
33     int            cpu_count;
34
35     hb_lock_t    * state_lock;
36     hb_state_t     state;
37
38     int            paused;
39     hb_lock_t    * pause_lock;
40     /* For MacGui active queue
41        increments each time the scan thread completes*/
42     int            scanCount;
43
44 };
45
46 hb_work_object_t * hb_objects = NULL;
47
48 static void thread_func( void * );
49
50 /**
51  * Registers work objects, by adding the work object to a liked list.
52  * @param w Handle to hb_work_object_t to register.
53  */
54 void hb_register( hb_work_object_t * w )
55 {
56     w->next    = hb_objects;
57     hb_objects = w;
58 }
59
60 /**
61  * libhb initialization routine.
62  * @param verbose HB_DEBUG_NONE or HB_DEBUG_ALL.
63  * @param update_check signals libhb to check for updated version from HandBrake website.
64  * @return Handle to hb_handle_t for use on all subsequent calls to libhb.
65  */
66 hb_handle_t * hb_init_real( int verbose, int update_check )
67 {
68     hb_handle_t * h = calloc( sizeof( hb_handle_t ), 1 );
69     uint64_t      date;
70
71     /* See hb_log() in common.c */
72     if( verbose > HB_DEBUG_NONE )
73     {
74         putenv( "HB_DEBUG=1" );
75                 av_log_set_level(AV_LOG_DEBUG);
76     }
77
78     /* Check for an update on the website if asked to */
79     h->build = -1;
80
81     if( update_check )
82     {
83         hb_log( "hb_init: checking for updates" );
84         date             = hb_get_date();
85         h->update_thread = hb_update_init( &h->build, h->version );
86
87         for( ;; )
88         {
89             if( hb_thread_has_exited( h->update_thread ) )
90             {
91                 /* Immediate success or failure */
92                 hb_thread_close( &h->update_thread );
93                 break;
94             }
95             if( hb_get_date() > date + 1000 )
96             {
97                 /* Still nothing after one second. Connection problem,
98                    let the thread die */
99                 hb_log( "hb_init: connection problem, not waiting for "
100                         "update_thread" );
101                 break;
102             }
103             hb_snooze( 500 );
104         }
105     }
106
107     /*
108      * Initialise buffer pool
109      */
110     hb_buffer_pool_init();
111
112     /* CPU count detection */
113     hb_log( "hb_init: checking cpu count" );
114     h->cpu_count = hb_get_cpu_count();
115
116     h->list_title = hb_list_init();
117     h->jobs       = hb_list_init();
118
119     h->state_lock  = hb_lock_init();
120     h->state.state = HB_STATE_IDLE;
121
122     h->pause_lock = hb_lock_init();
123
124     /* libavcodec */
125     avcodec_init();
126     avcodec_register_all();
127     av_register_codec_parser( &mpegaudio_parser);
128
129     /* Start library thread */
130     hb_log( "hb_init: starting libhb thread" );
131     h->die         = 0;
132     h->main_thread = hb_thread_init( "libhb", thread_func, h,
133                                      HB_NORMAL_PRIORITY );
134
135     return h;
136
137         /* Set the scan count to start at 0 */
138         //scan_count = 0;
139 }
140
141 /**
142  * libhb initialization routine.
143  * This version is to use when calling the dylib, the macro hb_init isn't available from a dylib call!
144  * @param verbose HB_DEBUG_NONE or HB_DEBUG_ALL.
145  * @param update_check signals libhb to check for updated version from HandBrake website.
146  * @return Handle to hb_handle_t for use on all subsequent calls to libhb.
147  */
148 hb_handle_t * hb_init_dl( int verbose, int update_check )
149 {
150     hb_handle_t * h = calloc( sizeof( hb_handle_t ), 1 );
151     uint64_t      date;
152
153     /* See hb_log() in common.c */
154     if( verbose > HB_DEBUG_NONE )
155     {
156         putenv( "HB_DEBUG=1" );
157                 av_log_set_level(AV_LOG_DEBUG);
158     }
159
160     /* Check for an update on the website if asked to */
161     h->build = -1;
162
163     if( update_check )
164     {
165         hb_log( "hb_init: checking for updates" );
166         date             = hb_get_date();
167         h->update_thread = hb_update_init( &h->build, h->version );
168
169         for( ;; )
170         {
171             if( hb_thread_has_exited( h->update_thread ) )
172             {
173                 /* Immediate success or failure */
174                 hb_thread_close( &h->update_thread );
175                 break;
176             }
177             if( hb_get_date() > date + 1000 )
178             {
179                 /* Still nothing after one second. Connection problem,
180                    let the thread die */
181                 hb_log( "hb_init: connection problem, not waiting for "
182                         "update_thread" );
183                 break;
184             }
185             hb_snooze( 500 );
186         }
187     }
188
189     /* CPU count detection */
190     hb_log( "hb_init: checking cpu count" );
191     h->cpu_count = hb_get_cpu_count();
192
193     h->list_title = hb_list_init();
194     h->jobs       = hb_list_init();
195     h->current_job = NULL;
196
197     h->state_lock  = hb_lock_init();
198     h->state.state = HB_STATE_IDLE;
199
200     h->pause_lock = hb_lock_init();
201
202     /* libavcodec */
203     avcodec_init();
204     avcodec_register_all();
205
206     /* Start library thread */
207     hb_log( "hb_init: starting libhb thread" );
208     h->die         = 0;
209     h->main_thread = hb_thread_init( "libhb", thread_func, h,
210                                      HB_NORMAL_PRIORITY );
211
212     hb_register( &hb_sync );
213         hb_register( &hb_decmpeg2 );
214         hb_register( &hb_decsub );
215         hb_register( &hb_render );
216         hb_register( &hb_encavcodec );
217         hb_register( &hb_encxvid );
218         hb_register( &hb_encx264 );
219     hb_register( &hb_enctheora );
220         hb_register( &hb_deca52 );
221         hb_register( &hb_decdca );
222         hb_register( &hb_decavcodec );
223         hb_register( &hb_declpcm );
224         hb_register( &hb_encfaac );
225         hb_register( &hb_enclame );
226         hb_register( &hb_encvorbis );
227
228         return h;
229 }
230
231
232 /**
233  * Returns current version of libhb.
234  * @param h Handle to hb_handle_t.
235  * @return character array of version number.
236  */
237 char * hb_get_version( hb_handle_t * h )
238 {
239     return HB_VERSION;
240 }
241
242 /**
243  * Returns current build of libhb.
244  * @param h Handle to hb_handle_t.
245  * @return character array of build number.
246  */
247 int hb_get_build( hb_handle_t * h )
248 {
249     return HB_BUILD;
250 }
251
252 /**
253  * Checks for needed update.
254  * @param h Handle to hb_handle_t.
255  * @param version Pointer to handle where version will be copied.
256  * @return update indicator.
257  */
258 int hb_check_update( hb_handle_t * h, char ** version )
259 {
260     *version = ( h->build < 0 ) ? NULL : h->version;
261     return h->build;
262 }
263
264 /**
265  * Sets the cpu count to the desired value.
266  * @param h Handle to hb_handle_t
267  * @param cpu_count Number of CPUs to use.
268  */
269 void hb_set_cpu_count( hb_handle_t * h, int cpu_count )
270 {
271     cpu_count    = MAX( 1, cpu_count );
272     cpu_count    = MIN( cpu_count, 8 );
273     h->cpu_count = cpu_count;
274 }
275
276 /**
277  * Initializes a scan of the by calling hb_scan_init
278  * @param h Handle to hb_handle_t
279  * @param path location of VIDEO_TS folder.
280  * @param title_index Desired title to scan.  0 for all titles.
281  */
282 void hb_scan( hb_handle_t * h, const char * path, int title_index )
283 {
284     hb_title_t * title;
285
286     /* Clean up from previous scan */
287     while( ( title = hb_list_item( h->list_title, 0 ) ) )
288     {
289         hb_list_rem( h->list_title, title );
290         hb_title_close( &title );
291     }
292
293     hb_log( "hb_scan: path=%s, title_index=%d", path, title_index );
294     h->scan_thread = hb_scan_init( h, path, title_index, h->list_title );
295 }
296
297 /**
298  * Returns the list of titles found.
299  * @param h Handle to hb_handle_t
300  * @return Handle to hb_list_t of the title list.
301  */
302 hb_list_t * hb_get_titles( hb_handle_t * h )
303 {
304     return h->list_title;
305 }
306
307 /**
308  * Create preview image of desired title a index of picture.
309  * @param h Handle to hb_handle_t.
310  * @param title Handle to hb_title_t of desired title.
311  * @param picture Index in title.
312  * @param buffer Handle to buufer were inage will be drawn.
313  */
314 void hb_get_preview( hb_handle_t * h, hb_title_t * title, int picture,
315                      uint8_t * buffer )
316 {
317     hb_job_t           * job = title->job;
318     char                 filename[1024];
319     FILE               * file;
320     uint8_t            * buf1, * buf2, * buf3, * buf4, * pen;
321     uint32_t           * p32;
322     AVPicture            pic_in, pic_preview, pic_deint, pic_crop, pic_scale;
323     struct SwsContext  * context;
324     int                  i;
325
326     buf1 = malloc( title->width * title->height * 3 / 2 );
327     buf2 = malloc( title->width * title->height * 3 / 2 );
328     buf3 = malloc( title->width * title->height * 3 / 2 );
329     buf4 = malloc( title->width * title->height * 4 );
330     avpicture_fill( &pic_in, buf1, PIX_FMT_YUV420P,
331                     title->width, title->height );
332     avpicture_fill( &pic_deint, buf2, PIX_FMT_YUV420P,
333                     title->width, title->height );
334     avpicture_fill( &pic_scale, buf3, PIX_FMT_YUV420P,
335                     job->width, job->height );
336     avpicture_fill( &pic_preview, buf4, PIX_FMT_RGBA32,
337                     job->width, job->height );
338
339     // Allocate the AVPicture frames and fill in
340
341     memset( filename, 0, 1024 );
342
343     hb_get_tempory_filename( h, filename, "%x%d",
344                              (intptr_t) title, picture );
345
346     file = fopen( filename, "r" );
347     if( !file )
348     {
349         hb_log( "hb_get_preview: fopen failed" );
350         return;
351     }
352
353     fread( buf1, title->width * title->height * 3 / 2, 1, file );
354     fclose( file );
355
356     if( job->deinterlace )
357     {
358         // Deinterlace and crop
359         avpicture_deinterlace( &pic_deint, &pic_in, PIX_FMT_YUV420P, title->width, title->height );
360         av_picture_crop( &pic_crop, &pic_deint, PIX_FMT_YUV420P, job->crop[0], job->crop[2] );
361     }
362     else
363     {
364         // Crop
365         av_picture_crop( &pic_crop, &pic_in, PIX_FMT_YUV420P, job->crop[0], job->crop[2] );
366     }
367
368     // Get scaling context
369     context = sws_getContext(title->width  - (job->crop[2] + job->crop[3]),
370                              title->height - (job->crop[0] + job->crop[1]),
371                              PIX_FMT_YUV420P,
372                              job->width, job->height, PIX_FMT_YUV420P,
373                              (uint16_t)(SWS_LANCZOS|SWS_ACCURATE_RND), NULL, NULL, NULL);
374
375     // Scale
376     sws_scale(context,
377               pic_crop.data, pic_crop.linesize,
378               0, title->height - (job->crop[0] + job->crop[1]),
379               pic_scale.data, pic_scale.linesize);
380
381     // Free context
382     sws_freeContext( context );
383
384     // Get preview context
385     context = sws_getContext(job->width, job->height, PIX_FMT_YUV420P,
386                              job->width, job->height, PIX_FMT_RGBA32,
387                              (uint16_t)(SWS_LANCZOS|SWS_ACCURATE_RND), NULL, NULL, NULL);
388
389     // Create preview
390     sws_scale(context,
391               pic_scale.data, pic_scale.linesize,
392               0, job->height,
393               pic_preview.data, pic_preview.linesize);
394
395     // Free context
396     sws_freeContext( context );
397
398     /* Gray background */
399     p32 = (uint32_t *) buffer;
400     for( i = 0; i < ( title->width + 2 ) * ( title->height + 2 ); i++ )
401     {
402         p32[i] = 0xFF808080;
403     }
404
405     /* Draw the picture, centered, and draw the cropping zone */
406     pen = buffer + ( title->height - job->height ) *
407         ( title->width + 2 ) * 2 + ( title->width - job->width ) * 2;
408     memset( pen, 0xFF, 4 * ( job->width + 2 ) );
409     pen += 4 * ( title->width + 2 );
410     for( i = 0; i < job->height; i++ )
411     {
412         uint8_t * nextLine;
413         nextLine = pen + 4 * ( title->width + 2 );
414         memset( pen, 0xFF, 4 );
415         pen += 4;
416         memcpy( pen, buf4 + 4 * job->width * i, 4 * job->width );
417         pen += 4 * job->width;
418         memset( pen, 0xFF, 4 );
419         pen = nextLine;
420     }
421     memset( pen, 0xFF, 4 * ( job->width + 2 ) );
422
423     // Clean up
424     avpicture_free( &pic_preview );
425     avpicture_free( &pic_scale );
426     avpicture_free( &pic_deint );
427     avpicture_free( &pic_in );
428 }
429
430 /**
431  * Calculates job width and height for anamorphic content,
432  *
433  * @param job Handle to hb_job_t
434  * @param output_width Pointer to returned storage width
435  * @param output_height Pointer to returned storage height
436  * @param output_par_width Pointer to returned pixel width
437  @ param output_par_height Pointer to returned pixel height
438  */
439 void hb_set_anamorphic_size( hb_job_t * job,
440         int *output_width, int *output_height,
441         int *output_par_width, int *output_par_height )
442 {
443     /* "Loose" anamorphic.
444         - Uses mod16-compliant dimensions,
445         - Allows users to set the width
446         - Handles ITU pixel aspects
447     */
448
449     /* Set up some variables to make the math easier to follow. */
450     hb_title_t * title = job->title;
451     int cropped_width = title->width - job->crop[2] - job->crop[3] ;
452     int cropped_height = title->height - job->crop[0] - job->crop[1] ;
453     int storage_aspect = cropped_width * 10000 / cropped_height;
454     int width = job->width;
455     int height; // Gets set later, ignore user value
456     int mod = job->modulus;
457     int aspect = title->aspect;
458
459     /* Gotta handle bounding dimensions differently
460        than for non-anamorphic encodes:
461        If the width is too big, just reset it with no rescaling.
462        Instead of using the aspect-scaled job height,
463        we need to see if the job width divided by the storage aspect
464        is bigger than the max. If so, set it to the max (this is sloppy).
465        If not, set job height to job width divided by storage aspect.
466     */
467
468     if ( job->maxWidth && (job->maxWidth < job->width) )
469             width = job->maxWidth;
470
471     if ( job->maxHeight && (job->maxHeight < (width / storage_aspect * 10000)) )
472     {
473         height = job->maxHeight;
474     }
475     else
476     {
477         height = width * 10000 / storage_aspect;
478     }
479
480
481     /* Time to get picture dimensions that divide cleanly.
482        These variables will store temporary dimensions as we iterate. */
483     int i, w, h;
484
485     /* In case the user specified a modulus, use it */
486     if (job->modulus)
487         mod = job->modulus;
488     else
489         mod = 16;
490
491     /* Iterate through multiples of mod to find one close to job->width. */
492     for( i = 1;; i++ )
493     {
494         w = mod * i;
495
496         if (w < width)
497         {
498             if ( ( width - w ) <= ( mod / 2 ) )
499                 /* We'll take a width that's
500                    smaller, but close enough. */
501                 break;
502         }
503         if (w == width)
504             /* Mod 16 dimensions, how nice! */
505             break;
506         if( w > width )
507         {
508             if ( ( w - width ) < (mod/2) )
509                 /* We'll take a width that's bigger, if we have to. */
510                 break;
511         }
512     }
513     width  = mod * (i);
514
515     /* Now do the same for a mod-friendly value near job->height. */
516     for( i = 1;; i++)
517     {
518         h = i * mod;
519
520         if (h < height)
521             {
522                 if ( ( height - h ) <= ( mod / 2 ))
523                     /* Go with a smaller height,
524                        if it's close enough.    */
525                     break;
526             }
527         if (h == height)
528             /* Mod 16 dimensions, how nice! */
529             break;
530
531         if ( h > height)
532         {
533             if ( ( h - height ) < ( mod / 2 ))
534                 /* Use a taller height if necessary */
535                 break;
536         }
537     }
538     height = mod  * (i);
539
540     int pixel_aspect_width = job->pixel_aspect_width;
541     int pixel_aspect_height = job->pixel_aspect_height;
542
543     if (cropped_width <= 706)
544     {
545         /* Handle ITU PARs */
546         if (title->height == 480)
547         {
548             /* It's NTSC */
549             if (aspect == 16)
550             {
551                 /* It's widescreen */
552                 pixel_aspect_width = 40;
553                 pixel_aspect_height = 33;
554             }
555             else
556             {
557                 /* It's 4:3 */
558                 pixel_aspect_width = 10;
559                 pixel_aspect_height = 11;
560             }
561         }
562         else if (title->height == 576)
563         {
564             /* It's PAL */
565             if(aspect == 16)
566             {
567                 /* It's widescreen */
568                 pixel_aspect_width = 16;
569                 pixel_aspect_height = 11;
570             }
571             else
572             {
573                 /* It's 4:3 */
574                 pixel_aspect_width = 12;
575                 pixel_aspect_height = 11;
576             }
577         }
578     }
579
580     /* Figure out what dimensions the source would display at. */
581     int source_display_width = cropped_width * ((float)pixel_aspect_width / (float)pixel_aspect_height) ;
582
583     /* The film AR is the source's display width / cropped source height.
584        The output display width is the output height * film AR.
585        The output PAR is the output display width / output storage width. */
586     pixel_aspect_width = height * source_display_width / cropped_height;
587     pixel_aspect_height = width;
588
589     /* While x264 is smart enough to reduce fractions on its own, libavcodec
590        needs some help with the math, so lose superfluous factors.            */
591     hb_reduce( &pixel_aspect_width, &pixel_aspect_height,
592                pixel_aspect_width, pixel_aspect_height );
593
594     /* Pass the results back to the caller */
595     *output_width = width;
596     *output_height = height;
597     *output_par_width = pixel_aspect_width;
598     *output_par_height = pixel_aspect_height;
599 }
600
601 /**
602  * Calculates job width, height, and cropping parameters.
603  * @param job Handle to hb_job_t.
604  * @param aspect Desired aspect ratio. Value of -1 uses title aspect.
605  * @param pixels Maximum desired pixel count.
606  */
607 void hb_set_size( hb_job_t * job, int aspect, int pixels )
608 {
609     hb_title_t * title = job->title;
610
611     int croppedWidth  = title->width - title->crop[2] - title->crop[3];
612     int croppedHeight = title->height - title->crop[0] - title->crop[1];
613     int croppedAspect = title->aspect * title->height * croppedWidth /
614                             croppedHeight / title->width;
615     int addCrop;
616     int i, w, h;
617
618     if( aspect <= 0 )
619     {
620         /* Keep the best possible aspect ratio */
621         aspect = croppedAspect;
622     }
623
624     /* Crop if necessary to obtain the desired ratio */
625     memcpy( job->crop, title->crop, 4 * sizeof( int ) );
626     if( aspect < croppedAspect )
627     {
628         /* Need to crop on the left and right */
629         addCrop = croppedWidth - aspect * croppedHeight * title->width /
630                     title->aspect / title->height;
631         if( addCrop & 3 )
632         {
633             addCrop = ( addCrop + 1 ) / 2;
634             job->crop[2] += addCrop;
635             job->crop[3] += addCrop;
636         }
637         else if( addCrop & 2 )
638         {
639             addCrop /= 2;
640             job->crop[2] += addCrop - 1;
641             job->crop[3] += addCrop + 1;
642         }
643         else
644         {
645             addCrop /= 2;
646             job->crop[2] += addCrop;
647             job->crop[3] += addCrop;
648         }
649     }
650     else if( aspect > croppedAspect )
651     {
652         /* Need to crop on the top and bottom */
653         addCrop = croppedHeight - croppedWidth * title->aspect *
654             title->height / aspect / title->width;
655         if( addCrop & 3 )
656         {
657             addCrop = ( addCrop + 1 ) / 2;
658             job->crop[0] += addCrop;
659             job->crop[1] += addCrop;
660         }
661         else if( addCrop & 2 )
662         {
663             addCrop /= 2;
664             job->crop[0] += addCrop - 1;
665             job->crop[1] += addCrop + 1;
666         }
667         else
668         {
669             addCrop /= 2;
670             job->crop[0] += addCrop;
671             job->crop[1] += addCrop;
672         }
673     }
674
675     /* Compute a resolution from the number of pixels and aspect */
676     for( i = 0;; i++ )
677     {
678         w = 16 * i;
679         h = MULTIPLE_16( w * HB_ASPECT_BASE / aspect );
680         if( w * h > pixels )
681         {
682             break;
683         }
684     }
685     i--;
686     job->width  = 16 * i;
687     job->height = MULTIPLE_16( 16 * i * HB_ASPECT_BASE / aspect );
688 }
689
690 /**
691  * Returns the number of jobs in the queue.
692  * @param h Handle to hb_handle_t.
693  * @return Number of jobs.
694  */
695 int hb_count( hb_handle_t * h )
696 {
697     return hb_list_count( h->jobs );
698 }
699
700 /**
701  * Returns handle to job at index i within the job list.
702  * @param h Handle to hb_handle_t.
703  * @param i Index of job.
704  * @returns Handle to hb_job_t of desired job.
705  */
706 hb_job_t * hb_job( hb_handle_t * h, int i )
707 {
708     return hb_list_item( h->jobs, i );
709 }
710
711 hb_job_t * hb_current_job( hb_handle_t * h )
712 {
713     return( h->current_job );
714 }
715
716 /**
717  * Adds a job to the job list.
718  * @param h Handle to hb_handle_t.
719  * @param job Handle to hb_job_t.
720  */
721 void hb_add( hb_handle_t * h, hb_job_t * job )
722 {
723     hb_job_t      * job_copy;
724     hb_title_t    * title,    * title_copy;
725     hb_chapter_t  * chapter,  * chapter_copy;
726     hb_audio_t    * audio,    * audio_copy;
727     hb_subtitle_t * subtitle, * subtitle_copy;
728     int             i;
729     char            audio_lang[4];
730
731     /* Copy the title */
732     title      = job->title;
733     title_copy = malloc( sizeof( hb_title_t ) );
734     memcpy( title_copy, title, sizeof( hb_title_t ) );
735
736     title_copy->list_chapter = hb_list_init();
737     for( i = 0; i < hb_list_count( title->list_chapter ); i++ )
738     {
739         chapter      = hb_list_item( title->list_chapter, i );
740         chapter_copy = malloc( sizeof( hb_chapter_t ) );
741         memcpy( chapter_copy, chapter, sizeof( hb_chapter_t ) );
742         hb_list_add( title_copy->list_chapter, chapter_copy );
743     }
744
745     /* Copy the audio track(s) we want */
746     title_copy->list_audio = hb_list_init();
747
748     /* Do nothing about audio during first pass */
749     if( job->pass == 0 || job->pass == 2 )
750     {
751         for( i = 0; i < 8; i++ )
752         {
753             if( job->audios[i] < 0 )
754             {
755                 break;
756             }
757             if( ( audio = hb_list_item( title->list_audio, job->audios[i] ) ) )
758             {
759                 audio_copy = malloc( sizeof( hb_audio_t ) );
760                 memcpy( audio_copy, audio, sizeof( hb_audio_t ) );
761                 hb_list_add( title_copy->list_audio, audio_copy );
762             }
763         }
764     }
765
766     title_copy->list_subtitle = hb_list_init();
767
768     /*
769      * The following code is confusing, there are three ways in which
770      * we select subtitles and it depends on whether this is single or
771      * two pass mode.
772      *
773      * subtitle_scan may be enabled, in which case the first pass
774      * scans all subtitles of that language. The second pass does not
775      * select any because they are set at the end of the first pass.
776      *
777      * native_language may have a preferred language, in which case we
778      * may be switching the language we want for the subtitles in the
779      * first pass of a single pass, or the second pass of a two pass.
780      *
781      * We may have manually selected a subtitle, in which case that is
782      * selected in the first pass of a single pass, or the second of a
783      * two pass.
784      */
785     memset( audio_lang, 0, sizeof( audio_lang ) );
786
787     if ( job->indepth_scan || job->native_language ) {
788
789         /*
790          * Find the first audio language that is being encoded
791          */
792         for( i = 0; i < 8; i++ )
793         {
794             if( job->audios[i] < 0 )
795             {
796                 break;
797             }
798             if( ( audio = hb_list_item( title->list_audio, job->audios[i] ) ) )
799             {
800                 strncpy(audio_lang, audio->iso639_2, sizeof(audio_lang));
801                 break;
802             }
803         }
804
805         /*
806          * In all cases switch the language if we need to to our native
807          * language.
808          */
809         if( job->native_language )
810         {
811             if( strncasecmp( job->native_language, audio_lang,
812                              sizeof( audio_lang ) ) != 0 )
813             {
814
815                 if( job->pass != 2 )
816                 {
817                     hb_log( "Enabled subtitles in native language '%s', audio is in '%s'",
818                             job->native_language, audio_lang);
819                 }
820                 /*
821                  * The main audio track is not in our native language, so switch
822                  * the subtitles to use our native language instead.
823                  */
824                 strncpy( audio_lang, job->native_language, sizeof( audio_lang ) );
825             } else {
826                 /*
827                  * native language is irrelevent, free it.
828                  */
829                 free( job->native_language );
830                 job->native_language = NULL;
831             }
832         }
833     }
834
835     /*
836      * If doing a subtitle scan then add all the matching subtitles for this
837      * language.
838      */
839     if ( job->indepth_scan )
840     {
841         for( i=0; i < hb_list_count( title->list_subtitle ); i++ )
842         {
843             subtitle = hb_list_item( title->list_subtitle, i );
844             if( strcmp( subtitle->iso639_2, audio_lang ) == 0 )
845             {
846                 /*
847                  * Matched subtitle language with audio language, so
848                  * add this to our list to scan.
849                  *
850                  * We will update the subtitle list on the second pass
851                  * later after the first pass has completed.
852                  */
853                 subtitle_copy = malloc( sizeof( hb_subtitle_t ) );
854                 memcpy( subtitle_copy, subtitle, sizeof( hb_subtitle_t ) );
855                 hb_list_add( title_copy->list_subtitle, subtitle_copy );
856                 if ( job->native_language ) {
857                     /*
858                      * With native language just select the
859                      * first match in our langiage, not all of
860                      * them. Subsequent ones are likely to be commentary
861                      */
862                     break;
863                 }
864             }
865         }
866     } else {
867         /*
868          * Not doing a subtitle scan in this pass, but maybe we are in the
869          * first pass?
870          */
871         if( job->select_subtitle )
872         {
873             /*
874              * Don't add subtitles here, we'll add them via select_subtitle
875              * at the end of the subtitle_scan.
876              */
877         } else {
878             /*
879              * Definitely not doing a subtitle scan.
880              */
881             if( job->pass != 1 && job->native_language )
882             {
883                 /*
884                  * We are not doing a subtitle scan but do want the
885                  * native langauge subtitle selected, so select it
886                  * for pass 0 or pass 2 of a two pass.
887                  */
888                 for( i=0; i < hb_list_count( title->list_subtitle ); i++ )
889                 {
890                     subtitle = hb_list_item( title->list_subtitle, i );
891                     if( strcmp( subtitle->iso639_2, audio_lang ) == 0 )
892                     {
893                         /*
894                          * Matched subtitle language with audio language, so
895                          * add this to our list to scan.
896                          */
897                         subtitle_copy = malloc( sizeof( hb_subtitle_t ) );
898                         memcpy( subtitle_copy, subtitle, sizeof( hb_subtitle_t ) );
899                         hb_list_add( title_copy->list_subtitle, subtitle_copy );
900                         break;
901                     }
902                 }
903             } else {
904                 /*
905                  * Manually selected subtitle, in which case only
906                  * bother adding them for pass 0 or pass 2 of a two
907                  * pass.
908                  */
909                 if( job->pass != 1 )
910                 {
911                     if( ( subtitle = hb_list_item( title->list_subtitle, job->subtitle ) ) )
912                     {
913                         subtitle_copy = malloc( sizeof( hb_subtitle_t ) );
914                         memcpy( subtitle_copy, subtitle, sizeof( hb_subtitle_t ) );
915                         hb_list_add( title_copy->list_subtitle, subtitle_copy );
916                     }
917                 }
918             }
919         }
920     }
921
922     /* Copy the job */
923     job_copy        = calloc( sizeof( hb_job_t ), 1 );
924     memcpy( job_copy, job, sizeof( hb_job_t ) );
925     title_copy->job = job_copy;
926     job_copy->title = title_copy;
927     job_copy->file  = strdup( job->file );
928     job_copy->h     = h;
929     job_copy->pause = h->pause_lock;
930
931     /* Copy the job filter list */
932     if( job->filters )
933     {
934         int i;
935         int filter_count = hb_list_count( job->filters );
936         job_copy->filters = hb_list_init();
937         for( i = 0; i < filter_count; i++ )
938         {
939             /*
940              * Copy the filters, since the MacGui reuses the global filter objects
941              * meaning that queued up jobs overwrite the previous filter settings.
942              * In reality, settings is probably the only field that needs duplicating
943              * since it's the only value that is ever changed. But name is duplicated
944              * as well for completeness. Not copying private_data since it gets
945              * created for each job in renderInit.
946              */
947             hb_filter_object_t * filter = hb_list_item( job->filters, i );
948             hb_filter_object_t * filter_copy = malloc( sizeof( hb_filter_object_t ) );
949             memcpy( filter_copy, filter, sizeof( hb_filter_object_t ) );
950             if( filter->name )
951                 filter_copy->name = strdup( filter->name );
952             if( filter->settings )
953                 filter_copy->settings = strdup( filter->settings );
954             hb_list_add( job_copy->filters, filter_copy );
955         }
956     }
957
958     /* Add the job to the list */
959     hb_list_add( h->jobs, job_copy );
960     h->job_count = hb_count(h);
961     h->job_count_permanent++;
962 }
963
964 /**
965  * Removes a job from the job list.
966  * @param h Handle to hb_handle_t.
967  * @param job Handle to hb_job_t.
968  */
969 void hb_rem( hb_handle_t * h, hb_job_t * job )
970 {
971     hb_list_rem( h->jobs, job );
972
973     h->job_count = hb_count(h);
974     if (h->job_count_permanent)
975         h->job_count_permanent--;
976
977     /* XXX free everything XXX */
978 }
979
980 /**
981  * Starts the conversion process.
982  * Sets state to HB_STATE_WORKING.
983  * calls hb_work_init, to launch work thread. Stores handle to work thread.
984  * @param h Handle to hb_handle_t.
985  */
986 void hb_start( hb_handle_t * h )
987 {
988     /* XXX Hack */
989     h->job_count = hb_list_count( h->jobs );
990     h->job_count_permanent = h->job_count;
991
992     hb_lock( h->state_lock );
993     h->state.state = HB_STATE_WORKING;
994 #define p h->state.param.working
995     p.progress  = 0.0;
996     p.job_cur   = 1;
997     p.job_count = h->job_count;
998     p.rate_cur  = 0.0;
999     p.rate_avg  = 0.0;
1000     p.hours     = -1;
1001     p.minutes   = -1;
1002     p.seconds   = -1;
1003     p.sequence_id = 0;
1004 #undef p
1005     hb_unlock( h->state_lock );
1006
1007     h->paused = 0;
1008
1009     h->work_die    = 0;
1010     h->work_thread = hb_work_init( h->jobs, h->cpu_count,
1011                                    &h->work_die, &h->work_error, &h->current_job );
1012 }
1013
1014 /**
1015  * Pauses the conversion process.
1016  * @param h Handle to hb_handle_t.
1017  */
1018 void hb_pause( hb_handle_t * h )
1019 {
1020     if( !h->paused )
1021     {
1022         hb_lock( h->pause_lock );
1023         h->paused = 1;
1024
1025         hb_lock( h->state_lock );
1026         h->state.state = HB_STATE_PAUSED;
1027         hb_unlock( h->state_lock );
1028     }
1029 }
1030
1031 /**
1032  * Resumes the conversion process.
1033  * @param h Handle to hb_handle_t.
1034  */
1035 void hb_resume( hb_handle_t * h )
1036 {
1037     if( h->paused )
1038     {
1039         hb_unlock( h->pause_lock );
1040         h->paused = 0;
1041     }
1042 }
1043
1044 /**
1045  * Stops the conversion process.
1046  * @param h Handle to hb_handle_t.
1047  */
1048 void hb_stop( hb_handle_t * h )
1049 {
1050     h->work_die = 1;
1051
1052     h->job_count = hb_count(h);
1053     h->job_count_permanent = 0;
1054
1055     hb_resume( h );
1056 }
1057
1058 /**
1059  * Returns the state of the conversion process.
1060  * @param h Handle to hb_handle_t.
1061  * @param s Handle to hb_state_t which to copy the state data.
1062  */
1063 void hb_get_state( hb_handle_t * h, hb_state_t * s )
1064 {
1065     hb_lock( h->state_lock );
1066
1067     memcpy( s, &h->state, sizeof( hb_state_t ) );
1068     if ( h->state.state == HB_STATE_SCANDONE || h->state.state == HB_STATE_WORKDONE )
1069         h->state.state = HB_STATE_IDLE;
1070
1071     hb_unlock( h->state_lock );
1072 }
1073
1074 void hb_get_state2( hb_handle_t * h, hb_state_t * s )
1075 {
1076     hb_lock( h->state_lock );
1077
1078     memcpy( s, &h->state, sizeof( hb_state_t ) );
1079
1080     hb_unlock( h->state_lock );
1081 }
1082
1083 /**
1084  * Called in MacGui in UpdateUI to check
1085  *  for a new scan being completed to set a new source
1086  */
1087 int hb_get_scancount( hb_handle_t * h)
1088  {
1089      return h->scanCount;
1090  }
1091
1092 /**
1093  * Closes access to libhb by freeing the hb_handle_t handle ontained in hb_init_real.
1094  * @param _h Pointer to handle to hb_handle_t.
1095  */
1096 void hb_close( hb_handle_t ** _h )
1097 {
1098     hb_handle_t * h = *_h;
1099     hb_title_t * title;
1100
1101     h->die = 1;
1102     hb_thread_close( &h->main_thread );
1103
1104     while( ( title = hb_list_item( h->list_title, 0 ) ) )
1105     {
1106         hb_list_rem( h->list_title, title );
1107         if( title->job && title->job->filters )
1108         {
1109             hb_list_close( &title->job->filters );
1110         }
1111         free( title->job );
1112         hb_title_close( &title );
1113     }
1114     hb_list_close( &h->list_title );
1115
1116     hb_list_close( &h->jobs );
1117     hb_lock_close( &h->state_lock );
1118     hb_lock_close( &h->pause_lock );
1119     free( h );
1120     *_h = NULL;
1121
1122 }
1123
1124 /**
1125  * Monitors the state of the update, scan, and work threads.
1126  * Sets scan done state when scan thread exits.
1127  * Sets work done state when work thread exits.
1128  * @param _h Handle to hb_handle_t
1129  */
1130 static void thread_func( void * _h )
1131 {
1132     hb_handle_t * h = (hb_handle_t *) _h;
1133     char dirname[1024];
1134     DIR * dir;
1135     struct dirent * entry;
1136
1137     h->pid = getpid();
1138
1139     /* Create folder for temporary files */
1140     memset( dirname, 0, 1024 );
1141     hb_get_tempory_directory( h, dirname );
1142
1143     hb_mkdir( dirname );
1144
1145     while( !h->die )
1146     {
1147         /* In case the check_update thread hangs, it'll die sooner or
1148            later. Then, we join it here */
1149         if( h->update_thread &&
1150             hb_thread_has_exited( h->update_thread ) )
1151         {
1152             hb_thread_close( &h->update_thread );
1153         }
1154
1155         /* Check if the scan thread is done */
1156         if( h->scan_thread &&
1157             hb_thread_has_exited( h->scan_thread ) )
1158         {
1159             hb_thread_close( &h->scan_thread );
1160
1161             hb_log( "libhb: scan thread found %d valid title(s)",
1162                     hb_list_count( h->list_title ) );
1163             hb_lock( h->state_lock );
1164             h->state.state = HB_STATE_SCANDONE; //originally state.state
1165                         hb_unlock( h->state_lock );
1166                         /*we increment this sessions scan count by one for the MacGui
1167                         to trigger a new source being set */
1168             h->scanCount++;
1169         }
1170
1171         /* Check if the work thread is done */
1172         if( h->work_thread &&
1173             hb_thread_has_exited( h->work_thread ) )
1174         {
1175             hb_thread_close( &h->work_thread );
1176
1177             hb_log( "libhb: work result = %d",
1178                     h->work_error );
1179             hb_lock( h->state_lock );
1180             h->state.state                = HB_STATE_WORKDONE;
1181             h->state.param.workdone.error = h->work_error;
1182
1183             h->job_count = hb_count(h);
1184             if (h->job_count < 1)
1185                 h->job_count_permanent = 0;
1186             hb_unlock( h->state_lock );
1187         }
1188
1189         hb_snooze( 50 );
1190     }
1191
1192     if( h->work_thread )
1193     {
1194         hb_stop( h );
1195         hb_thread_close( &h->work_thread );
1196     }
1197
1198     /* Remove temp folder */
1199     dir = opendir( dirname );
1200     while( ( entry = readdir( dir ) ) )
1201     {
1202         char filename[1024];
1203         if( entry->d_name[0] == '.' )
1204         {
1205             continue;
1206         }
1207         memset( filename, 0, 1024 );
1208         snprintf( filename, 1023, "%s/%s", dirname, entry->d_name );
1209         unlink( filename );
1210     }
1211     closedir( dir );
1212     rmdir( dirname );
1213 }
1214
1215 /**
1216  * Returns the PID.
1217  * @param h Handle to hb_handle_t
1218  */
1219 int hb_get_pid( hb_handle_t * h )
1220 {
1221     return h->pid;
1222 }
1223
1224 /**
1225  * Sets the current state.
1226  * @param h Handle to hb_handle_t
1227  * @param s Handle to new hb_state_t
1228  */
1229 void hb_set_state( hb_handle_t * h, hb_state_t * s )
1230 {
1231     hb_lock( h->pause_lock );
1232     hb_lock( h->state_lock );
1233     memcpy( &h->state, s, sizeof( hb_state_t ) );
1234     if( h->state.state == HB_STATE_WORKING )
1235     {
1236         /* XXX Hack */
1237         if (h->job_count < 1)
1238             h->job_count_permanent = 1;
1239
1240         h->state.param.working.job_cur =
1241             h->job_count_permanent - hb_list_count( h->jobs );
1242         h->state.param.working.job_count = h->job_count_permanent;
1243
1244         // Set which job is being worked on
1245         if (h->current_job)
1246             h->state.param.working.sequence_id = h->current_job->sequence_id;
1247         else
1248             h->state.param.working.sequence_id = 0;
1249     }
1250     hb_unlock( h->state_lock );
1251     hb_unlock( h->pause_lock );
1252 }