OSDN Git Service

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