4 #if defined( SYS_MINGW ) && defined( PTW32_STATIC_LIB )
12 /* The "Check for update" thread */
15 hb_thread_t * update_thread;
17 /* This thread's only purpose is to check other threads'
20 hb_thread_t * main_thread;
23 /* DVD/file scan thread */
24 hb_list_t * list_title;
25 hb_thread_t * scan_thread;
27 /* The thread which processes the jobs. Others threads are launched
28 from this one (see work.c) */
30 hb_job_t * current_job;
32 int job_count_permanent;
33 volatile int work_die;
35 hb_thread_t * work_thread;
39 hb_lock_t * state_lock;
43 hb_lock_t * pause_lock;
44 /* For MacGui active queue
45 increments each time the scan thread completes*/
47 volatile int scan_die;
49 /* Stash of persistent data between jobs, for stuff
50 like correcting frame count and framerate estimates
51 on multi-pass encodes where frames get dropped. */
52 hb_interjob_t * interjob;
56 hb_lock_t *hb_avcodec_lock;
57 hb_work_object_t * hb_objects = NULL;
58 int hb_instance_counter = 0;
59 int hb_process_initialized = 0;
61 static void thread_func( void * );
63 void hb_avcodec_init()
65 hb_avcodec_lock = hb_lock_init();
69 int hb_avcodec_open(AVCodecContext *avctx, AVCodec *codec)
72 hb_lock( hb_avcodec_lock );
73 ret = avcodec_open(avctx, codec);
74 hb_unlock( hb_avcodec_lock );
78 int hb_avcodec_close(AVCodecContext *avctx)
81 hb_lock( hb_avcodec_lock );
82 ret = avcodec_close(avctx);
83 hb_unlock( hb_avcodec_lock );
87 int hb_ff_layout_xlat(int64_t ff_channel_layout, int channels)
91 switch (ff_channel_layout)
94 hb_layout = HB_INPUT_CH_LAYOUT_MONO;
96 case CH_LAYOUT_STEREO:
97 hb_layout = HB_INPUT_CH_LAYOUT_STEREO;
99 case CH_LAYOUT_SURROUND:
100 hb_layout = HB_INPUT_CH_LAYOUT_3F;
102 case CH_LAYOUT_4POINT0:
103 hb_layout = HB_INPUT_CH_LAYOUT_3F1R;
106 hb_layout = HB_INPUT_CH_LAYOUT_2F2R;
109 hb_layout = HB_INPUT_CH_LAYOUT_2F2R;
111 case CH_LAYOUT_5POINT0:
112 hb_layout = HB_INPUT_CH_LAYOUT_3F2R;
114 case CH_LAYOUT_5POINT1:
115 hb_layout = HB_INPUT_CH_LAYOUT_3F2R|HB_INPUT_CH_LAYOUT_HAS_LFE;
117 case CH_LAYOUT_5POINT0_BACK:
118 hb_layout = HB_INPUT_CH_LAYOUT_3F2R;
120 case CH_LAYOUT_5POINT1_BACK:
121 hb_layout = HB_INPUT_CH_LAYOUT_3F2R|HB_INPUT_CH_LAYOUT_HAS_LFE;
123 case CH_LAYOUT_7POINT0:
124 hb_layout = HB_INPUT_CH_LAYOUT_3F4R;
126 case CH_LAYOUT_7POINT1:
127 hb_layout = HB_INPUT_CH_LAYOUT_3F4R|HB_INPUT_CH_LAYOUT_HAS_LFE;
129 case CH_LAYOUT_STEREO_DOWNMIX:
130 hb_layout = HB_INPUT_CH_LAYOUT_STEREO;
133 hb_layout = HB_INPUT_CH_LAYOUT_STEREO;
136 // Now make sure the chosen layout agrees with the number of channels
137 // ffmpeg tells us there are. It seems ffmpeg is sometimes confused
138 // about this. So we will make a best guess based on the number
140 int chans = HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT( hb_layout );
141 if ( chans == channels )
145 hb_log( "Channels reported by ffmpeg (%d) != computed layout channels (%d).\n", channels, chans );
149 hb_layout = HB_INPUT_CH_LAYOUT_MONO;
152 hb_layout = HB_INPUT_CH_LAYOUT_STEREO;
155 hb_layout = HB_INPUT_CH_LAYOUT_3F;
158 hb_layout = HB_INPUT_CH_LAYOUT_3F1R;
161 hb_layout = HB_INPUT_CH_LAYOUT_3F2R;
164 hb_layout = HB_INPUT_CH_LAYOUT_3F2R|HB_INPUT_CH_LAYOUT_HAS_LFE;
167 hb_layout = HB_INPUT_CH_LAYOUT_3F4R;
170 hb_layout = HB_INPUT_CH_LAYOUT_3F4R|HB_INPUT_CH_LAYOUT_HAS_LFE;
173 hb_log("Unsupported number of audio channels (%d).\n", channels);
181 * Registers work objects, by adding the work object to a liked list.
182 * @param w Handle to hb_work_object_t to register.
184 void hb_register( hb_work_object_t * w )
186 w->next = hb_objects;
191 * libhb initialization routine.
192 * @param verbose HB_DEBUG_NONE or HB_DEBUG_ALL.
193 * @param update_check signals libhb to check for updated version from HandBrake website.
194 * @return Handle to hb_handle_t for use on all subsequent calls to libhb.
196 hb_handle_t * hb_init( int verbose, int update_check )
198 if (!hb_process_initialized)
200 #if defined( SYS_MINGW ) && defined( PTW32_STATIC_LIB )
201 pthread_win32_process_attach_np();
203 hb_process_initialized =1;
206 hb_handle_t * h = calloc( sizeof( hb_handle_t ), 1 );
209 /* See hb_deep_log() and hb_log() in common.c */
210 global_verbosity_level = verbose;
212 putenv( "HB_DEBUG=1" );
214 h->id = hb_instance_counter++;
216 /* Check for an update on the website if asked to */
221 hb_log( "hb_init: checking for updates" );
222 date = hb_get_date();
223 h->update_thread = hb_update_init( &h->build, h->version );
227 if( hb_thread_has_exited( h->update_thread ) )
229 /* Immediate success or failure */
230 hb_thread_close( &h->update_thread );
233 if( hb_get_date() > date + 1000 )
235 /* Still nothing after one second. Connection problem,
236 let the thread die */
237 hb_log( "hb_init: connection problem, not waiting for "
246 * Initialise buffer pool
248 hb_buffer_pool_init();
250 /* CPU count detection */
251 hb_log( "hb_init: checking cpu count" );
252 h->cpu_count = hb_get_cpu_count();
254 h->list_title = hb_list_init();
255 h->jobs = hb_list_init();
257 h->state_lock = hb_lock_init();
258 h->state.state = HB_STATE_IDLE;
260 h->pause_lock = hb_lock_init();
262 h->interjob = calloc( sizeof( hb_interjob_t ), 1 );
267 /* Start library thread */
268 hb_log( "hb_init: starting libhb thread" );
270 h->main_thread = hb_thread_init( "libhb", thread_func, h,
271 HB_NORMAL_PRIORITY );
272 hb_register( &hb_sync_video );
273 hb_register( &hb_sync_audio );
274 hb_register( &hb_decmpeg2 );
275 hb_register( &hb_decvobsub );
276 hb_register( &hb_encvobsub );
277 hb_register( &hb_deccc608 );
278 hb_register( &hb_decsrtsub );
279 hb_register( &hb_render );
280 hb_register( &hb_encavcodec );
281 hb_register( &hb_encx264 );
282 hb_register( &hb_enctheora );
283 hb_register( &hb_deca52 );
284 hb_register( &hb_decdca );
285 hb_register( &hb_decavcodec );
286 hb_register( &hb_decavcodecv );
287 hb_register( &hb_decavcodecvi );
288 hb_register( &hb_decavcodecai );
289 hb_register( &hb_declpcm );
290 hb_register( &hb_encfaac );
291 hb_register( &hb_enclame );
292 hb_register( &hb_encvorbis );
293 hb_register( &hb_muxer );
295 hb_register( &hb_encca_aac );
302 * libhb initialization routine.
303 * This version is to use when calling the dylib, the macro hb_init isn't available from a dylib call!
304 * @param verbose HB_DEBUG_NONE or HB_DEBUG_ALL.
305 * @param update_check signals libhb to check for updated version from HandBrake website.
306 * @return Handle to hb_handle_t for use on all subsequent calls to libhb.
308 hb_handle_t * hb_init_dl( int verbose, int update_check )
310 hb_handle_t * h = calloc( sizeof( hb_handle_t ), 1 );
313 /* See hb_log() in common.c */
314 if( verbose > HB_DEBUG_NONE )
316 putenv( "HB_DEBUG=1" );
319 h->id = hb_instance_counter++;
321 /* Check for an update on the website if asked to */
326 hb_log( "hb_init: checking for updates" );
327 date = hb_get_date();
328 h->update_thread = hb_update_init( &h->build, h->version );
332 if( hb_thread_has_exited( h->update_thread ) )
334 /* Immediate success or failure */
335 hb_thread_close( &h->update_thread );
338 if( hb_get_date() > date + 1000 )
340 /* Still nothing after one second. Connection problem,
341 let the thread die */
342 hb_log( "hb_init: connection problem, not waiting for "
350 /* CPU count detection */
351 hb_log( "hb_init: checking cpu count" );
352 h->cpu_count = hb_get_cpu_count();
354 h->list_title = hb_list_init();
355 h->jobs = hb_list_init();
356 h->current_job = NULL;
358 h->state_lock = hb_lock_init();
359 h->state.state = HB_STATE_IDLE;
361 h->pause_lock = hb_lock_init();
365 avcodec_register_all();
367 /* Start library thread */
368 hb_log( "hb_init: starting libhb thread" );
370 h->main_thread = hb_thread_init( "libhb", thread_func, h,
371 HB_NORMAL_PRIORITY );
373 hb_register( &hb_sync_video );
374 hb_register( &hb_sync_audio );
375 hb_register( &hb_decmpeg2 );
376 hb_register( &hb_decvobsub );
377 hb_register( &hb_encvobsub );
378 hb_register( &hb_deccc608 );
379 hb_register( &hb_decsrtsub );
380 hb_register( &hb_render );
381 hb_register( &hb_encavcodec );
382 hb_register( &hb_encx264 );
383 hb_register( &hb_enctheora );
384 hb_register( &hb_deca52 );
385 hb_register( &hb_decdca );
386 hb_register( &hb_decavcodec );
387 hb_register( &hb_decavcodecv );
388 hb_register( &hb_decavcodecvi );
389 hb_register( &hb_decavcodecai );
390 hb_register( &hb_declpcm );
391 hb_register( &hb_encfaac );
392 hb_register( &hb_enclame );
393 hb_register( &hb_encvorbis );
394 hb_register( &hb_muxer );
396 hb_register( &hb_encca_aac );
404 * Returns current version of libhb.
405 * @param h Handle to hb_handle_t.
406 * @return character array of version number.
408 char * hb_get_version( hb_handle_t * h )
410 return HB_PROJECT_VERSION;
414 * Returns current build of libhb.
415 * @param h Handle to hb_handle_t.
416 * @return character array of build number.
418 int hb_get_build( hb_handle_t * h )
420 return HB_PROJECT_BUILD;
424 * Checks for needed update.
425 * @param h Handle to hb_handle_t.
426 * @param version Pointer to handle where version will be copied.
427 * @return update indicator.
429 int hb_check_update( hb_handle_t * h, char ** version )
431 *version = ( h->build < 0 ) ? NULL : h->version;
436 * Sets the cpu count to the desired value.
437 * @param h Handle to hb_handle_t
438 * @param cpu_count Number of CPUs to use.
440 void hb_set_cpu_count( hb_handle_t * h, int cpu_count )
442 cpu_count = MAX( 1, cpu_count );
443 cpu_count = MIN( cpu_count, 8 );
444 h->cpu_count = cpu_count;
448 * Deletes current previews associated with titles
449 * @param h Handle to hb_handle_t
451 void hb_remove_previews( hb_handle_t * h )
458 struct dirent * entry;
460 memset( dirname, 0, 1024 );
461 hb_get_temporary_directory( dirname );
462 dir = opendir( dirname );
463 if (dir == NULL) return;
465 count = hb_list_count( h->list_title );
466 while( ( entry = readdir( dir ) ) )
468 if( entry->d_name[0] == '.' )
472 for( i = 0; i < count; i++ )
474 title = hb_list_item( h->list_title, i );
475 len = snprintf( filename, 1024, "%d_%d", h->id, title->index );
476 if (strncmp(entry->d_name, filename, len) == 0)
478 snprintf( filename, 1024, "%s/%s", dirname, entry->d_name );
488 * Initializes a scan of the by calling hb_scan_init
489 * @param h Handle to hb_handle_t
490 * @param path location of VIDEO_TS folder.
491 * @param title_index Desired title to scan. 0 for all titles.
492 * @param preview_count Number of preview images to generate.
493 * @param store_previews Whether or not to write previews to disk.
495 void hb_scan( hb_handle_t * h, const char * path, int title_index,
496 int preview_count, int store_previews )
502 /* Clean up from previous scan */
503 hb_remove_previews( h );
504 while( ( title = hb_list_item( h->list_title, 0 ) ) )
506 hb_list_rem( h->list_title, title );
507 hb_title_close( &title );
510 hb_log( "hb_scan: path=%s, title_index=%d", path, title_index );
511 h->scan_thread = hb_scan_init( h, &h->scan_die, path, title_index,
512 h->list_title, preview_count,
517 * Returns the list of titles found.
518 * @param h Handle to hb_handle_t
519 * @return Handle to hb_list_t of the title list.
521 hb_list_t * hb_get_titles( hb_handle_t * h )
523 return h->list_title;
527 * Create preview image of desired title a index of picture.
528 * @param h Handle to hb_handle_t.
529 * @param title Handle to hb_title_t of desired title.
530 * @param picture Index in title.
531 * @param buffer Handle to buufer were inage will be drawn.
533 void hb_get_preview( hb_handle_t * h, hb_title_t * title, int picture,
536 hb_job_t * job = title->job;
539 uint8_t * buf1, * buf2, * buf3, * buf4, * pen;
541 AVPicture pic_in, pic_preview, pic_deint, pic_crop, pic_scale;
542 struct SwsContext * context;
544 int rgb_width = ((job->width + 7) >> 3) << 3;
547 swsflags = SWS_LANCZOS | SWS_ACCURATE_RND;
549 buf1 = av_malloc( avpicture_get_size( PIX_FMT_YUV420P, title->width, title->height ) );
550 buf2 = av_malloc( avpicture_get_size( PIX_FMT_YUV420P, title->width, title->height ) );
551 buf3 = av_malloc( avpicture_get_size( PIX_FMT_YUV420P, rgb_width, job->height ) );
552 buf4 = av_malloc( avpicture_get_size( PIX_FMT_RGB32, rgb_width, job->height ) );
553 avpicture_fill( &pic_in, buf1, PIX_FMT_YUV420P,
554 title->width, title->height );
555 avpicture_fill( &pic_deint, buf2, PIX_FMT_YUV420P,
556 title->width, title->height );
557 avpicture_fill( &pic_scale, buf3, PIX_FMT_YUV420P,
558 rgb_width, job->height );
559 avpicture_fill( &pic_preview, buf4, PIX_FMT_RGB32,
560 rgb_width, job->height );
562 // Allocate the AVPicture frames and fill in
564 memset( filename, 0, 1024 );
566 hb_get_tempory_filename( h, filename, "%d_%d_%d",
567 h->id, title->index, picture );
569 file = fopen( filename, "rb" );
572 hb_log( "hb_get_preview: fopen failed" );
576 fread( buf1, avpicture_get_size( PIX_FMT_YUV420P, title->width, title->height), 1, file );
579 if( job->deinterlace )
581 // Deinterlace and crop
582 avpicture_deinterlace( &pic_deint, &pic_in, PIX_FMT_YUV420P, title->width, title->height );
583 av_picture_crop( &pic_crop, &pic_deint, PIX_FMT_YUV420P, job->crop[0], job->crop[2] );
588 av_picture_crop( &pic_crop, &pic_in, PIX_FMT_YUV420P, job->crop[0], job->crop[2] );
591 // Get scaling context
592 context = sws_getContext(title->width - (job->crop[2] + job->crop[3]),
593 title->height - (job->crop[0] + job->crop[1]),
595 job->width, job->height, PIX_FMT_YUV420P,
596 swsflags, NULL, NULL, NULL);
600 pic_crop.data, pic_crop.linesize,
601 0, title->height - (job->crop[0] + job->crop[1]),
602 pic_scale.data, pic_scale.linesize);
605 sws_freeContext( context );
607 // Get preview context
608 context = sws_getContext(rgb_width, job->height, PIX_FMT_YUV420P,
609 rgb_width, job->height, PIX_FMT_RGB32,
610 swsflags, NULL, NULL, NULL);
614 pic_scale.data, pic_scale.linesize,
616 pic_preview.data, pic_preview.linesize);
619 sws_freeContext( context );
621 preview_size = pic_preview.linesize[0];
623 for( i = 0; i < job->height; i++ )
625 memcpy( pen, buf4 + preview_size * i, 4 * job->width );
626 pen += 4 * job->width;
630 avpicture_free( &pic_preview );
631 avpicture_free( &pic_scale );
632 avpicture_free( &pic_deint );
633 avpicture_free( &pic_in );
637 * Analyzes a frame to detect interlacing artifacts
638 * and returns true if interlacing (combing) is found.
640 * Code taken from Thomas Oestreich's 32detect filter
641 * in the Transcode project, with minor formatting changes.
643 * @param buf An hb_buffer structure holding valid frame data
644 * @param width The frame's width in pixels
645 * @param height The frame's height in pixels
646 * @param color_equal Sensitivity for detecting similar colors
647 * @param color_diff Sensitivity for detecting different colors
648 * @param threshold Sensitivity for flagging planes as combed
649 * @param prog_equal Sensitivity for detecting similar colors on progressive frames
650 * @param prog_diff Sensitivity for detecting different colors on progressive frames
651 * @param prog_threshold Sensitivity for flagging progressive frames as combed
653 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 )
655 int j, k, n, off, cc_1, cc_2, cc[3];
656 // int flag[3] ; // debugging flag
657 uint16_t s1, s2, s3, s4;
662 if ( buf->flags & 16 )
664 /* Frame is progressive, be more discerning. */
665 color_diff = prog_diff;
666 color_equal = prog_equal;
667 threshold = prog_threshold;
670 /* One pas for Y, one pass for Cb, one pass for Cr */
671 for( k = 0; k < 3; k++ )
675 /* Y has already been checked, now offset by Y's dimensions
676 and divide all the other values by 2, since Cr and Cb
677 are half-size compared to Y. */
678 offset = width * height;
684 /* Y and Cb are done, so the offset needs to be bumped
685 so it's width*height + (width / 2) * (height / 2) */
689 for( j = 0; j < width; ++j )
693 for( n = 0; n < ( height - 4 ); n = n + 2 )
695 /* Look at groups of 4 sequential horizontal lines */
696 s1 = ( ( buf->data + offset )[ off + j ] & 0xff );
697 s2 = ( ( buf->data + offset )[ off + j + width ] & 0xff );
698 s3 = ( ( buf->data + offset )[ off + j + 2 * width ] & 0xff );
699 s4 = ( ( buf->data + offset )[ off + j + 3 * width ] & 0xff );
701 /* Note if the 1st and 2nd lines are more different in
702 color than the 1st and 3rd lines are similar in color.*/
703 if ( ( abs( s1 - s3 ) < color_equal ) &&
704 ( abs( s1 - s2 ) > color_diff ) )
707 /* Note if the 2nd and 3rd lines are more different in
708 color than the 2nd and 4th lines are similar in color.*/
709 if ( ( abs( s2 - s4 ) < color_equal ) &&
710 ( abs( s2 - s3 ) > color_diff) )
713 /* Now move down 2 horizontal lines before starting over.*/
719 /* The final cc score for a plane is the percentage of combed pixels it contains.
720 Because sensitivity goes down to hundreths of a percent, multiply by 1000
721 so it will be easy to compare against the threhold value which is an integer. */
722 cc[k] = (int)( ( cc_1 + cc_2 ) * 1000.0 / ( width * height ) );
726 /* HandBrake is all yuv420, so weight the average percentage of all 3 planes accordingly.*/
727 int average_cc = ( 2 * cc[0] + ( cc[1] / 2 ) + ( cc[2] / 2 ) ) / 3;
729 /* Now see if that average percentage of combed pixels surpasses the threshold percentage given by the user.*/
730 if( average_cc > threshold )
733 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" );
739 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" );
742 /* Reaching this point means no combing detected. */
748 * Calculates job width and height for anamorphic content,
750 * @param job Handle to hb_job_t
751 * @param output_width Pointer to returned storage width
752 * @param output_height Pointer to returned storage height
753 * @param output_par_width Pointer to returned pixel width
754 @ param output_par_height Pointer to returned pixel height
756 void hb_set_anamorphic_size( hb_job_t * job,
757 int *output_width, int *output_height,
758 int *output_par_width, int *output_par_height )
760 /* Set up some variables to make the math easier to follow. */
761 hb_title_t * title = job->title;
762 int cropped_width = title->width - job->crop[2] - job->crop[3] ;
763 int cropped_height = title->height - job->crop[0] - job->crop[1] ;
764 double storage_aspect = (double)cropped_width / (double)cropped_height;
765 int mod = job->modulus ? job->modulus : 16;
766 double aspect = title->aspect;
768 int pixel_aspect_width = job->anamorphic.par_width;
769 int pixel_aspect_height = job->anamorphic.par_height;
771 /* If a source was really NTSC or PAL and the user specified ITU PAR
772 values, replace the standard PAR values with the ITU broadcast ones. */
773 if( title->width == 720 && job->anamorphic.itu_par )
775 // convert aspect to a scaled integer so we can test for 16:9 & 4:3
776 // aspect ratios ignoring insignificant differences in the LSBs of
777 // the floating point representation.
778 int iaspect = aspect * 9.;
780 /* Handle ITU PARs */
781 if (title->height == 480)
786 /* It's widescreen */
787 pixel_aspect_width = 40;
788 pixel_aspect_height = 33;
790 else if (iaspect == 12)
793 pixel_aspect_width = 10;
794 pixel_aspect_height = 11;
797 else if (title->height == 576)
802 /* It's widescreen */
803 pixel_aspect_width = 16;
804 pixel_aspect_height = 11;
806 else if (iaspect == 12)
809 pixel_aspect_width = 12;
810 pixel_aspect_height = 11;
815 /* Figure out what width the source would display at. */
816 int source_display_width = cropped_width * (double)pixel_aspect_width /
817 (double)pixel_aspect_height ;
820 3 different ways of deciding output dimensions:
821 - 1: Strict anamorphic, preserve source dimensions
822 - 2: Loose anamorphic, round to mod16 and preserve storage aspect ratio
823 - 3: Power user anamorphic, specify everything
826 switch( job->anamorphic.mode )
829 /* Strict anamorphic */
830 *output_width = cropped_width;
831 *output_height = cropped_height;
832 *output_par_width = title->pixel_aspect_width;
833 *output_par_height = title->pixel_aspect_height;
837 /* "Loose" anamorphic.
838 - Uses mod16-compliant dimensions,
839 - Allows users to set the width
842 // height: Gets set later, ignore user job->height value
844 /* Gotta handle bounding dimensions.
845 If the width is too big, just reset it with no rescaling.
846 Instead of using the aspect-scaled job height,
847 we need to see if the job width divided by the storage aspect
848 is bigger than the max. If so, set it to the max (this is sloppy).
849 If not, set job height to job width divided by storage aspect.
852 if ( job->maxWidth && (job->maxWidth < job->width) )
853 width = job->maxWidth;
855 /* Time to get picture width that divide cleanly.*/
856 width = MULTIPLE_MOD( width, mod);
858 /* Verify these new dimensions don't violate max height and width settings */
859 if ( job->maxWidth && (job->maxWidth < job->width) )
860 width = job->maxWidth;
862 height = ((double)width / storage_aspect) + 0.5;
864 if ( job->maxHeight && (job->maxHeight < height) )
865 height = job->maxHeight;
867 /* Time to get picture height that divide cleanly.*/
868 height = MULTIPLE_MOD( height, mod);
870 /* Verify these new dimensions don't violate max height and width settings */
871 if ( job->maxHeight && (job->maxHeight < height) )
872 height = job->maxHeight;
874 /* The film AR is the source's display width / cropped source height.
875 The output display width is the output height * film AR.
876 The output PAR is the output display width / output storage width. */
877 pixel_aspect_width = height * source_display_width / cropped_height;
878 pixel_aspect_height = width;
880 /* Pass the results back to the caller */
881 *output_width = width;
882 *output_height = height;
886 /* Anamorphic 3: Power User Jamboree
887 - Set everything based on specified values */
889 /* Use specified storage dimensions */
891 height = job->height;
893 /* Bind to max dimensions */
894 if( job->maxWidth && width > job->maxWidth )
895 width = job->maxWidth;
896 if( job->maxHeight && height > job->maxHeight )
897 height = job->maxHeight;
899 /* Time to get picture dimensions that divide cleanly.*/
900 width = MULTIPLE_MOD( width, mod);
901 height = MULTIPLE_MOD( height, mod);
903 /* Verify we're still within max dimensions */
904 if( job->maxWidth && width > job->maxWidth )
905 width = job->maxWidth - (mod/2);
906 if( job->maxHeight && height > job->maxHeight )
907 height = job->maxHeight - (mod/2);
909 /* Re-ensure we have picture dimensions that divide cleanly. */
910 width = MULTIPLE_MOD( width, mod );
911 height = MULTIPLE_MOD( height, mod );
913 /* That finishes the storage dimensions. On to display. */
914 if( job->anamorphic.dar_width && job->anamorphic.dar_height )
916 /* We need to adjust the PAR to produce this aspect. */
917 pixel_aspect_width = height * job->anamorphic.dar_width / job->anamorphic.dar_height;
918 pixel_aspect_height = width;
922 /* If we're doing ana 3 and not specifying a DAR, care needs to be taken.
923 This indicates a PAR is potentially being set by the interface. But
924 this is an output PAR, to correct a source, and it should not be assumed
925 that it properly creates a display aspect ratio when applied to the source,
926 which could easily be stored in a different resolution. */
927 if( job->anamorphic.keep_display_aspect )
929 /* We can ignore the possibility of a PAR change */
930 pixel_aspect_width = height * ( (double)source_display_width / (double)cropped_height );
931 pixel_aspect_height = width;
935 int output_display_width = width * (double)pixel_aspect_width /
936 (double)pixel_aspect_height;
937 pixel_aspect_width = output_display_width;
938 pixel_aspect_height = width;
943 *output_width = width;
944 *output_height = height;
948 /* While x264 is smart enough to reduce fractions on its own, libavcodec
949 needs some help with the math, so lose superfluous factors. */
950 hb_reduce( output_par_width, output_par_height,
951 pixel_aspect_width, pixel_aspect_height );
955 * Calculates job width, height, and cropping parameters.
956 * @param job Handle to hb_job_t.
957 * @param aspect Desired aspect ratio. Value of -1 uses title aspect.
958 * @param pixels Maximum desired pixel count.
960 void hb_set_size( hb_job_t * job, double aspect, int pixels )
962 hb_title_t * title = job->title;
964 int croppedWidth = title->width - title->crop[2] - title->crop[3];
965 int croppedHeight = title->height - title->crop[0] - title->crop[1];
966 double croppedAspect = title->aspect * title->height * croppedWidth /
967 croppedHeight / title->width;
973 /* Keep the best possible aspect ratio */
974 aspect = croppedAspect;
977 /* Crop if necessary to obtain the desired ratio */
978 memcpy( job->crop, title->crop, 4 * sizeof( int ) );
979 if( aspect < croppedAspect )
981 /* Need to crop on the left and right */
982 addCrop = croppedWidth - aspect * croppedHeight * title->width /
983 title->aspect / title->height;
986 addCrop = ( addCrop + 1 ) / 2;
987 job->crop[2] += addCrop;
988 job->crop[3] += addCrop;
990 else if( addCrop & 2 )
993 job->crop[2] += addCrop - 1;
994 job->crop[3] += addCrop + 1;
999 job->crop[2] += addCrop;
1000 job->crop[3] += addCrop;
1003 else if( aspect > croppedAspect )
1005 /* Need to crop on the top and bottom */
1006 addCrop = croppedHeight - croppedWidth * title->aspect *
1007 title->height / aspect / title->width;
1010 addCrop = ( addCrop + 1 ) / 2;
1011 job->crop[0] += addCrop;
1012 job->crop[1] += addCrop;
1014 else if( addCrop & 2 )
1017 job->crop[0] += addCrop - 1;
1018 job->crop[1] += addCrop + 1;
1023 job->crop[0] += addCrop;
1024 job->crop[1] += addCrop;
1028 /* Compute a resolution from the number of pixels and aspect */
1032 h = MULTIPLE_16( (int)( (double)w / aspect ) );
1033 if( w * h > pixels )
1039 job->width = 16 * i;
1040 job->height = MULTIPLE_16( (int)( (double)job->width / aspect ) );
1044 * Returns the number of jobs in the queue.
1045 * @param h Handle to hb_handle_t.
1046 * @return Number of jobs.
1048 int hb_count( hb_handle_t * h )
1050 return hb_list_count( h->jobs );
1054 * Returns handle to job at index i within the job list.
1055 * @param h Handle to hb_handle_t.
1056 * @param i Index of job.
1057 * @returns Handle to hb_job_t of desired job.
1059 hb_job_t * hb_job( hb_handle_t * h, int i )
1061 return hb_list_item( h->jobs, i );
1064 hb_job_t * hb_current_job( hb_handle_t * h )
1066 return( h->current_job );
1070 * Adds a job to the job list.
1071 * @param h Handle to hb_handle_t.
1072 * @param job Handle to hb_job_t.
1074 void hb_add( hb_handle_t * h, hb_job_t * job )
1076 hb_job_t * job_copy;
1077 hb_title_t * title, * title_copy;
1078 hb_chapter_t * chapter, * chapter_copy;
1080 hb_subtitle_t * subtitle, * subtitle_copy;
1084 /* Copy the title */
1086 title_copy = malloc( sizeof( hb_title_t ) );
1087 memcpy( title_copy, title, sizeof( hb_title_t ) );
1089 title_copy->list_chapter = hb_list_init();
1090 for( i = 0; i < hb_list_count( title->list_chapter ); i++ )
1092 chapter = hb_list_item( title->list_chapter, i );
1093 chapter_copy = malloc( sizeof( hb_chapter_t ) );
1094 memcpy( chapter_copy, chapter, sizeof( hb_chapter_t ) );
1095 hb_list_add( title_copy->list_chapter, chapter_copy );
1101 if( title->metadata )
1103 title_copy->metadata = malloc( sizeof( hb_metadata_t ) );
1105 if( title_copy->metadata )
1107 memcpy( title_copy->metadata, title->metadata, sizeof( hb_metadata_t ) );
1110 * Need to copy the artwork seperatly (TODO).
1112 if( title->metadata->coverart )
1114 title_copy->metadata->coverart = malloc( title->metadata->coverart_size );
1115 if( title_copy->metadata->coverart )
1117 memcpy( title_copy->metadata->coverart, title->metadata->coverart,
1118 title->metadata->coverart_size );
1120 title_copy->metadata->coverart_size = 0;
1126 /* Copy the audio track(s) we want */
1127 title_copy->list_audio = hb_list_init();
1129 for( i = 0; i < hb_list_count(job->list_audio); i++ )
1131 if( ( audio = hb_list_item( job->list_audio, i ) ) )
1133 hb_list_add( title_copy->list_audio, hb_audio_copy(audio) );
1137 title_copy->list_subtitle = hb_list_init();
1140 * The following code is confusing, there are two ways in which
1141 * we select subtitles and it depends on whether this is single or
1144 * subtitle_scan may be enabled, in which case the first pass
1145 * scans all subtitles of that language. The second pass does not
1146 * select any because they are set at the end of the first pass.
1148 * We may have manually selected a subtitle, in which case that is
1149 * selected in the first pass of a single pass, or the second of a
1152 memset( audio_lang, 0, sizeof( audio_lang ) );
1154 if ( job->indepth_scan ) {
1157 * Find the first audio language that is being encoded
1159 for( i = 0; i < hb_list_count(job->list_audio); i++ )
1161 if( ( audio = hb_list_item( job->list_audio, i ) ) )
1163 strncpy(audio_lang, audio->config.lang.iso639_2, sizeof(audio_lang));
1170 * If doing a subtitle scan then add all the matching subtitles for this
1173 if ( job->indepth_scan )
1175 for( i=0; i < hb_list_count( title->list_subtitle ); i++ )
1177 subtitle = hb_list_item( title->list_subtitle, i );
1178 if( strcmp( subtitle->iso639_2, audio_lang ) == 0 &&
1179 subtitle->source == VOBSUB )
1182 * Matched subtitle language with audio language, so
1183 * add this to our list to scan.
1185 * We will update the subtitle list on the second pass
1186 * later after the first pass has completed.
1188 subtitle_copy = malloc( sizeof( hb_subtitle_t ) );
1189 memcpy( subtitle_copy, subtitle, sizeof( hb_subtitle_t ) );
1190 hb_list_add( title_copy->list_subtitle, subtitle_copy );
1195 * Not doing a subtitle scan in this pass, but maybe we are in the
1198 if( job->pass != 1 )
1201 * Copy all of them from the input job, to the title_copy/job_copy.
1203 for( i = 0; i < hb_list_count(job->list_subtitle); i++ ) {
1204 if( ( subtitle = hb_list_item( job->list_subtitle, i ) ) )
1206 subtitle_copy = malloc( sizeof( hb_subtitle_t ) );
1207 memcpy( subtitle_copy, subtitle, sizeof( hb_subtitle_t ) );
1208 hb_list_add( title_copy->list_subtitle, subtitle_copy );
1215 job_copy = calloc( sizeof( hb_job_t ), 1 );
1216 memcpy( job_copy, job, sizeof( hb_job_t ) );
1217 title_copy->job = job_copy;
1218 job_copy->title = title_copy;
1219 job_copy->list_audio = title_copy->list_audio;
1220 job_copy->list_subtitle = title_copy->list_subtitle; // sharing list between title and job
1221 job_copy->file = strdup( job->file );
1223 job_copy->pause = h->pause_lock;
1225 /* Copy the job filter list */
1229 int filter_count = hb_list_count( job->filters );
1230 job_copy->filters = hb_list_init();
1231 for( i = 0; i < filter_count; i++ )
1234 * Copy the filters, since the MacGui reuses the global filter objects
1235 * meaning that queued up jobs overwrite the previous filter settings.
1236 * In reality, settings is probably the only field that needs duplicating
1237 * since it's the only value that is ever changed. But name is duplicated
1238 * as well for completeness. Not copying private_data since it gets
1239 * created for each job in renderInit.
1241 hb_filter_object_t * filter = hb_list_item( job->filters, i );
1242 hb_filter_object_t * filter_copy = malloc( sizeof( hb_filter_object_t ) );
1243 memcpy( filter_copy, filter, sizeof( hb_filter_object_t ) );
1245 filter_copy->name = strdup( filter->name );
1246 if( filter->settings )
1247 filter_copy->settings = strdup( filter->settings );
1248 hb_list_add( job_copy->filters, filter_copy );
1252 /* Add the job to the list */
1253 hb_list_add( h->jobs, job_copy );
1254 h->job_count = hb_count(h);
1255 h->job_count_permanent++;
1259 * Removes a job from the job list.
1260 * @param h Handle to hb_handle_t.
1261 * @param job Handle to hb_job_t.
1263 void hb_rem( hb_handle_t * h, hb_job_t * job )
1265 hb_list_rem( h->jobs, job );
1267 h->job_count = hb_count(h);
1268 if (h->job_count_permanent)
1269 h->job_count_permanent--;
1271 /* XXX free everything XXX */
1275 * Starts the conversion process.
1276 * Sets state to HB_STATE_WORKING.
1277 * calls hb_work_init, to launch work thread. Stores handle to work thread.
1278 * @param h Handle to hb_handle_t.
1280 void hb_start( hb_handle_t * h )
1283 h->job_count = hb_list_count( h->jobs );
1284 h->job_count_permanent = h->job_count;
1286 hb_lock( h->state_lock );
1287 h->state.state = HB_STATE_WORKING;
1288 #define p h->state.param.working
1291 p.job_count = h->job_count;
1299 hb_unlock( h->state_lock );
1304 h->work_thread = hb_work_init( h->jobs, h->cpu_count,
1305 &h->work_die, &h->work_error, &h->current_job );
1309 * Pauses the conversion process.
1310 * @param h Handle to hb_handle_t.
1312 void hb_pause( hb_handle_t * h )
1316 hb_lock( h->pause_lock );
1319 hb_current_job( h )->st_pause_date = hb_get_date();
1321 hb_lock( h->state_lock );
1322 h->state.state = HB_STATE_PAUSED;
1323 hb_unlock( h->state_lock );
1328 * Resumes the conversion process.
1329 * @param h Handle to hb_handle_t.
1331 void hb_resume( hb_handle_t * h )
1335 #define job hb_current_job( h )
1336 if( job->st_pause_date != -1 )
1338 job->st_paused += hb_get_date() - job->st_pause_date;
1342 hb_unlock( h->pause_lock );
1348 * Stops the conversion process.
1349 * @param h Handle to hb_handle_t.
1351 void hb_stop( hb_handle_t * h )
1355 h->job_count = hb_count(h);
1356 h->job_count_permanent = 0;
1362 * Stops the conversion process.
1363 * @param h Handle to hb_handle_t.
1365 void hb_scan_stop( hb_handle_t * h )
1369 h->job_count = hb_count(h);
1370 h->job_count_permanent = 0;
1376 * Returns the state of the conversion process.
1377 * @param h Handle to hb_handle_t.
1378 * @param s Handle to hb_state_t which to copy the state data.
1380 void hb_get_state( hb_handle_t * h, hb_state_t * s )
1382 hb_lock( h->state_lock );
1384 memcpy( s, &h->state, sizeof( hb_state_t ) );
1385 if ( h->state.state == HB_STATE_SCANDONE || h->state.state == HB_STATE_WORKDONE )
1386 h->state.state = HB_STATE_IDLE;
1388 hb_unlock( h->state_lock );
1391 void hb_get_state2( hb_handle_t * h, hb_state_t * s )
1393 hb_lock( h->state_lock );
1395 memcpy( s, &h->state, sizeof( hb_state_t ) );
1397 hb_unlock( h->state_lock );
1401 * Called in MacGui in UpdateUI to check
1402 * for a new scan being completed to set a new source
1404 int hb_get_scancount( hb_handle_t * h)
1406 return h->scanCount;
1410 * Closes access to libhb by freeing the hb_handle_t handle ontained in hb_init.
1411 * @param _h Pointer to handle to hb_handle_t.
1413 void hb_close( hb_handle_t ** _h )
1415 hb_handle_t * h = *_h;
1420 hb_thread_close( &h->main_thread );
1422 while( ( title = hb_list_item( h->list_title, 0 ) ) )
1424 hb_list_rem( h->list_title, title );
1425 if( title->job && title->job->filters )
1427 hb_list_close( &title->job->filters );
1430 hb_title_close( &title );
1432 hb_list_close( &h->list_title );
1434 hb_list_close( &h->jobs );
1435 hb_lock_close( &h->state_lock );
1436 hb_lock_close( &h->pause_lock );
1443 * Cleans up libhb at a process level. Call before the app closes. Removes preview directory.
1445 void hb_global_close()
1449 struct dirent * entry;
1451 /* Find and remove temp folder */
1452 memset( dirname, 0, 1024 );
1453 hb_get_temporary_directory( dirname );
1455 dir = opendir( dirname );
1458 while( ( entry = readdir( dir ) ) )
1460 char filename[1024];
1461 if( entry->d_name[0] == '.' )
1465 memset( filename, 0, 1024 );
1466 snprintf( filename, 1023, "%s/%s", dirname, entry->d_name );
1475 * Monitors the state of the update, scan, and work threads.
1476 * Sets scan done state when scan thread exits.
1477 * Sets work done state when work thread exits.
1478 * @param _h Handle to hb_handle_t
1480 static void thread_func( void * _h )
1482 hb_handle_t * h = (hb_handle_t *) _h;
1487 /* Create folder for temporary files */
1488 memset( dirname, 0, 1024 );
1489 hb_get_temporary_directory( dirname );
1491 hb_mkdir( dirname );
1495 /* In case the check_update thread hangs, it'll die sooner or
1496 later. Then, we join it here */
1497 if( h->update_thread &&
1498 hb_thread_has_exited( h->update_thread ) )
1500 hb_thread_close( &h->update_thread );
1503 /* Check if the scan thread is done */
1504 if( h->scan_thread &&
1505 hb_thread_has_exited( h->scan_thread ) )
1507 hb_thread_close( &h->scan_thread );
1513 hb_remove_previews( h );
1514 while( ( title = hb_list_item( h->list_title, 0 ) ) )
1516 hb_list_rem( h->list_title, title );
1517 hb_title_close( &title );
1520 hb_log( "hb_scan: canceled" );
1524 hb_log( "libhb: scan thread found %d valid title(s)",
1525 hb_list_count( h->list_title ) );
1527 hb_lock( h->state_lock );
1528 h->state.state = HB_STATE_SCANDONE; //originally state.state
1529 hb_unlock( h->state_lock );
1530 /*we increment this sessions scan count by one for the MacGui
1531 to trigger a new source being set */
1535 /* Check if the work thread is done */
1536 if( h->work_thread &&
1537 hb_thread_has_exited( h->work_thread ) )
1539 hb_thread_close( &h->work_thread );
1541 hb_log( "libhb: work result = %d",
1543 hb_lock( h->state_lock );
1544 h->state.state = HB_STATE_WORKDONE;
1545 h->state.param.workdone.error = h->work_error;
1547 h->job_count = hb_count(h);
1548 if (h->job_count < 1)
1549 h->job_count_permanent = 0;
1550 hb_unlock( h->state_lock );
1556 if( h->scan_thread )
1559 hb_thread_close( &h->scan_thread );
1561 if( h->work_thread )
1564 hb_thread_close( &h->work_thread );
1566 hb_remove_previews( h );
1571 * @param h Handle to hb_handle_t
1573 int hb_get_pid( hb_handle_t * h )
1579 * Returns the id for the given instance.
1580 * @param h Handle to hb_handle_t
1582 int hb_get_instance_id( hb_handle_t * h )
1588 * Sets the current state.
1589 * @param h Handle to hb_handle_t
1590 * @param s Handle to new hb_state_t
1592 void hb_set_state( hb_handle_t * h, hb_state_t * s )
1594 hb_lock( h->pause_lock );
1595 hb_lock( h->state_lock );
1596 memcpy( &h->state, s, sizeof( hb_state_t ) );
1597 if( h->state.state == HB_STATE_WORKING ||
1598 h->state.state == HB_STATE_SEARCHING )
1601 if (h->job_count < 1)
1602 h->job_count_permanent = 1;
1604 h->state.param.working.job_cur =
1605 h->job_count_permanent - hb_list_count( h->jobs );
1606 h->state.param.working.job_count = h->job_count_permanent;
1608 // Set which job is being worked on
1610 h->state.param.working.sequence_id = h->current_job->sequence_id;
1612 h->state.param.working.sequence_id = 0;
1614 hb_unlock( h->state_lock );
1615 hb_unlock( h->pause_lock );
1618 /* Passes a pointer to persistent data */
1619 hb_interjob_t * hb_interjob_get( hb_handle_t * h )