OSDN Git Service

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