OSDN Git Service

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