OSDN Git Service

Add ac3 encoding
[handbrake-jp/handbrake-jp-git.git] / libhb / hb.c
1 #include "hb.h"
2 #include "hbffmpeg.h"
3 #include <stdio.h>
4 #include <unistd.h>
5 #include <fcntl.h>
6
7 #if defined( SYS_MINGW )
8 #include <io.h>
9 #if defined( PTW32_STATIC_LIB )
10 #include <pthread.h>
11 #endif
12 #endif
13
14 struct hb_handle_s
15 {
16     int            id;
17     
18     /* The "Check for update" thread */
19     int            build;
20     char           version[32];
21     hb_thread_t  * update_thread;
22
23     /* This thread's only purpose is to check other threads'
24        states */
25     volatile int   die;
26     hb_thread_t  * main_thread;
27     int            pid;
28
29     /* DVD/file scan thread */
30     hb_list_t    * list_title;
31     hb_thread_t  * scan_thread;
32
33     /* The thread which processes the jobs. Others threads are launched
34        from this one (see work.c) */
35     hb_list_t    * jobs;
36     hb_job_t     * current_job;
37     int            job_count;
38     int            job_count_permanent;
39     volatile int   work_die;
40     int            work_error;
41     hb_thread_t  * work_thread;
42
43     int            cpu_count;
44
45     hb_lock_t    * state_lock;
46     hb_state_t     state;
47
48     int            paused;
49     hb_lock_t    * pause_lock;
50     /* For MacGui active queue
51        increments each time the scan thread completes*/
52     int            scanCount;
53     volatile int   scan_die;
54     
55     /* Stash of persistent data between jobs, for stuff
56        like correcting frame count and framerate estimates
57        on multi-pass encodes where frames get dropped.     */
58     hb_interjob_t * interjob;
59
60 };
61
62 hb_lock_t *hb_avcodec_lock;
63 hb_work_object_t * hb_objects = NULL;
64 int hb_instance_counter = 0;
65 int hb_process_initialized = 0;
66
67 static void thread_func( void * );
68 hb_title_t * hb_get_title_by_index( hb_handle_t *, int );
69
70 void hb_avcodec_init()
71 {
72     hb_avcodec_lock  = hb_lock_init();
73     av_register_all();
74 }
75
76 int hb_avcodec_open(AVCodecContext *avctx, AVCodec *codec)
77 {
78     int ret;
79     hb_lock( hb_avcodec_lock );
80     ret = avcodec_open(avctx, codec);
81     hb_unlock( hb_avcodec_lock );
82     return ret;
83 }
84
85 int hb_av_find_stream_info(AVFormatContext *ic)
86 {
87     int ret;
88     hb_lock( hb_avcodec_lock );
89     ret = av_find_stream_info( ic );
90     hb_unlock( hb_avcodec_lock );
91     return ret;
92 }
93
94 int hb_avcodec_close(AVCodecContext *avctx)
95 {
96     int ret;
97     hb_lock( hb_avcodec_lock );
98     ret = avcodec_close(avctx);
99     hb_unlock( hb_avcodec_lock );
100     return ret;
101 }
102
103 int hb_ff_layout_xlat(int64_t ff_channel_layout, int channels)
104 {
105     int hb_layout;
106
107     switch (ff_channel_layout)
108     {
109         case CH_LAYOUT_MONO:
110             hb_layout = HB_INPUT_CH_LAYOUT_MONO;
111             break;
112         case CH_LAYOUT_STEREO:
113             hb_layout = HB_INPUT_CH_LAYOUT_STEREO;
114             break;
115         case CH_LAYOUT_SURROUND:
116             hb_layout = HB_INPUT_CH_LAYOUT_3F;
117             break;
118         case CH_LAYOUT_4POINT0:
119             hb_layout = HB_INPUT_CH_LAYOUT_3F1R;
120             break;
121         case CH_LAYOUT_2_2:
122             hb_layout = HB_INPUT_CH_LAYOUT_2F2R;
123             break;
124         case CH_LAYOUT_QUAD:
125             hb_layout = HB_INPUT_CH_LAYOUT_2F2R;
126             break;
127         case CH_LAYOUT_5POINT0:
128             hb_layout = HB_INPUT_CH_LAYOUT_3F2R;
129             break;
130         case CH_LAYOUT_5POINT1:
131             hb_layout = HB_INPUT_CH_LAYOUT_3F2R|HB_INPUT_CH_LAYOUT_HAS_LFE;
132             break;
133         case CH_LAYOUT_5POINT0_BACK:
134             hb_layout = HB_INPUT_CH_LAYOUT_3F2R;
135             break;
136         case CH_LAYOUT_5POINT1_BACK:
137             hb_layout = HB_INPUT_CH_LAYOUT_3F2R|HB_INPUT_CH_LAYOUT_HAS_LFE;
138             break;
139         case CH_LAYOUT_7POINT0:
140             hb_layout = HB_INPUT_CH_LAYOUT_3F4R;
141             break;
142         case CH_LAYOUT_7POINT1:
143             hb_layout = HB_INPUT_CH_LAYOUT_3F4R|HB_INPUT_CH_LAYOUT_HAS_LFE;
144             break;
145         case CH_LAYOUT_STEREO_DOWNMIX:
146             hb_layout = HB_INPUT_CH_LAYOUT_STEREO;
147             break;
148         default:
149             hb_layout = HB_INPUT_CH_LAYOUT_STEREO;
150             break;
151     }
152     // Now make sure the chosen layout agrees with the number of channels
153     // ffmpeg tells us there are.  It seems ffmpeg is sometimes confused
154     // about this. So we will make a best guess based on the number
155     // of channels.
156     int chans = HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT( hb_layout );
157     if ( chans == channels )
158     {
159         return hb_layout;
160     }
161     hb_log( "Channels reported by ffmpeg (%d) != computed layout channels (%d).", channels, chans );
162     switch (channels)
163     {
164         case 1:
165             hb_layout = HB_INPUT_CH_LAYOUT_MONO;
166             break;
167         case 2:
168             hb_layout = HB_INPUT_CH_LAYOUT_STEREO;
169             break;
170         case 3:
171             hb_layout = HB_INPUT_CH_LAYOUT_3F;
172             break;
173         case 4:
174             hb_layout = HB_INPUT_CH_LAYOUT_3F1R;
175             break;
176         case 5:
177             hb_layout = HB_INPUT_CH_LAYOUT_3F2R;
178             break;
179         case 6:
180             hb_layout = HB_INPUT_CH_LAYOUT_3F2R|HB_INPUT_CH_LAYOUT_HAS_LFE;
181             break;
182         case 7:
183             hb_layout = HB_INPUT_CH_LAYOUT_3F4R;
184             break;
185         case 8:
186             hb_layout = HB_INPUT_CH_LAYOUT_3F4R|HB_INPUT_CH_LAYOUT_HAS_LFE;
187             break;
188         default:
189             hb_log("Unsupported number of audio channels (%d).\n", channels);
190             hb_layout = 0;
191             break;
192     }
193     return hb_layout;
194 }
195
196 /**
197  * Registers work objects, by adding the work object to a liked list.
198  * @param w Handle to hb_work_object_t to register.
199  */
200 void hb_register( hb_work_object_t * w )
201 {
202     w->next    = hb_objects;
203     hb_objects = w;
204 }
205
206 /**
207  * Ensures that the process has been initialized.
208  */
209 static void process_init()
210 {
211     if (!hb_process_initialized)
212     {
213 #if defined( SYS_MINGW ) && defined( PTW32_STATIC_LIB )
214         pthread_win32_process_attach_np();
215 #endif
216
217 #if defined( _WIN32 ) || defined( __MINGW32__ )
218         setvbuf( stdout, NULL, _IONBF, 0 );
219         setvbuf( stderr, NULL, _IONBF, 0 );
220 #endif
221         hb_process_initialized = 1;
222     }
223     
224 }
225
226 void (*hb_log_callback)(const char* message);
227 static void redirect_thread_func(void *);
228
229 #if defined( SYS_MINGW )
230 #define pipe(phandles)  _pipe (phandles, 4096, _O_BINARY)
231 #endif
232
233 /**
234  * Registers the given function as a logger. All logs will be passed to it.
235  * @param log_cb The function to register as a logger.
236  */
237 void hb_register_logger( void (*log_cb)(const char* message) )
238 {
239     process_init();
240
241     hb_log_callback = log_cb;
242     hb_thread_init("ioredirect", redirect_thread_func, NULL, HB_NORMAL_PRIORITY);
243 }
244
245 /**
246  * libhb initialization routine.
247  * @param verbose HB_DEBUG_NONE or HB_DEBUG_ALL.
248  * @param update_check signals libhb to check for updated version from HandBrake website.
249  * @return Handle to hb_handle_t for use on all subsequent calls to libhb.
250  */
251 hb_handle_t * hb_init( int verbose, int update_check )
252 {
253     process_init();
254
255     hb_handle_t * h = calloc( sizeof( hb_handle_t ), 1 );
256     uint64_t      date;
257
258     /* See hb_deep_log() and hb_log() in common.c */
259     global_verbosity_level = verbose;
260     if( verbose )
261         putenv( "HB_DEBUG=1" );
262     
263     h->id = hb_instance_counter++;
264     
265     /* Check for an update on the website if asked to */
266     h->build = -1;
267
268     if( update_check )
269     {
270         hb_log( "hb_init: checking for updates" );
271         date             = hb_get_date();
272         h->update_thread = hb_update_init( &h->build, h->version );
273
274         for( ;; )
275         {
276             if( hb_thread_has_exited( h->update_thread ) )
277             {
278                 /* Immediate success or failure */
279                 hb_thread_close( &h->update_thread );
280                 break;
281             }
282             if( hb_get_date() > date + 1000 )
283             {
284                 /* Still nothing after one second. Connection problem,
285                    let the thread die */
286                 hb_log( "hb_init: connection problem, not waiting for "
287                         "update_thread" );
288                 break;
289             }
290             hb_snooze( 500 );
291         }
292     }
293
294     /*
295      * Initialise buffer pool
296      */
297     hb_buffer_pool_init();
298
299     /* CPU count detection */
300     hb_log( "hb_init: checking cpu count" );
301     h->cpu_count = hb_get_cpu_count();
302
303     h->list_title = hb_list_init();
304     h->jobs       = hb_list_init();
305
306     h->state_lock  = hb_lock_init();
307     h->state.state = HB_STATE_IDLE;
308
309     h->pause_lock = hb_lock_init();
310
311     h->interjob = calloc( sizeof( hb_interjob_t ), 1 );
312
313     /* libavcodec */
314     hb_avcodec_init();
315
316     /* Start library thread */
317     hb_log( "hb_init: starting libhb thread" );
318     h->die         = 0;
319     h->main_thread = hb_thread_init( "libhb", thread_func, h,
320                                      HB_NORMAL_PRIORITY );
321     hb_register( &hb_sync_video );
322     hb_register( &hb_sync_audio );
323         hb_register( &hb_decmpeg2 );
324         hb_register( &hb_decvobsub );
325     hb_register( &hb_encvobsub );
326     hb_register( &hb_deccc608 );
327     hb_register( &hb_decsrtsub );
328     hb_register( &hb_decutf8sub );
329     hb_register( &hb_dectx3gsub );
330     hb_register( &hb_decssasub );
331         hb_register( &hb_render );
332         hb_register( &hb_encavcodec );
333         hb_register( &hb_encx264 );
334     hb_register( &hb_enctheora );
335         hb_register( &hb_deca52 );
336         hb_register( &hb_decdca );
337         hb_register( &hb_decavcodec );
338         hb_register( &hb_decavcodecv );
339         hb_register( &hb_decavcodecvi );
340         hb_register( &hb_decavcodecai );
341         hb_register( &hb_declpcm );
342         hb_register( &hb_encfaac );
343         hb_register( &hb_enclame );
344         hb_register( &hb_encvorbis );
345         hb_register( &hb_muxer );
346 #ifdef __APPLE__
347         hb_register( &hb_encca_aac );
348 #endif
349         hb_register( &hb_encac3 );
350     
351     return h;
352 }
353
354 /**
355  * libhb initialization routine.
356  * This version is to use when calling the dylib, the macro hb_init isn't available from a dylib call!
357  * @param verbose HB_DEBUG_NONE or HB_DEBUG_ALL.
358  * @param update_check signals libhb to check for updated version from HandBrake website.
359  * @return Handle to hb_handle_t for use on all subsequent calls to libhb.
360  */
361 hb_handle_t * hb_init_dl( int verbose, int update_check )
362 {
363     hb_handle_t * h = calloc( sizeof( hb_handle_t ), 1 );
364     uint64_t      date;
365
366     /* See hb_log() in common.c */
367     if( verbose > HB_DEBUG_NONE )
368     {
369         putenv( "HB_DEBUG=1" );
370     }
371
372     h->id = hb_instance_counter++;
373
374     /* Check for an update on the website if asked to */
375     h->build = -1;
376
377     if( update_check )
378     {
379         hb_log( "hb_init: checking for updates" );
380         date             = hb_get_date();
381         h->update_thread = hb_update_init( &h->build, h->version );
382
383         for( ;; )
384         {
385             if( hb_thread_has_exited( h->update_thread ) )
386             {
387                 /* Immediate success or failure */
388                 hb_thread_close( &h->update_thread );
389                 break;
390             }
391             if( hb_get_date() > date + 1000 )
392             {
393                 /* Still nothing after one second. Connection problem,
394                    let the thread die */
395                 hb_log( "hb_init: connection problem, not waiting for "
396                         "update_thread" );
397                 break;
398             }
399             hb_snooze( 500 );
400         }
401     }
402
403     /* CPU count detection */
404     hb_log( "hb_init: checking cpu count" );
405     h->cpu_count = hb_get_cpu_count();
406
407     h->list_title = hb_list_init();
408     h->jobs       = hb_list_init();
409     h->current_job = NULL;
410
411     h->state_lock  = hb_lock_init();
412     h->state.state = HB_STATE_IDLE;
413
414     h->pause_lock = hb_lock_init();
415
416     /* libavcodec */
417     avcodec_init();
418     avcodec_register_all();
419
420     /* Start library thread */
421     hb_log( "hb_init: starting libhb thread" );
422     h->die         = 0;
423     h->main_thread = hb_thread_init( "libhb", thread_func, h,
424                                      HB_NORMAL_PRIORITY );
425
426     hb_register( &hb_sync_video );
427     hb_register( &hb_sync_audio );
428         hb_register( &hb_decmpeg2 );
429         hb_register( &hb_decvobsub );
430     hb_register( &hb_encvobsub );
431     hb_register( &hb_deccc608 );
432     hb_register( &hb_decsrtsub );
433     hb_register( &hb_decutf8sub );
434     hb_register( &hb_dectx3gsub );
435     hb_register( &hb_decssasub );
436         hb_register( &hb_render );
437         hb_register( &hb_encavcodec );
438         hb_register( &hb_encx264 );
439     hb_register( &hb_enctheora );
440         hb_register( &hb_deca52 );
441         hb_register( &hb_decdca );
442         hb_register( &hb_decavcodec );
443         hb_register( &hb_decavcodecv );
444         hb_register( &hb_decavcodecvi );
445         hb_register( &hb_decavcodecai );
446         hb_register( &hb_declpcm );
447         hb_register( &hb_encfaac );
448         hb_register( &hb_enclame );
449         hb_register( &hb_encvorbis );
450         hb_register( &hb_muxer );
451 #ifdef __APPLE__
452         hb_register( &hb_encca_aac );
453 #endif
454         hb_register( &hb_encac3 );
455
456         return h;
457 }
458
459
460 /**
461  * Returns current version of libhb.
462  * @param h Handle to hb_handle_t.
463  * @return character array of version number.
464  */
465 char * hb_get_version( hb_handle_t * h )
466 {
467     return HB_PROJECT_VERSION;
468 }
469
470 /**
471  * Returns current build of libhb.
472  * @param h Handle to hb_handle_t.
473  * @return character array of build number.
474  */
475 int hb_get_build( hb_handle_t * h )
476 {
477     return HB_PROJECT_BUILD;
478 }
479
480 /**
481  * Checks for needed update.
482  * @param h Handle to hb_handle_t.
483  * @param version Pointer to handle where version will be copied.
484  * @return update indicator.
485  */
486 int hb_check_update( hb_handle_t * h, char ** version )
487 {
488     *version = ( h->build < 0 ) ? NULL : h->version;
489     return h->build;
490 }
491
492 /**
493  * Sets the cpu count to the desired value.
494  * @param h Handle to hb_handle_t
495  * @param cpu_count Number of CPUs to use.
496  */
497 void hb_set_cpu_count( hb_handle_t * h, int cpu_count )
498 {
499     cpu_count    = MAX( 1, cpu_count );
500     cpu_count    = MIN( cpu_count, 8 );
501     h->cpu_count = cpu_count;
502 }
503
504 /**
505  * Deletes current previews associated with titles
506  * @param h Handle to hb_handle_t
507  */
508 void hb_remove_previews( hb_handle_t * h )
509 {
510     char            filename[1024];
511     char            dirname[1024];
512     hb_title_t    * title;
513     int             i, count, len;
514     DIR           * dir;
515     struct dirent * entry;
516
517     memset( dirname, 0, 1024 );
518     hb_get_temporary_directory( dirname );
519     dir = opendir( dirname );
520     if (dir == NULL) return;
521
522     count = hb_list_count( h->list_title );
523     while( ( entry = readdir( dir ) ) )
524     {
525         if( entry->d_name[0] == '.' )
526         {
527             continue;
528         }
529         for( i = 0; i < count; i++ )
530         {
531             title = hb_list_item( h->list_title, i );
532             len = snprintf( filename, 1024, "%d_%d", h->id, title->index );
533             if (strncmp(entry->d_name, filename, len) == 0)
534             {
535                 snprintf( filename, 1024, "%s/%s", dirname, entry->d_name );
536                 unlink( filename );
537                 break;
538             }
539         }
540     }
541     closedir( dir );
542 }
543
544 /**
545  * Initializes a scan of the by calling hb_scan_init
546  * @param h Handle to hb_handle_t
547  * @param path location of VIDEO_TS folder.
548  * @param title_index Desired title to scan.  0 for all titles.
549  * @param preview_count Number of preview images to generate.
550  * @param store_previews Whether or not to write previews to disk.
551  */
552 void hb_scan( hb_handle_t * h, const char * path, int title_index,
553               int preview_count, int store_previews, uint64_t min_duration )
554 {
555     hb_title_t * title;
556
557     h->scan_die = 0;
558
559     /* Clean up from previous scan */
560     hb_remove_previews( h );
561     while( ( title = hb_list_item( h->list_title, 0 ) ) )
562     {
563         hb_list_rem( h->list_title, title );
564         hb_title_close( &title );
565     }
566
567     hb_log( "hb_scan: path=%s, title_index=%d", path, title_index );
568     h->scan_thread = hb_scan_init( h, &h->scan_die, path, title_index, 
569                                    h->list_title, preview_count, 
570                                    store_previews, min_duration );
571 }
572
573 /**
574  * Returns the list of titles found.
575  * @param h Handle to hb_handle_t
576  * @return Handle to hb_list_t of the title list.
577  */
578 hb_list_t * hb_get_titles( hb_handle_t * h )
579 {
580     return h->list_title;
581 }
582
583 /**
584  * Create preview image of desired title a index of picture.
585  * @param h Handle to hb_handle_t.
586  * @param title_index Index of the title to get the preview for (1-based).
587  * @param picture Index in title.
588  * @param buffer Handle to buffer were image will be drawn.
589  */
590 void hb_get_preview_by_index( hb_handle_t * h, int title_index, int picture, uint8_t * buffer )
591 {
592     hb_title_t * title;
593
594     title = hb_get_title_by_index( h, title_index );
595     if ( title != NULL )
596     {
597         hb_get_preview( h, title, picture, buffer );
598     } 
599 }
600
601 /**
602  * Create preview image of desired title a index of picture.
603  * @param h Handle to hb_handle_t.
604  * @param title Handle to hb_title_t of desired title.
605  * @param picture Index in title.
606  * @param buffer Handle to buffer were image will be drawn.
607  */
608 void hb_get_preview( hb_handle_t * h, hb_title_t * title, int picture,
609                      uint8_t * buffer )
610 {
611     hb_job_t           * job = title->job;
612     char                 filename[1024];
613     FILE               * file;
614     uint8_t            * buf1, * buf2, * buf3, * buf4, * pen;
615     uint32_t             swsflags;
616     AVPicture            pic_in, pic_preview, pic_deint, pic_crop, pic_scale;
617     struct SwsContext  * context;
618     int                  i;
619     int                  rgb_width = ((job->width + 7) >> 3) << 3;
620     int                  preview_size;
621
622     swsflags = SWS_LANCZOS | SWS_ACCURATE_RND;
623
624     buf1 = av_malloc( avpicture_get_size( PIX_FMT_YUV420P, title->width, title->height ) );
625     buf2 = av_malloc( avpicture_get_size( PIX_FMT_YUV420P, title->width, title->height ) );
626     buf3 = av_malloc( avpicture_get_size( PIX_FMT_YUV420P, rgb_width, job->height ) );
627     buf4 = av_malloc( avpicture_get_size( PIX_FMT_RGB32, rgb_width, job->height ) );
628     avpicture_fill( &pic_in, buf1, PIX_FMT_YUV420P,
629                     title->width, title->height );
630     avpicture_fill( &pic_deint, buf2, PIX_FMT_YUV420P,
631                     title->width, title->height );
632     avpicture_fill( &pic_scale, buf3, PIX_FMT_YUV420P,
633                     rgb_width, job->height );
634     avpicture_fill( &pic_preview, buf4, PIX_FMT_RGB32,
635                     rgb_width, job->height );
636
637     // Allocate the AVPicture frames and fill in
638
639     memset( filename, 0, 1024 );
640
641     hb_get_tempory_filename( h, filename, "%d_%d_%d",
642                              h->id, title->index, picture );
643
644     file = fopen( filename, "rb" );
645     if( !file )
646     {
647         hb_log( "hb_get_preview: fopen failed" );
648         return;
649     }
650
651     fread( buf1, avpicture_get_size( PIX_FMT_YUV420P, title->width, title->height), 1, file );
652     fclose( file );
653
654     if( job->deinterlace )
655     {
656         // Deinterlace and crop
657         avpicture_deinterlace( &pic_deint, &pic_in, PIX_FMT_YUV420P, title->width, title->height );
658         av_picture_crop( &pic_crop, &pic_deint, PIX_FMT_YUV420P, job->crop[0], job->crop[2] );
659     }
660     else
661     {
662         // Crop
663         av_picture_crop( &pic_crop, &pic_in, PIX_FMT_YUV420P, job->crop[0], job->crop[2] );
664     }
665
666     // Get scaling context
667     context = sws_getContext(title->width  - (job->crop[2] + job->crop[3]),
668                              title->height - (job->crop[0] + job->crop[1]),
669                              PIX_FMT_YUV420P,
670                              job->width, job->height, PIX_FMT_YUV420P,
671                              swsflags, NULL, NULL, NULL);
672
673     // Scale
674     sws_scale(context,
675               pic_crop.data, pic_crop.linesize,
676               0, title->height - (job->crop[0] + job->crop[1]),
677               pic_scale.data, pic_scale.linesize);
678
679     // Free context
680     sws_freeContext( context );
681
682     // Get preview context
683     context = sws_getContext(rgb_width, job->height, PIX_FMT_YUV420P,
684                               rgb_width, job->height, PIX_FMT_RGB32,
685                               swsflags, NULL, NULL, NULL);
686
687     // Create preview
688     sws_scale(context,
689               pic_scale.data, pic_scale.linesize,
690               0, job->height,
691               pic_preview.data, pic_preview.linesize);
692
693     // Free context
694     sws_freeContext( context );
695
696     preview_size = pic_preview.linesize[0];
697     pen = buffer;
698     for( i = 0; i < job->height; i++ )
699     {
700         memcpy( pen, buf4 + preview_size * i, 4 * job->width );
701         pen += 4 * job->width;
702     }
703
704     // Clean up
705     avpicture_free( &pic_preview );
706     avpicture_free( &pic_scale );
707     avpicture_free( &pic_deint );
708     avpicture_free( &pic_in );
709 }
710
711  /**
712  * Analyzes a frame to detect interlacing artifacts
713  * and returns true if interlacing (combing) is found.
714  *
715  * Code taken from Thomas Oestreich's 32detect filter
716  * in the Transcode project, with minor formatting changes.
717  *
718  * @param buf         An hb_buffer structure holding valid frame data
719  * @param width       The frame's width in pixels
720  * @param height      The frame's height in pixels
721  * @param color_equal Sensitivity for detecting similar colors
722  * @param color_diff  Sensitivity for detecting different colors
723  * @param threshold   Sensitivity for flagging planes as combed
724  * @param prog_equal  Sensitivity for detecting similar colors on progressive frames
725  * @param prog_diff   Sensitivity for detecting different colors on progressive frames
726  * @param prog_threshold Sensitivity for flagging progressive frames as combed
727  */
728 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 )
729 {
730     int j, k, n, off, cc_1, cc_2, cc[3];
731         // int flag[3] ; // debugging flag
732     uint16_t s1, s2, s3, s4;
733     cc_1 = 0; cc_2 = 0;
734
735     int offset = 0;
736     
737     if ( buf->flags & 16 )
738     {
739         /* Frame is progressive, be more discerning. */
740         color_diff = prog_diff;
741         color_equal = prog_equal;
742         threshold = prog_threshold;
743     }
744
745     /* One pas for Y, one pass for Cb, one pass for Cr */    
746     for( k = 0; k < 3; k++ )
747     {
748         if( k == 1 )
749         {
750             /* Y has already been checked, now offset by Y's dimensions
751                and divide all the other values by 2, since Cr and Cb
752                are half-size compared to Y.                               */
753             offset = width * height;
754             width >>= 1;
755             height >>= 1;
756         }
757         else if ( k == 2 )
758         {
759             /* Y and Cb are done, so the offset needs to be bumped
760                so it's width*height + (width / 2) * (height / 2)  */
761             offset *= 5/4;
762         }
763
764         for( j = 0; j < width; ++j )
765         {
766             off = 0;
767
768             for( n = 0; n < ( height - 4 ); n = n + 2 )
769             {
770                 /* Look at groups of 4 sequential horizontal lines */
771                 s1 = ( ( buf->data + offset )[ off + j             ] & 0xff );
772                 s2 = ( ( buf->data + offset )[ off + j + width     ] & 0xff );
773                 s3 = ( ( buf->data + offset )[ off + j + 2 * width ] & 0xff );
774                 s4 = ( ( buf->data + offset )[ off + j + 3 * width ] & 0xff );
775
776                 /* Note if the 1st and 2nd lines are more different in
777                    color than the 1st and 3rd lines are similar in color.*/
778                 if ( ( abs( s1 - s3 ) < color_equal ) &&
779                      ( abs( s1 - s2 ) > color_diff ) )
780                         ++cc_1;
781
782                 /* Note if the 2nd and 3rd lines are more different in
783                    color than the 2nd and 4th lines are similar in color.*/
784                 if ( ( abs( s2 - s4 ) < color_equal ) &&
785                      ( abs( s2 - s3 ) > color_diff) )
786                         ++cc_2;
787
788                 /* Now move down 2 horizontal lines before starting over.*/
789                 off += 2 * width;
790             }
791         }
792
793         // compare results
794         /*  The final cc score for a plane is the percentage of combed pixels it contains.
795             Because sensitivity goes down to hundreths of a percent, multiply by 1000
796             so it will be easy to compare against the threhold value which is an integer. */
797         cc[k] = (int)( ( cc_1 + cc_2 ) * 1000.0 / ( width * height ) );
798     }
799
800
801     /* HandBrake is all yuv420, so weight the average percentage of all 3 planes accordingly.*/
802     int average_cc = ( 2 * cc[0] + ( cc[1] / 2 ) + ( cc[2] / 2 ) ) / 3;
803     
804     /* Now see if that average percentage of combed pixels surpasses the threshold percentage given by the user.*/
805     if( average_cc > threshold )
806     {
807 #if 0
808             hb_log("Average %i combed (Threshold %i) %i/%i/%i | PTS: %"PRId64" (%fs) %s", average_cc, threshold, cc[0], cc[1], cc[2], buf->start, (float)buf->start / 90000, (buf->flags & 16) ? "Film" : "Video" );
809 #endif
810         return 1;
811     }
812
813 #if 0
814     hb_log("SKIPPED Average %i combed (Threshold %i) %i/%i/%i | PTS: %"PRId64" (%fs) %s", average_cc, threshold, cc[0], cc[1], cc[2], buf->start, (float)buf->start / 90000, (buf->flags & 16) ? "Film" : "Video" );
815 #endif
816
817     /* Reaching this point means no combing detected. */
818     return 0;
819
820 }
821
822 /**
823  * Calculates job width and height for anamorphic content,
824  *
825  * @param h Instance handle
826  * @param title_index Index of the title/job to inspect (1-based).
827  * @param output_width Pointer to returned storage width
828  * @param output_height Pointer to returned storage height
829  * @param output_par_width Pointer to returned pixel width
830  * @param output_par_height Pointer to returned pixel height
831  */
832 void hb_set_anamorphic_size_by_index( hb_handle_t * h, int title_index,
833         int *output_width, int *output_height,
834         int *output_par_width, int *output_par_height )
835 {
836     hb_title_t * title;
837     title = hb_get_title_by_index( h, title_index );
838     
839     hb_set_anamorphic_size( title->job, output_width, output_height, output_par_width, output_par_height );
840 }
841
842 /**
843  * Calculates job width and height for anamorphic content,
844  *
845  * @param job Handle to hb_job_t
846  * @param output_width Pointer to returned storage width
847  * @param output_height Pointer to returned storage height
848  * @param output_par_width Pointer to returned pixel width
849  * @param output_par_height Pointer to returned pixel height
850  */
851 void hb_set_anamorphic_size( hb_job_t * job,
852         int *output_width, int *output_height,
853         int *output_par_width, int *output_par_height )
854 {
855     /* Set up some variables to make the math easier to follow. */
856     hb_title_t * title = job->title;
857     int cropped_width = title->width - job->crop[2] - job->crop[3] ;
858     int cropped_height = title->height - job->crop[0] - job->crop[1] ;
859     double storage_aspect = (double)cropped_width / (double)cropped_height;
860     int mod = job->modulus ? job->modulus : 16;
861     double aspect = title->aspect;
862     
863     int pixel_aspect_width  = job->anamorphic.par_width;
864     int pixel_aspect_height = job->anamorphic.par_height;
865
866     /* If a source was really NTSC or PAL and the user specified ITU PAR
867        values, replace the standard PAR values with the ITU broadcast ones. */
868     if( title->width == 720 && job->anamorphic.itu_par )
869     {
870         // convert aspect to a scaled integer so we can test for 16:9 & 4:3
871         // aspect ratios ignoring insignificant differences in the LSBs of
872         // the floating point representation.
873         int iaspect = aspect * 9.;
874
875         /* Handle ITU PARs */
876         if (title->height == 480)
877         {
878             /* It's NTSC */
879             if (iaspect == 16)
880             {
881                 /* It's widescreen */
882                 pixel_aspect_width = 40;
883                 pixel_aspect_height = 33;
884             }
885             else if (iaspect == 12)
886             {
887                 /* It's 4:3 */
888                 pixel_aspect_width = 10;
889                 pixel_aspect_height = 11;
890             }
891         }
892         else if (title->height == 576)
893         {
894             /* It's PAL */
895             if(iaspect == 16)
896             {
897                 /* It's widescreen */
898                 pixel_aspect_width = 16;
899                 pixel_aspect_height = 11;
900             }
901             else if (iaspect == 12)
902             {
903                 /* It's 4:3 */
904                 pixel_aspect_width = 12;
905                 pixel_aspect_height = 11;
906             }
907         }
908     }
909
910     /* Figure out what width the source would display at. */
911     int source_display_width = cropped_width * (double)pixel_aspect_width /
912                                (double)pixel_aspect_height ;
913
914     /*
915        3 different ways of deciding output dimensions:
916         - 1: Strict anamorphic, preserve source dimensions
917         - 2: Loose anamorphic, round to mod16 and preserve storage aspect ratio
918         - 3: Power user anamorphic, specify everything
919     */
920     int width, height;
921     int maxWidth, maxHeight;
922
923     maxWidth = MULTIPLE_MOD_DOWN( job->maxWidth, mod );
924     maxHeight = MULTIPLE_MOD_DOWN( job->maxHeight, mod );
925
926     switch( job->anamorphic.mode )
927     {
928         case 1:
929             /* Strict anamorphic */
930             *output_width = cropped_width;
931             *output_height = cropped_height;
932             *output_par_width = title->pixel_aspect_width;
933             *output_par_height = title->pixel_aspect_height;
934         break;
935
936         case 2:
937             /* "Loose" anamorphic.
938                 - Uses mod16-compliant dimensions,
939                 - Allows users to set the width
940             */
941             width = job->width;
942             // height: Gets set later, ignore user job->height value
943
944             /* Gotta handle bounding dimensions.
945                If the width is too big, just reset it with no rescaling.
946                Instead of using the aspect-scaled job height,
947                we need to see if the job width divided by the storage aspect
948                is bigger than the max. If so, set it to the max (this is sloppy).
949                If not, set job height to job width divided by storage aspect.
950             */
951
952             /* Time to get picture width that divide cleanly.*/
953             width  = MULTIPLE_MOD( width, mod);
954
955             if ( maxWidth && (maxWidth < job->width) )
956                 width = maxWidth;
957
958             /* Verify these new dimensions don't violate max height and width settings */
959             height = ((double)width / storage_aspect) + 0.5;
960
961             /* Time to get picture height that divide cleanly.*/
962             height = MULTIPLE_MOD( height, mod);
963             
964             if ( maxHeight && (maxHeight < height) )
965             {
966                 height = maxHeight;
967                 width = ((double)height * storage_aspect) + 0.5;
968                 width  = MULTIPLE_MOD( width, mod);
969             }
970
971             /* The film AR is the source's display width / cropped source height.
972                The output display width is the output height * film AR.
973                The output PAR is the output display width / output storage width. */
974             pixel_aspect_width = height * source_display_width / cropped_height;
975             pixel_aspect_height = width;
976
977             /* Pass the results back to the caller */
978             *output_width = width;
979             *output_height = height;
980         break;
981             
982         case 3:
983             /* Anamorphic 3: Power User Jamboree
984                - Set everything based on specified values */
985             
986             /* Use specified storage dimensions */
987             storage_aspect = (double)job->width / (double)job->height;
988             width = job->width;
989             height = job->height;
990             
991             /* Time to get picture dimensions that divide cleanly.*/
992             width  = MULTIPLE_MOD( width, mod);
993             height = MULTIPLE_MOD( height, mod);
994             
995             /* Bind to max dimensions */
996             if( maxWidth && width > maxWidth )
997             {
998                 width = maxWidth;
999                 // If we are keeping the display aspect, then we are going
1000                 // to be modifying the PAR anyway.  So it's preferred
1001                 // to let the width/height stray some from the original
1002                 // requested storage aspect.
1003                 //
1004                 // But otherwise, PAR and DAR will change the least
1005                 // if we stay as close as possible to the requested
1006                 // storage aspect.
1007                 if ( !job->anamorphic.keep_display_aspect )
1008                 {
1009                     height = ((double)width / storage_aspect) + 0.5;
1010                     height = MULTIPLE_MOD( height, mod);
1011                 }
1012             }
1013             if( maxHeight && height > maxHeight )
1014             {
1015                 height = maxHeight;
1016                 // Ditto, see comment above
1017                 if ( !job->anamorphic.keep_display_aspect )
1018                 {
1019                     width = ((double)height * storage_aspect) + 0.5;
1020                     width  = MULTIPLE_MOD( width, mod);
1021                 }
1022             }
1023             
1024             /* That finishes the storage dimensions. On to display. */            
1025             if( job->anamorphic.dar_width && job->anamorphic.dar_height )
1026             {
1027                 /* We need to adjust the PAR to produce this aspect. */
1028                 pixel_aspect_width = height * job->anamorphic.dar_width / job->anamorphic.dar_height;
1029                 pixel_aspect_height = width;
1030             }
1031             else
1032             {
1033                 /* If we're doing ana 3 and not specifying a DAR, care needs to be taken.
1034                    This indicates a PAR is potentially being set by the interface. But
1035                    this is an output PAR, to correct a source, and it should not be assumed
1036                    that it properly creates a display aspect ratio when applied to the source,
1037                    which could easily be stored in a different resolution. */
1038                 if( job->anamorphic.keep_display_aspect )
1039                 {
1040                     /* We can ignore the possibility of a PAR change */
1041                     pixel_aspect_width = height * ( (double)source_display_width / (double)cropped_height );
1042                     pixel_aspect_height = width;
1043                 }
1044                 else
1045                 {
1046                     int output_display_width = width * (double)pixel_aspect_width /
1047                         (double)pixel_aspect_height;
1048                     pixel_aspect_width = output_display_width;
1049                     pixel_aspect_height = width;
1050                 }
1051             }
1052             
1053             /* Back to caller */
1054             *output_width = width;
1055             *output_height = height;
1056         break;
1057     }
1058     
1059     /* While x264 is smart enough to reduce fractions on its own, libavcodec
1060        needs some help with the math, so lose superfluous factors.            */
1061     hb_reduce( output_par_width, output_par_height,
1062                pixel_aspect_width, pixel_aspect_height );
1063 }
1064
1065 /**
1066  * Calculates job width, height, and cropping parameters.
1067  * @param job Handle to hb_job_t.
1068  * @param aspect Desired aspect ratio. Value of -1 uses title aspect.
1069  * @param pixels Maximum desired pixel count.
1070  */
1071 void hb_set_size( hb_job_t * job, double aspect, int pixels )
1072 {
1073     hb_title_t * title = job->title;
1074
1075     int croppedWidth  = title->width - title->crop[2] - title->crop[3];
1076     int croppedHeight = title->height - title->crop[0] - title->crop[1];
1077     double croppedAspect = title->aspect * title->height * croppedWidth /
1078                            croppedHeight / title->width;
1079     int addCrop;
1080     int i, w, h;
1081
1082     if( aspect <= 0 )
1083     {
1084         /* Keep the best possible aspect ratio */
1085         aspect = croppedAspect;
1086     }
1087
1088     /* Crop if necessary to obtain the desired ratio */
1089     memcpy( job->crop, title->crop, 4 * sizeof( int ) );
1090     if( aspect < croppedAspect )
1091     {
1092         /* Need to crop on the left and right */
1093         addCrop = croppedWidth - aspect * croppedHeight * title->width /
1094                     title->aspect / title->height;
1095         if( addCrop & 3 )
1096         {
1097             addCrop = ( addCrop + 1 ) / 2;
1098             job->crop[2] += addCrop;
1099             job->crop[3] += addCrop;
1100         }
1101         else if( addCrop & 2 )
1102         {
1103             addCrop /= 2;
1104             job->crop[2] += addCrop - 1;
1105             job->crop[3] += addCrop + 1;
1106         }
1107         else
1108         {
1109             addCrop /= 2;
1110             job->crop[2] += addCrop;
1111             job->crop[3] += addCrop;
1112         }
1113     }
1114     else if( aspect > croppedAspect )
1115     {
1116         /* Need to crop on the top and bottom */
1117         addCrop = croppedHeight - croppedWidth * title->aspect *
1118             title->height / aspect / title->width;
1119         if( addCrop & 3 )
1120         {
1121             addCrop = ( addCrop + 1 ) / 2;
1122             job->crop[0] += addCrop;
1123             job->crop[1] += addCrop;
1124         }
1125         else if( addCrop & 2 )
1126         {
1127             addCrop /= 2;
1128             job->crop[0] += addCrop - 1;
1129             job->crop[1] += addCrop + 1;
1130         }
1131         else
1132         {
1133             addCrop /= 2;
1134             job->crop[0] += addCrop;
1135             job->crop[1] += addCrop;
1136         }
1137     }
1138
1139     /* Compute a resolution from the number of pixels and aspect */
1140     for( i = 0;; i++ )
1141     {
1142         w = 16 * i;
1143         h = MULTIPLE_16( (int)( (double)w / aspect ) );
1144         if( w * h > pixels )
1145         {
1146             break;
1147         }
1148     }
1149     i--;
1150     job->width  = 16 * i;
1151     job->height = MULTIPLE_16( (int)( (double)job->width / aspect ) );
1152 }
1153
1154 /**
1155  * Returns the number of jobs in the queue.
1156  * @param h Handle to hb_handle_t.
1157  * @return Number of jobs.
1158  */
1159 int hb_count( hb_handle_t * h )
1160 {
1161     return hb_list_count( h->jobs );
1162 }
1163
1164 /**
1165  * Returns handle to job at index i within the job list.
1166  * @param h Handle to hb_handle_t.
1167  * @param i Index of job.
1168  * @returns Handle to hb_job_t of desired job.
1169  */
1170 hb_job_t * hb_job( hb_handle_t * h, int i )
1171 {
1172     return hb_list_item( h->jobs, i );
1173 }
1174
1175 hb_job_t * hb_current_job( hb_handle_t * h )
1176 {
1177     return( h->current_job );
1178 }
1179
1180 /**
1181  * Applies information from the given job to the official job instance.
1182  * @param h Handle to hb_handle_t.
1183  * @param title_index Index of the title to apply the chapter name to (1-based).
1184  * @param chapter The chapter to apply the name to (1-based).
1185  * @param job Job information to apply.
1186  */
1187 void hb_set_chapter_name( hb_handle_t * h, int title_index, int chapter_index, const char * chapter_name )
1188 {
1189     hb_title_t * title;
1190     title = hb_get_title_by_index( h, title_index );
1191     
1192     hb_chapter_t * chapter = hb_list_item( title->list_chapter, chapter_index - 1 );
1193     
1194     strncpy(chapter->title, chapter_name, 1023);
1195     chapter->title[1023] = '\0';
1196 }
1197
1198 /**
1199  * Applies information from the given job to the official job instance.
1200  * Currently only applies information needed for anamorphic size calculation and previews.
1201  * @param h Handle to hb_handle_t.
1202  * @param title_index Index of the title to apply the job information to (1-based).
1203  * @param job Job information to apply.
1204  */
1205 void hb_set_job( hb_handle_t * h, int title_index, hb_job_t * job )
1206 {
1207         int i;
1208
1209     hb_title_t * title;
1210     title = hb_get_title_by_index( h, title_index );
1211     
1212     hb_job_t * job_target = title->job;
1213     
1214     job_target->deinterlace = job->deinterlace;
1215     job_target->width = job->width;
1216     job_target->height = job->height;
1217     job_target->maxWidth = job->maxWidth;
1218     job_target->maxHeight = job->maxHeight;
1219     for (i = 0; i < 4; i++)
1220     {
1221         job_target->crop[i] = job->crop[i];
1222     }
1223         
1224     job_target->anamorphic = job->anamorphic;
1225 }
1226
1227 /**
1228  * Adds a job to the job list.
1229  * @param h Handle to hb_handle_t.
1230  * @param job Handle to hb_job_t.
1231  */
1232 void hb_add( hb_handle_t * h, hb_job_t * job )
1233 {
1234     hb_job_t      * job_copy;
1235     hb_title_t    * title,    * title_copy;
1236     hb_chapter_t  * chapter,  * chapter_copy;
1237     hb_audio_t    * audio;
1238     hb_subtitle_t * subtitle, * subtitle_copy;
1239     hb_attachment_t * attachment;
1240     int             i;
1241     char            audio_lang[4];
1242
1243     /* Copy the title */
1244     title      = job->title;
1245     title_copy = malloc( sizeof( hb_title_t ) );
1246     memcpy( title_copy, title, sizeof( hb_title_t ) );
1247
1248     title_copy->list_chapter = hb_list_init();
1249     for( i = 0; i < hb_list_count( title->list_chapter ); i++ )
1250     {
1251         chapter      = hb_list_item( title->list_chapter, i );
1252         chapter_copy = malloc( sizeof( hb_chapter_t ) );
1253         memcpy( chapter_copy, chapter, sizeof( hb_chapter_t ) );
1254         hb_list_add( title_copy->list_chapter, chapter_copy );
1255     }
1256
1257     /*
1258      * Copy the metadata
1259      */
1260     if( title->metadata )
1261     {
1262         title_copy->metadata = malloc( sizeof( hb_metadata_t ) );
1263         
1264         if( title_copy->metadata ) 
1265         {
1266             memcpy( title_copy->metadata, title->metadata, sizeof( hb_metadata_t ) );
1267
1268             /*
1269              * Need to copy the artwork seperatly (TODO).
1270              */
1271             if( title->metadata->coverart )
1272             {
1273                 title_copy->metadata->coverart = malloc( title->metadata->coverart_size );
1274                 if( title_copy->metadata->coverart )
1275                 {
1276                     memcpy( title_copy->metadata->coverart, title->metadata->coverart,
1277                             title->metadata->coverart_size );
1278                 } else {
1279                     title_copy->metadata->coverart_size = 0; 
1280                 }
1281             }
1282         }
1283     }
1284
1285     /* Copy the audio track(s) we want */
1286     title_copy->list_audio = hb_list_init();
1287     for( i = 0; i < hb_list_count(job->list_audio); i++ )
1288     {
1289         if( ( audio = hb_list_item( job->list_audio, i ) ) )
1290         {
1291             hb_list_add( title_copy->list_audio, hb_audio_copy(audio) );
1292         }
1293     }
1294
1295     /* Initialize subtitle list - filled out further below */
1296     title_copy->list_subtitle = hb_list_init();
1297     
1298     /* Copy all the attachments */
1299     title_copy->list_attachment = hb_list_init();
1300     for( i = 0; i < hb_list_count(title->list_attachment); i++ )
1301     {
1302         if( ( attachment = hb_list_item( title->list_attachment, i ) ) )
1303         {
1304             hb_list_add( title_copy->list_attachment, hb_attachment_copy(attachment) );
1305         }
1306     }
1307
1308     /*
1309      * The following code is confusing, there are two ways in which
1310      * we select subtitles and it depends on whether this is single or
1311      * two pass mode.
1312      *
1313      * subtitle_scan may be enabled, in which case the first pass
1314      * scans all subtitles of that language. The second pass does not
1315      * select any because they are set at the end of the first pass.
1316      *
1317      * We may have manually selected a subtitle, in which case that is
1318      * selected in the first pass of a single pass, or the second of a
1319      * two pass.
1320      */
1321     memset( audio_lang, 0, sizeof( audio_lang ) );
1322
1323     if ( job->indepth_scan ) {
1324
1325         /*
1326          * Find the first audio language that is being encoded
1327          */
1328         for( i = 0; i < hb_list_count(job->list_audio); i++ )
1329         {
1330             if( ( audio = hb_list_item( job->list_audio, i ) ) )
1331             {
1332                 strncpy(audio_lang, audio->config.lang.iso639_2, sizeof(audio_lang));
1333                 break;
1334             }
1335         }
1336     }
1337
1338     /*
1339      * If doing a subtitle scan then add all the matching subtitles for this
1340      * language.
1341      */
1342     if ( job->indepth_scan )
1343     {
1344         for( i=0; i < hb_list_count( title->list_subtitle ); i++ )
1345         {
1346             subtitle = hb_list_item( title->list_subtitle, i );
1347             if( strcmp( subtitle->iso639_2, audio_lang ) == 0 &&
1348                 subtitle->source == VOBSUB )
1349             {
1350                 /*
1351                  * Matched subtitle language with audio language, so
1352                  * add this to our list to scan.
1353                  *
1354                  * We will update the subtitle list on the second pass
1355                  * later after the first pass has completed.
1356                  */
1357                 subtitle_copy = malloc( sizeof( hb_subtitle_t ) );
1358                 memcpy( subtitle_copy, subtitle, sizeof( hb_subtitle_t ) );
1359                 hb_list_add( title_copy->list_subtitle, subtitle_copy );
1360             }
1361         }
1362     } else {
1363         /*
1364          * Not doing a subtitle scan in this pass, but maybe we are in the
1365          * first pass?
1366          */
1367         if( job->pass != 1 )
1368         {
1369             /*
1370              * Copy all of them from the input job, to the title_copy/job_copy.
1371              */
1372             for(  i = 0; i < hb_list_count(job->list_subtitle); i++ ) {
1373                 if( ( subtitle = hb_list_item( job->list_subtitle, i ) ) )
1374                 {
1375                     subtitle_copy = malloc( sizeof( hb_subtitle_t ) );
1376                     memcpy( subtitle_copy, subtitle, sizeof( hb_subtitle_t ) );
1377                     hb_list_add( title_copy->list_subtitle, subtitle_copy );
1378                 }
1379             }
1380         }
1381     }
1382
1383     /* Copy the job */
1384     job_copy        = calloc( sizeof( hb_job_t ), 1 );
1385     memcpy( job_copy, job, sizeof( hb_job_t ) );
1386     title_copy->job = job_copy;
1387     job_copy->title = title_copy;
1388     job_copy->list_audio = title_copy->list_audio;
1389     job_copy->list_subtitle = title_copy->list_subtitle;   // sharing list between title and job
1390     job_copy->file  = strdup( job->file );
1391     job_copy->h     = h;
1392     job_copy->pause = h->pause_lock;
1393
1394     /* Copy the job filter list */
1395     if( job->filters )
1396     {
1397         int i;
1398         int filter_count = hb_list_count( job->filters );
1399         job_copy->filters = hb_list_init();
1400         for( i = 0; i < filter_count; i++ )
1401         {
1402             /*
1403              * Copy the filters, since the MacGui reuses the global filter objects
1404              * meaning that queued up jobs overwrite the previous filter settings.
1405              * In reality, settings is probably the only field that needs duplicating
1406              * since it's the only value that is ever changed. But name is duplicated
1407              * as well for completeness. Not copying private_data since it gets
1408              * created for each job in renderInit.
1409              */
1410             hb_filter_object_t * filter = hb_list_item( job->filters, i );
1411             hb_filter_object_t * filter_copy = malloc( sizeof( hb_filter_object_t ) );
1412             memcpy( filter_copy, filter, sizeof( hb_filter_object_t ) );
1413             if( filter->name )
1414                 filter_copy->name = strdup( filter->name );
1415             if( filter->settings )
1416                 filter_copy->settings = strdup( filter->settings );
1417             hb_list_add( job_copy->filters, filter_copy );
1418         }
1419     }
1420
1421     /* Add the job to the list */
1422     hb_list_add( h->jobs, job_copy );
1423     h->job_count = hb_count(h);
1424     h->job_count_permanent++;
1425 }
1426
1427 /**
1428  * Removes a job from the job list.
1429  * @param h Handle to hb_handle_t.
1430  * @param job Handle to hb_job_t.
1431  */
1432 void hb_rem( hb_handle_t * h, hb_job_t * job )
1433 {
1434     hb_list_rem( h->jobs, job );
1435
1436     h->job_count = hb_count(h);
1437     if (h->job_count_permanent)
1438         h->job_count_permanent--;
1439
1440     /* XXX free everything XXX */
1441 }
1442
1443 /**
1444  * Starts the conversion process.
1445  * Sets state to HB_STATE_WORKING.
1446  * calls hb_work_init, to launch work thread. Stores handle to work thread.
1447  * @param h Handle to hb_handle_t.
1448  */
1449 void hb_start( hb_handle_t * h )
1450 {
1451     /* XXX Hack */
1452     h->job_count = hb_list_count( h->jobs );
1453     h->job_count_permanent = h->job_count;
1454
1455     hb_lock( h->state_lock );
1456     h->state.state = HB_STATE_WORKING;
1457 #define p h->state.param.working
1458     p.progress  = 0.0;
1459     p.job_cur   = 1;
1460     p.job_count = h->job_count;
1461     p.rate_cur  = 0.0;
1462     p.rate_avg  = 0.0;
1463     p.hours     = -1;
1464     p.minutes   = -1;
1465     p.seconds   = -1;
1466     p.sequence_id = 0;
1467 #undef p
1468     hb_unlock( h->state_lock );
1469
1470     h->paused = 0;
1471
1472     h->work_die    = 0;
1473     h->work_thread = hb_work_init( h->jobs, h->cpu_count,
1474                                    &h->work_die, &h->work_error, &h->current_job );
1475 }
1476
1477 /**
1478  * Pauses the conversion process.
1479  * @param h Handle to hb_handle_t.
1480  */
1481 void hb_pause( hb_handle_t * h )
1482 {
1483     if( !h->paused )
1484     {
1485         hb_lock( h->pause_lock );
1486         h->paused = 1;
1487
1488         hb_current_job( h )->st_pause_date = hb_get_date();
1489
1490         hb_lock( h->state_lock );
1491         h->state.state = HB_STATE_PAUSED;
1492         hb_unlock( h->state_lock );
1493     }
1494 }
1495
1496 /**
1497  * Resumes the conversion process.
1498  * @param h Handle to hb_handle_t.
1499  */
1500 void hb_resume( hb_handle_t * h )
1501 {
1502     if( h->paused )
1503     {
1504 #define job hb_current_job( h )
1505         if( job->st_pause_date != -1 )
1506         {
1507            job->st_paused += hb_get_date() - job->st_pause_date;
1508         }
1509 #undef job
1510
1511         hb_unlock( h->pause_lock );
1512         h->paused = 0;
1513     }
1514 }
1515
1516 /**
1517  * Stops the conversion process.
1518  * @param h Handle to hb_handle_t.
1519  */
1520 void hb_stop( hb_handle_t * h )
1521 {
1522     h->work_die = 1;
1523
1524     h->job_count = hb_count(h);
1525     h->job_count_permanent = 0;
1526
1527     hb_resume( h );
1528 }
1529
1530 /**
1531  * Stops the conversion process.
1532  * @param h Handle to hb_handle_t.
1533  */
1534 void hb_scan_stop( hb_handle_t * h )
1535 {
1536     h->scan_die = 1;
1537
1538     h->job_count = hb_count(h);
1539     h->job_count_permanent = 0;
1540
1541     hb_resume( h );
1542 }
1543
1544 /**
1545  * Gets a filter object with the given type and settings.
1546  * @param filter_id The type of filter to get.
1547  * @param settings The filter settings to use.
1548  * @returns The requested filter object.
1549  */
1550 hb_filter_object_t * hb_get_filter_object(int filter_id, const char * settings)
1551 {
1552     if (filter_id == HB_FILTER_ROTATE)
1553     {
1554         hb_filter_rotate.settings = (char*)settings;
1555         return &hb_filter_rotate;
1556     }
1557
1558     if (filter_id == HB_FILTER_DETELECINE)
1559     {
1560         hb_filter_detelecine.settings = (char*)settings;
1561         return &hb_filter_detelecine;
1562     }
1563
1564     if (filter_id == HB_FILTER_DECOMB)
1565     {
1566         hb_filter_decomb.settings = (char*)settings;
1567         return &hb_filter_decomb;
1568     }
1569
1570     if (filter_id == HB_FILTER_DEINTERLACE)
1571     {
1572         hb_filter_deinterlace.settings = (char*)settings;
1573         return &hb_filter_deinterlace;
1574     }
1575
1576     if (filter_id == HB_FILTER_DEBLOCK)
1577     {
1578         hb_filter_deblock.settings = (char*)settings;
1579         return &hb_filter_deblock;
1580     }
1581
1582     if (filter_id == HB_FILTER_DENOISE)
1583     {
1584         hb_filter_denoise.settings = (char*)settings;
1585         return &hb_filter_denoise;
1586     }
1587     return NULL;
1588 }
1589
1590 /**
1591  * Returns the state of the conversion process.
1592  * @param h Handle to hb_handle_t.
1593  * @param s Handle to hb_state_t which to copy the state data.
1594  */
1595 void hb_get_state( hb_handle_t * h, hb_state_t * s )
1596 {
1597     hb_lock( h->state_lock );
1598
1599     memcpy( s, &h->state, sizeof( hb_state_t ) );
1600     if ( h->state.state == HB_STATE_SCANDONE || h->state.state == HB_STATE_WORKDONE )
1601         h->state.state = HB_STATE_IDLE;
1602
1603     hb_unlock( h->state_lock );
1604 }
1605
1606 void hb_get_state2( hb_handle_t * h, hb_state_t * s )
1607 {
1608     hb_lock( h->state_lock );
1609
1610     memcpy( s, &h->state, sizeof( hb_state_t ) );
1611
1612     hb_unlock( h->state_lock );
1613 }
1614
1615 /**
1616  * Called in MacGui in UpdateUI to check
1617  *  for a new scan being completed to set a new source
1618  */
1619 int hb_get_scancount( hb_handle_t * h)
1620  {
1621      return h->scanCount;
1622  }
1623
1624 /**
1625  * Closes access to libhb by freeing the hb_handle_t handle ontained in hb_init.
1626  * @param _h Pointer to handle to hb_handle_t.
1627  */
1628 void hb_close( hb_handle_t ** _h )
1629 {
1630     hb_handle_t * h = *_h;
1631     hb_title_t * title;
1632
1633     h->die = 1;
1634     
1635     hb_thread_close( &h->main_thread );
1636
1637     while( ( title = hb_list_item( h->list_title, 0 ) ) )
1638     {
1639         hb_list_rem( h->list_title, title );
1640         if( title->job && title->job->filters )
1641         {
1642             hb_list_close( &title->job->filters );
1643         }
1644         free( title->job );
1645         hb_title_close( &title );
1646     }
1647     hb_list_close( &h->list_title );
1648
1649     hb_list_close( &h->jobs );
1650     hb_lock_close( &h->state_lock );
1651     hb_lock_close( &h->pause_lock );
1652
1653     free( h );
1654     *_h = NULL;
1655 }
1656
1657 /**
1658  * Cleans up libhb at a process level. Call before the app closes. Removes preview directory.
1659  */
1660 void hb_global_close()
1661 {
1662     char dirname[1024];
1663     DIR * dir;
1664     struct dirent * entry;
1665     
1666     /* Find and remove temp folder */
1667     memset( dirname, 0, 1024 );
1668     hb_get_temporary_directory( dirname );
1669
1670     dir = opendir( dirname );
1671     if (dir)
1672     {
1673         while( ( entry = readdir( dir ) ) )
1674         {
1675             char filename[1024];
1676             if( entry->d_name[0] == '.' )
1677             {
1678                 continue;
1679             }
1680             memset( filename, 0, 1024 );
1681             snprintf( filename, 1023, "%s/%s", dirname, entry->d_name );
1682             unlink( filename );
1683         }
1684         closedir( dir );
1685         rmdir( dirname );
1686     }
1687 }
1688
1689 /**
1690  * Monitors the state of the update, scan, and work threads.
1691  * Sets scan done state when scan thread exits.
1692  * Sets work done state when work thread exits.
1693  * @param _h Handle to hb_handle_t
1694  */
1695 static void thread_func( void * _h )
1696 {
1697     hb_handle_t * h = (hb_handle_t *) _h;
1698     char dirname[1024];
1699
1700     h->pid = getpid();
1701
1702     /* Create folder for temporary files */
1703     memset( dirname, 0, 1024 );
1704     hb_get_temporary_directory( dirname );
1705
1706     hb_mkdir( dirname );
1707
1708     while( !h->die )
1709     {
1710         /* In case the check_update thread hangs, it'll die sooner or
1711            later. Then, we join it here */
1712         if( h->update_thread &&
1713             hb_thread_has_exited( h->update_thread ) )
1714         {
1715             hb_thread_close( &h->update_thread );
1716         }
1717
1718         /* Check if the scan thread is done */
1719         if( h->scan_thread &&
1720             hb_thread_has_exited( h->scan_thread ) )
1721         {
1722             hb_thread_close( &h->scan_thread );
1723
1724             if ( h->scan_die )
1725             {
1726                 hb_title_t * title;
1727
1728                 hb_remove_previews( h );
1729                 while( ( title = hb_list_item( h->list_title, 0 ) ) )
1730                 {
1731                     hb_list_rem( h->list_title, title );
1732                     hb_title_close( &title );
1733                 }
1734
1735                 hb_log( "hb_scan: canceled" );
1736             }
1737             else
1738             {
1739                 hb_log( "libhb: scan thread found %d valid title(s)",
1740                         hb_list_count( h->list_title ) );
1741             }
1742             hb_lock( h->state_lock );
1743             h->state.state = HB_STATE_SCANDONE; //originally state.state
1744                         hb_unlock( h->state_lock );
1745                         /*we increment this sessions scan count by one for the MacGui
1746                         to trigger a new source being set */
1747             h->scanCount++;
1748         }
1749
1750         /* Check if the work thread is done */
1751         if( h->work_thread &&
1752             hb_thread_has_exited( h->work_thread ) )
1753         {
1754             hb_thread_close( &h->work_thread );
1755
1756             hb_log( "libhb: work result = %d",
1757                     h->work_error );
1758             hb_lock( h->state_lock );
1759             h->state.state                = HB_STATE_WORKDONE;
1760             h->state.param.workdone.error = h->work_error;
1761
1762             h->job_count = hb_count(h);
1763             if (h->job_count < 1)
1764                 h->job_count_permanent = 0;
1765             hb_unlock( h->state_lock );
1766         }
1767
1768         hb_snooze( 50 );
1769     }
1770
1771     if( h->scan_thread )
1772     {
1773         hb_scan_stop( h );
1774         hb_thread_close( &h->scan_thread );
1775     }
1776     if( h->work_thread )
1777     {
1778         hb_stop( h );
1779         hb_thread_close( &h->work_thread );
1780     }
1781     hb_remove_previews( h );
1782 }
1783
1784 /**
1785  * Redirects stderr to the registered callback
1786  * function.
1787  * @param _data Unused.
1788  */
1789 static void redirect_thread_func(void * _data)
1790 {
1791     int pfd[2];
1792     pipe(pfd);
1793 #if defined( SYS_MINGW )
1794     // dup2 doesn't work on windows for some stupid reason
1795     stderr->_file = pfd[1];
1796 #else
1797     dup2(pfd[1], /*stderr*/ 2);
1798 #endif
1799     FILE * log_f = fdopen(pfd[0], "rb");
1800     
1801     char line_buffer[500];
1802     while(fgets(line_buffer, 500, log_f) != NULL)
1803     {
1804         hb_log_callback(line_buffer);
1805     }
1806 }
1807
1808 /**
1809  * Returns the PID.
1810  * @param h Handle to hb_handle_t
1811  */
1812 int hb_get_pid( hb_handle_t * h )
1813 {
1814     return h->pid;
1815 }
1816
1817 /**
1818  * Returns the id for the given instance.
1819  * @param h Handle to hb_handle_t
1820  * @returns The ID for the given instance
1821  */
1822 int hb_get_instance_id( hb_handle_t * h )
1823 {
1824     return h->id;
1825 }
1826
1827 /**
1828  * Returns the title with the given title index.
1829  * @param h Handle to hb_handle_t
1830  * @param title_index the index of the title to get
1831  * @returns The requested title
1832  */
1833 hb_title_t * hb_get_title_by_index( hb_handle_t * h, int title_index )
1834 {
1835     hb_title_t * title;
1836     int i;
1837         int count = hb_list_count( h->list_title );
1838     for (i = 0; i < count; i++)
1839     {
1840         title = hb_list_item( h->list_title, i );
1841         if (title->index == title_index)
1842         {
1843             return title;
1844         }
1845     }
1846     
1847     return NULL;
1848 }
1849
1850 /**
1851  * Sets the current state.
1852  * @param h Handle to hb_handle_t
1853  * @param s Handle to new hb_state_t
1854  */
1855 void hb_set_state( hb_handle_t * h, hb_state_t * s )
1856 {
1857     hb_lock( h->pause_lock );
1858     hb_lock( h->state_lock );
1859     memcpy( &h->state, s, sizeof( hb_state_t ) );
1860     if( h->state.state == HB_STATE_WORKING ||
1861         h->state.state == HB_STATE_SEARCHING )
1862     {
1863         /* XXX Hack */
1864         if (h->job_count < 1)
1865             h->job_count_permanent = 1;
1866
1867         h->state.param.working.job_cur =
1868             h->job_count_permanent - hb_list_count( h->jobs );
1869         h->state.param.working.job_count = h->job_count_permanent;
1870
1871         // Set which job is being worked on
1872         if (h->current_job)
1873             h->state.param.working.sequence_id = h->current_job->sequence_id;
1874         else
1875             h->state.param.working.sequence_id = 0;
1876     }
1877     hb_unlock( h->state_lock );
1878     hb_unlock( h->pause_lock );
1879 }
1880
1881 /* Passes a pointer to persistent data */
1882 hb_interjob_t * hb_interjob_get( hb_handle_t * h )
1883 {
1884     return h->interjob;
1885 }