OSDN Git Service

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