X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=libhb%2Fcommon.c;h=f7b9ee384ab277f4e0e2ba972c87bc54833044a7;hb=4f0019f03c2e85e8634150ff0c9a31bee6d35ce5;hp=52ea27f66bdb6ab5707685d1538cc472ddea49d1;hpb=216a47ebc53d4afbb8021f5574894c5fa7053871;p=handbrake-jp%2Fhandbrake-jp-git.git diff --git a/libhb/common.c b/libhb/common.c index 52ea27f6..f7b9ee38 100644 --- a/libhb/common.c +++ b/libhb/common.c @@ -119,6 +119,9 @@ void hb_fix_aspect( hb_job_t * job, int keep ) { hb_title_t * title = job->title; int i; + int min_width; + int min_height; + int modulus; /* don't do anything unless the title has complete size info */ if ( title->height == 0 || title->width == 0 || title->aspect == 0 ) @@ -129,44 +132,47 @@ void hb_fix_aspect( hb_job_t * job, int keep ) return; } - /* Sanity checks: - Widths and heights must be multiples of 16 and greater than or - equal to 16 - Crop values must be multiples of 2, greater than or equal to 0 - and less than half of the dimension */ - job->width = MULTIPLE_16( job->width ); - job->height = MULTIPLE_16( job->height ); - job->width = MAX( 16, job->width ); - job->height = MAX( 16, job->height ); + // min_width and min_height should be multiples of modulus + min_width = 32; + min_height = 32; + modulus = job->modulus ? job->modulus : 16; + for( i = 0; i < 4; i++ ) { - job->crop[i] = EVEN( job->crop[i] ); - job->crop[i] = MAX( 0, job->crop[i] ); + // Sanity check crop values are zero or positive multiples of 2 if( i < 2 ) { - /* Top, bottom */ - job->crop[i] = MIN( job->crop[i], ( title->height / 2 ) - 2 ); + // Top, bottom + job->crop[i] = MIN( EVEN( job->crop[i] ), EVEN( ( title->height / 2 ) - ( min_height / 2 ) ) ); + job->crop[i] = MAX( 0, job->crop[i] ); } else { - /* Left, right */ - job->crop[i] = MIN( job->crop[i], ( title->width / 2 ) - 2 ); + // Left, right + job->crop[i] = MIN( EVEN( job->crop[i] ), EVEN( ( title->width / 2 ) - ( min_width / 2 ) ) ); + job->crop[i] = MAX( 0, job->crop[i] ); } } double par = (double)title->width / ( (double)title->height * title->aspect ); double cropped_sar = (double)( title->height - job->crop[0] - job->crop[1] ) / - (double)(title->width - job->crop[2] - job->crop[3] ); + (double)( title->width - job->crop[2] - job->crop[3] ); double ar = par * cropped_sar; + + // Dimensions must be greater than minimum and multiple of modulus if( keep == HB_KEEP_WIDTH ) { - job->height = MULTIPLE_16( (uint64_t)( (double)job->width * ar ) ); - job->height = MAX( 16, job->height ); + job->width = MULTIPLE_MOD( job->width, modulus ); + job->width = MAX( min_width, job->width ); + job->height = MULTIPLE_MOD( (uint64_t)( (double)job->width * ar ), modulus ); + job->height = MAX( min_height, job->height ); } else { - job->width = MULTIPLE_16( (uint64_t)( (double)job->height / ar ) ); - job->width = MAX( 16, job->width ); + job->height = MULTIPLE_MOD( job->height, modulus ); + job->height = MAX( min_height, job->height ); + job->width = MULTIPLE_MOD( (uint64_t)( (double)job->height / ar ), modulus ); + job->width = MAX( min_width, job->width ); } } @@ -613,13 +619,84 @@ void hb_deep_log( hb_debug_level_t level, char * log, ... ) void hb_error( char * log, ... ) { char string[181]; /* 180 chars + \0 */ + char rep_string[181]; + static char last_string[181]; + static int last_error_count = 0; + static uint64_t last_series_error_time = 0; + static hb_lock_t *mutex = 0; va_list args; + uint64_t time_now; /* Convert the message to a string */ va_start( args, log ); vsnprintf( string, 180, log, args ); va_end( args ); + if( !mutex ) + { + mutex = hb_lock_init(); + } + + hb_lock( mutex ); + + time_now = hb_get_date(); + + if( strcmp( string, last_string) == 0 ) + { + /* + * The last error and this one are the same, don't log it + * just count it instead, unless it was more than one second + * ago. + */ + last_error_count++; + if( last_series_error_time + ( 1000 * 1 ) > time_now ) + { + hb_unlock( mutex ); + return; + } + } + + /* + * A new error, or the same one more than 10sec since the last one + * did we have any of the same counted up? + */ + if( last_error_count > 0 ) + { + /* + * Print out the last error to ensure context for the last + * repeated message. + */ + if( error_handler ) + { + error_handler( last_string ); + } else { + hb_log( "%s", last_string ); + } + + if( last_error_count > 1 ) + { + /* + * Only print out the repeat message for more than 2 of the + * same, since we just printed out two of them already. + */ + snprintf( rep_string, 180, "Last error repeated %d times", + last_error_count - 1 ); + + if( error_handler ) + { + error_handler( rep_string ); + } else { + hb_log( "%s", rep_string ); + } + } + + last_error_count = 0; + } + + last_series_error_time = time_now; + + strcpy( last_string, string ); + /* * Got the error in a single string, send it off to be dispatched. */ @@ -627,8 +704,10 @@ void hb_error( char * log, ... ) { error_handler( string ); } else { - hb_log( string ); + hb_log( "%s", string ); } + + hb_unlock( mutex ); } void hb_register_error_handler( hb_error_handler_t * handler ) @@ -641,7 +720,7 @@ void hb_register_error_handler( hb_error_handler_t * handler ) ********************************************************************** * *********************************************************************/ -hb_title_t * hb_title_init( char * dvd, int index ) +hb_title_t * hb_title_init( char * path, int index ) { hb_title_t * t; @@ -651,7 +730,7 @@ hb_title_t * hb_title_init( char * dvd, int index ) t->list_audio = hb_list_init(); t->list_chapter = hb_list_init(); t->list_subtitle = hb_list_init(); - strcat( t->dvd, dvd ); + strcat( t->path, path ); // default to decoding mpeg2 t->video_id = 0xE0; t->video_codec = WORK_DECMPEG2; @@ -900,3 +979,113 @@ int hb_srt_add( const hb_job_t * job, } return retval; } + +char * hb_strdup_printf( char * fmt, ... ) +{ + int len; + va_list ap; + int size = 256; + char * str; + char * tmp; + + str = malloc( size ); + if ( str == NULL ) + return NULL; + + while (1) + { + /* Try to print in the allocated space. */ + va_start( ap, fmt ); + len = vsnprintf( str, size, fmt, ap ); + va_end( ap ); + + /* If that worked, return the string. */ + if ( len > -1 && len < size ) + { + return str; + } + + /* Else try again with more space. */ + if ( len > -1 ) /* glibc 2.1 */ + size = len + 1; /* precisely what is needed */ + else /* glibc 2.0 */ + size *= 2; /* twice the old size */ + tmp = realloc( str, size ); + if ( tmp == NULL ) + { + free( str ); + return NULL; + } + else + str = tmp; + } +} + +/********************************************************************** + * hb_yuv2rgb + ********************************************************************** + * Converts a YCbCr pixel to an RGB pixel. + * + * This conversion is lossy (due to rounding and clamping). + * + * Algorithm: + * http://en.wikipedia.org/w/index.php?title=YCbCr&oldid=361987695#Technical_details + *********************************************************************/ +int hb_yuv2rgb(int yuv) +{ + double y, Cr, Cb; + int r, g, b; + + y = (yuv >> 16) & 0xff; + Cb = (yuv >> 8) & 0xff; + Cr = (yuv ) & 0xff; + + r = 1.164 * (y - 16) + 2.018 * (Cb - 128); + g = 1.164 * (y - 16) - 0.813 * (Cr - 128) - 0.391 * (Cb - 128); + b = 1.164 * (y - 16) + 1.596 * (Cr - 128); + + r = (r < 0) ? 0 : r; + g = (g < 0) ? 0 : g; + b = (b < 0) ? 0 : b; + + r = (r > 255) ? 255 : r; + g = (g > 255) ? 255 : g; + b = (b > 255) ? 255 : b; + + return (r << 16) | (g << 8) | b; +} + +/********************************************************************** + * hb_rgb2yuv + ********************************************************************** + * Converts an RGB pixel to a YCbCr pixel. + * + * This conversion is lossy (due to rounding and clamping). + * + * Algorithm: + * http://en.wikipedia.org/w/index.php?title=YCbCr&oldid=361987695#Technical_details + *********************************************************************/ +int hb_rgb2yuv(int rgb) +{ + double r, g, b; + int y, Cr, Cb; + + r = (rgb >> 16) & 0xff; + g = (rgb >> 8) & 0xff; + b = (rgb ) & 0xff; + + y = 16. + ( 0.257 * r) + (0.504 * g) + (0.098 * b); + Cb = 128. + (-0.148 * r) - (0.291 * g) + (0.439 * b); + Cr = 128. + ( 0.439 * r) - (0.368 * g) - (0.071 * b); + + y = (y < 0) ? 0 : y; + Cb = (Cb < 0) ? 0 : Cb; + Cr = (Cr < 0) ? 0 : Cr; + + y = (y > 255) ? 255 : y; + Cb = (Cb > 255) ? 255 : Cb; + Cr = (Cr > 255) ? 255 : Cr; + + return (y << 16) | (Cb << 8) | Cr; +} +