OSDN Git Service

fix some floating point rounding errors in aspect ratio calculations
[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) + 0.5;
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     /*
824      * Copy the metadata
825      */
826     if( title->metadata )
827     {
828         title_copy->metadata = malloc( sizeof( hb_metadata_t ) );
829         
830         if( title_copy->metadata ) 
831         {
832             memcpy( title_copy->metadata, title->metadata, sizeof( hb_metadata_t ) );
833
834             /*
835              * Need to copy the artwork seperatly (TODO).
836              */
837             if( title->metadata->coverart )
838             {
839                 title_copy->metadata->coverart = malloc( title->metadata->coverart_size );
840                 if( title_copy->metadata->coverart )
841                 {
842                     memcpy( title_copy->metadata->coverart, title->metadata->coverart,
843                             title->metadata->coverart_size );
844                 } else {
845                     title_copy->metadata->coverart_size = 0; 
846                 }
847             }
848         }
849     }
850
851     /* Copy the audio track(s) we want */
852     title_copy->list_audio = hb_list_init();
853
854     for( i = 0; i < hb_list_count(job->list_audio); i++ )
855     {
856         if( ( audio = hb_list_item( job->list_audio, i ) ) )
857         {
858             hb_list_add( title_copy->list_audio, hb_audio_copy(audio) );
859         }
860     }
861
862     title_copy->list_subtitle = hb_list_init();
863
864     /*
865      * The following code is confusing, there are three ways in which
866      * we select subtitles and it depends on whether this is single or
867      * two pass mode.
868      *
869      * subtitle_scan may be enabled, in which case the first pass
870      * scans all subtitles of that language. The second pass does not
871      * select any because they are set at the end of the first pass.
872      *
873      * native_language may have a preferred language, in which case we
874      * may be switching the language we want for the subtitles in the
875      * first pass of a single pass, or the second pass of a two pass.
876      *
877      * We may have manually selected a subtitle, in which case that is
878      * selected in the first pass of a single pass, or the second of a
879      * two pass.
880      */
881     memset( audio_lang, 0, sizeof( audio_lang ) );
882
883     if ( job->indepth_scan || job->native_language ) {
884
885         /*
886          * Find the first audio language that is being encoded
887          */
888         for( i = 0; i < hb_list_count(job->list_audio); i++ )
889         {
890             if( ( audio = hb_list_item( job->list_audio, i ) ) )
891             {
892                 strncpy(audio_lang, audio->config.lang.iso639_2, sizeof(audio_lang));
893                 break;
894             }
895         }
896
897         /*
898          * In all cases switch the language if we need to to our native
899          * language.
900          */
901         if( job->native_language )
902         {
903             if( strncasecmp( job->native_language, audio_lang,
904                              sizeof( audio_lang ) ) != 0 )
905             {
906
907                 if( job->pass != 2 )
908                 {
909                     hb_log( "Enabled subtitles in native language '%s', audio is in '%s'",
910                             job->native_language, audio_lang);
911                 }
912                 /*
913                  * The main audio track is not in our native language, so switch
914                  * the subtitles to use our native language instead.
915                  */
916                 strncpy( audio_lang, job->native_language, sizeof( audio_lang ) );
917             } else {
918                 /*
919                  * native language is irrelevent, free it.
920                  */
921                 free( job->native_language );
922                 job->native_language = NULL;
923             }
924         }
925     }
926
927     /*
928      * If doing a subtitle scan then add all the matching subtitles for this
929      * language.
930      */
931     if ( job->indepth_scan )
932     {
933         for( i=0; i < hb_list_count( title->list_subtitle ); i++ )
934         {
935             subtitle = hb_list_item( title->list_subtitle, i );
936             if( strcmp( subtitle->iso639_2, audio_lang ) == 0 )
937             {
938                 /*
939                  * Matched subtitle language with audio language, so
940                  * add this to our list to scan.
941                  *
942                  * We will update the subtitle list on the second pass
943                  * later after the first pass has completed.
944                  */
945                 subtitle_copy = malloc( sizeof( hb_subtitle_t ) );
946                 memcpy( subtitle_copy, subtitle, sizeof( hb_subtitle_t ) );
947                 hb_list_add( title_copy->list_subtitle, subtitle_copy );
948                 if ( job->native_language ) {
949                     /*
950                      * With native language just select the
951                      * first match in our langiage, not all of
952                      * them. Subsequent ones are likely to be commentary
953                      */
954                     break;
955                 }
956             }
957         }
958     } else {
959         /*
960          * Not doing a subtitle scan in this pass, but maybe we are in the
961          * first pass?
962          */
963         if( job->select_subtitle )
964         {
965             /*
966              * Don't add subtitles here, we'll add them via select_subtitle
967              * at the end of the subtitle_scan.
968              */
969         } else {
970             /*
971              * Definitely not doing a subtitle scan.
972              */
973             if( job->pass != 1 && job->native_language )
974             {
975                 /*
976                  * We are not doing a subtitle scan but do want the
977                  * native langauge subtitle selected, so select it
978                  * for pass 0 or pass 2 of a two pass.
979                  */
980                 for( i=0; i < hb_list_count( title->list_subtitle ); i++ )
981                 {
982                     subtitle = hb_list_item( title->list_subtitle, i );
983                     if( strcmp( subtitle->iso639_2, audio_lang ) == 0 )
984                     {
985                         /*
986                          * Matched subtitle language with audio language, so
987                          * add this to our list to scan.
988                          */
989                         subtitle_copy = malloc( sizeof( hb_subtitle_t ) );
990                         memcpy( subtitle_copy, subtitle, sizeof( hb_subtitle_t ) );
991                         hb_list_add( title_copy->list_subtitle, subtitle_copy );
992                         break;
993                     }
994                 }
995             } else {
996                 /*
997                  * Manually selected subtitle, in which case only
998                  * bother adding them for pass 0 or pass 2 of a two
999                  * pass.
1000                  */
1001                 if( job->pass != 1 )
1002                 {
1003                     if( ( subtitle = hb_list_item( title->list_subtitle, job->subtitle ) ) )
1004                     {
1005                         subtitle_copy = malloc( sizeof( hb_subtitle_t ) );
1006                         memcpy( subtitle_copy, subtitle, sizeof( hb_subtitle_t ) );
1007                         hb_list_add( title_copy->list_subtitle, subtitle_copy );
1008                     }
1009                 }
1010             }
1011         }
1012     }
1013
1014     /* Copy the job */
1015     job_copy        = calloc( sizeof( hb_job_t ), 1 );
1016     memcpy( job_copy, job, sizeof( hb_job_t ) );
1017     title_copy->job = job_copy;
1018     job_copy->title = title_copy;
1019     job_copy->list_audio = title_copy->list_audio;
1020     job_copy->file  = strdup( job->file );
1021     job_copy->h     = h;
1022     job_copy->pause = h->pause_lock;
1023
1024     /* Copy the job filter list */
1025     if( job->filters )
1026     {
1027         int i;
1028         int filter_count = hb_list_count( job->filters );
1029         job_copy->filters = hb_list_init();
1030         for( i = 0; i < filter_count; i++ )
1031         {
1032             /*
1033              * Copy the filters, since the MacGui reuses the global filter objects
1034              * meaning that queued up jobs overwrite the previous filter settings.
1035              * In reality, settings is probably the only field that needs duplicating
1036              * since it's the only value that is ever changed. But name is duplicated
1037              * as well for completeness. Not copying private_data since it gets
1038              * created for each job in renderInit.
1039              */
1040             hb_filter_object_t * filter = hb_list_item( job->filters, i );
1041             hb_filter_object_t * filter_copy = malloc( sizeof( hb_filter_object_t ) );
1042             memcpy( filter_copy, filter, sizeof( hb_filter_object_t ) );
1043             if( filter->name )
1044                 filter_copy->name = strdup( filter->name );
1045             if( filter->settings )
1046                 filter_copy->settings = strdup( filter->settings );
1047             hb_list_add( job_copy->filters, filter_copy );
1048         }
1049     }
1050
1051     /* Add the job to the list */
1052     hb_list_add( h->jobs, job_copy );
1053     h->job_count = hb_count(h);
1054     h->job_count_permanent++;
1055 }
1056
1057 /**
1058  * Removes a job from the job list.
1059  * @param h Handle to hb_handle_t.
1060  * @param job Handle to hb_job_t.
1061  */
1062 void hb_rem( hb_handle_t * h, hb_job_t * job )
1063 {
1064     hb_list_rem( h->jobs, job );
1065
1066     h->job_count = hb_count(h);
1067     if (h->job_count_permanent)
1068         h->job_count_permanent--;
1069
1070     /* XXX free everything XXX */
1071 }
1072
1073 /**
1074  * Starts the conversion process.
1075  * Sets state to HB_STATE_WORKING.
1076  * calls hb_work_init, to launch work thread. Stores handle to work thread.
1077  * @param h Handle to hb_handle_t.
1078  */
1079 void hb_start( hb_handle_t * h )
1080 {
1081     /* XXX Hack */
1082     h->job_count = hb_list_count( h->jobs );
1083     h->job_count_permanent = h->job_count;
1084
1085     hb_lock( h->state_lock );
1086     h->state.state = HB_STATE_WORKING;
1087 #define p h->state.param.working
1088     p.progress  = 0.0;
1089     p.job_cur   = 1;
1090     p.job_count = h->job_count;
1091     p.rate_cur  = 0.0;
1092     p.rate_avg  = 0.0;
1093     p.hours     = -1;
1094     p.minutes   = -1;
1095     p.seconds   = -1;
1096     p.sequence_id = 0;
1097 #undef p
1098     hb_unlock( h->state_lock );
1099
1100     h->paused = 0;
1101
1102     h->work_die    = 0;
1103     h->work_thread = hb_work_init( h->jobs, h->cpu_count,
1104                                    &h->work_die, &h->work_error, &h->current_job );
1105 }
1106
1107 /**
1108  * Pauses the conversion process.
1109  * @param h Handle to hb_handle_t.
1110  */
1111 void hb_pause( hb_handle_t * h )
1112 {
1113     if( !h->paused )
1114     {
1115         hb_lock( h->pause_lock );
1116         h->paused = 1;
1117
1118         hb_lock( h->state_lock );
1119         h->state.state = HB_STATE_PAUSED;
1120         hb_unlock( h->state_lock );
1121     }
1122 }
1123
1124 /**
1125  * Resumes the conversion process.
1126  * @param h Handle to hb_handle_t.
1127  */
1128 void hb_resume( hb_handle_t * h )
1129 {
1130     if( h->paused )
1131     {
1132         hb_unlock( h->pause_lock );
1133         h->paused = 0;
1134     }
1135 }
1136
1137 /**
1138  * Stops the conversion process.
1139  * @param h Handle to hb_handle_t.
1140  */
1141 void hb_stop( hb_handle_t * h )
1142 {
1143     h->work_die = 1;
1144
1145     h->job_count = hb_count(h);
1146     h->job_count_permanent = 0;
1147
1148     hb_resume( h );
1149 }
1150
1151 /**
1152  * Returns the state of the conversion process.
1153  * @param h Handle to hb_handle_t.
1154  * @param s Handle to hb_state_t which to copy the state data.
1155  */
1156 void hb_get_state( hb_handle_t * h, hb_state_t * s )
1157 {
1158     hb_lock( h->state_lock );
1159
1160     memcpy( s, &h->state, sizeof( hb_state_t ) );
1161     if ( h->state.state == HB_STATE_SCANDONE || h->state.state == HB_STATE_WORKDONE )
1162         h->state.state = HB_STATE_IDLE;
1163
1164     hb_unlock( h->state_lock );
1165 }
1166
1167 void hb_get_state2( hb_handle_t * h, hb_state_t * s )
1168 {
1169     hb_lock( h->state_lock );
1170
1171     memcpy( s, &h->state, sizeof( hb_state_t ) );
1172
1173     hb_unlock( h->state_lock );
1174 }
1175
1176 /**
1177  * Called in MacGui in UpdateUI to check
1178  *  for a new scan being completed to set a new source
1179  */
1180 int hb_get_scancount( hb_handle_t * h)
1181  {
1182      return h->scanCount;
1183  }
1184
1185 /**
1186  * Closes access to libhb by freeing the hb_handle_t handle ontained in hb_init_real.
1187  * @param _h Pointer to handle to hb_handle_t.
1188  */
1189 void hb_close( hb_handle_t ** _h )
1190 {
1191     hb_handle_t * h = *_h;
1192     hb_title_t * title;
1193
1194     h->die = 1;
1195     hb_thread_close( &h->main_thread );
1196
1197     while( ( title = hb_list_item( h->list_title, 0 ) ) )
1198     {
1199         hb_list_rem( h->list_title, title );
1200         if( title->job && title->job->filters )
1201         {
1202             hb_list_close( &title->job->filters );
1203         }
1204         free( title->job );
1205         hb_title_close( &title );
1206     }
1207     hb_list_close( &h->list_title );
1208
1209     hb_list_close( &h->jobs );
1210     hb_lock_close( &h->state_lock );
1211     hb_lock_close( &h->pause_lock );
1212     free( h );
1213     *_h = NULL;
1214
1215 }
1216
1217 /**
1218  * Monitors the state of the update, scan, and work threads.
1219  * Sets scan done state when scan thread exits.
1220  * Sets work done state when work thread exits.
1221  * @param _h Handle to hb_handle_t
1222  */
1223 static void thread_func( void * _h )
1224 {
1225     hb_handle_t * h = (hb_handle_t *) _h;
1226     char dirname[1024];
1227     DIR * dir;
1228     struct dirent * entry;
1229
1230     h->pid = getpid();
1231
1232     /* Create folder for temporary files */
1233     memset( dirname, 0, 1024 );
1234     hb_get_tempory_directory( h, dirname );
1235
1236     hb_mkdir( dirname );
1237
1238     while( !h->die )
1239     {
1240         /* In case the check_update thread hangs, it'll die sooner or
1241            later. Then, we join it here */
1242         if( h->update_thread &&
1243             hb_thread_has_exited( h->update_thread ) )
1244         {
1245             hb_thread_close( &h->update_thread );
1246         }
1247
1248         /* Check if the scan thread is done */
1249         if( h->scan_thread &&
1250             hb_thread_has_exited( h->scan_thread ) )
1251         {
1252             hb_thread_close( &h->scan_thread );
1253
1254             hb_log( "libhb: scan thread found %d valid title(s)",
1255                     hb_list_count( h->list_title ) );
1256             hb_lock( h->state_lock );
1257             h->state.state = HB_STATE_SCANDONE; //originally state.state
1258                         hb_unlock( h->state_lock );
1259                         /*we increment this sessions scan count by one for the MacGui
1260                         to trigger a new source being set */
1261             h->scanCount++;
1262         }
1263
1264         /* Check if the work thread is done */
1265         if( h->work_thread &&
1266             hb_thread_has_exited( h->work_thread ) )
1267         {
1268             hb_thread_close( &h->work_thread );
1269
1270             hb_log( "libhb: work result = %d",
1271                     h->work_error );
1272             hb_lock( h->state_lock );
1273             h->state.state                = HB_STATE_WORKDONE;
1274             h->state.param.workdone.error = h->work_error;
1275
1276             h->job_count = hb_count(h);
1277             if (h->job_count < 1)
1278                 h->job_count_permanent = 0;
1279             hb_unlock( h->state_lock );
1280         }
1281
1282         hb_snooze( 50 );
1283     }
1284
1285     if( h->work_thread )
1286     {
1287         hb_stop( h );
1288         hb_thread_close( &h->work_thread );
1289     }
1290
1291     /* Remove temp folder */
1292     dir = opendir( dirname );
1293     if (dir)
1294     {
1295         while( ( entry = readdir( dir ) ) )
1296         {
1297             char filename[1024];
1298             if( entry->d_name[0] == '.' )
1299             {
1300                 continue;
1301             }
1302             memset( filename, 0, 1024 );
1303             snprintf( filename, 1023, "%s/%s", dirname, entry->d_name );
1304             unlink( filename );
1305         }
1306         closedir( dir );
1307         rmdir( dirname );
1308     }
1309 }
1310
1311 /**
1312  * Returns the PID.
1313  * @param h Handle to hb_handle_t
1314  */
1315 int hb_get_pid( hb_handle_t * h )
1316 {
1317     return h->pid;
1318 }
1319
1320 /**
1321  * Sets the current state.
1322  * @param h Handle to hb_handle_t
1323  * @param s Handle to new hb_state_t
1324  */
1325 void hb_set_state( hb_handle_t * h, hb_state_t * s )
1326 {
1327     hb_lock( h->pause_lock );
1328     hb_lock( h->state_lock );
1329     memcpy( &h->state, s, sizeof( hb_state_t ) );
1330     if( h->state.state == HB_STATE_WORKING )
1331     {
1332         /* XXX Hack */
1333         if (h->job_count < 1)
1334             h->job_count_permanent = 1;
1335
1336         h->state.param.working.job_cur =
1337             h->job_count_permanent - hb_list_count( h->jobs );
1338         h->state.param.working.job_count = h->job_count_permanent;
1339
1340         // Set which job is being worked on
1341         if (h->current_job)
1342             h->state.param.working.sequence_id = h->current_job->sequence_id;
1343         else
1344             h->state.param.working.sequence_id = 0;
1345     }
1346     hb_unlock( h->state_lock );
1347     hb_unlock( h->pause_lock );
1348 }