OSDN Git Service

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