X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=libhb%2Fcommon.c;h=52ea27f66bdb6ab5707685d1538cc472ddea49d1;hb=033e32de9c380f54c7d1362a3979da205ebc3a29;hp=00810dd7956b89993067399d29e427c03de13e3d;hpb=39976ca3e604e3eef3823d2fe8f09742b69fac77;p=handbrake-jp%2Fhandbrake-jp-git.git diff --git a/libhb/common.c b/libhb/common.c index 00810dd7..52ea27f6 100644 --- a/libhb/common.c +++ b/libhb/common.c @@ -7,9 +7,10 @@ #include #include #include -#include #include "common.h" +#include "lang.h" +#include "hb.h" /********************************************************************** * Global variables @@ -32,7 +33,8 @@ hb_rate_t hb_audio_bitrates[] = { { "32", 32 }, { "40", 40 }, { "48", 48 }, { "56", 56 }, { "64", 64 }, { "80", 80 }, { "96", 96 }, { "112", 112 }, { "128", 128 }, { "160", 160 }, { "192", 192 }, { "224", 224 }, - { "256", 256 }, { "320", 320 }, { "384", 384 } }; + { "256", 256 }, { "320", 320 }, { "384", 384 }, { "448", 448 }, + { "768", 768 } }; int hb_audio_bitrates_count = sizeof( hb_audio_bitrates ) / sizeof( hb_rate_t ); int hb_audio_bitrates_default = 8; /* 128 kbps */ @@ -83,18 +85,26 @@ const char * hb_mixdown_get_short_name_from_mixdown( int amixdown ) *********************************************************************/ void hb_reduce( int *x, int *y, int num, int den ) { - int lower = MIN( num, den ); - int i; - *x = num; - *y = den; - for( i = lower - 1; i > 1; --i ) + // find the greatest common divisor of num & den by Euclid's algorithm + int n = num, d = den; + while ( d ) { - if( ( num % i == 0 ) && ( den % i == 0 ) ) - { - *x = num / i; - *y = den / i; - break; - } + int t = d; + d = n % d; + n = t; + } + + // at this point n is the gcd. if it's non-zero remove it from num + // and den. Otherwise just return the original values. + if ( n ) + { + *x = num / n; + *y = den / n; + } + else + { + *x = num; + *y = den; } } @@ -114,8 +124,8 @@ void hb_fix_aspect( hb_job_t * job, int keep ) if ( title->height == 0 || title->width == 0 || title->aspect == 0 ) { hb_log( "hb_fix_aspect: incomplete info for title %d: " - "height = %d, width = %d, aspect = %d", - title->height, title->width, title->aspect ); + "height = %d, width = %d, aspect = %.3f", + title->index, title->height, title->width, title->aspect ); return; } @@ -144,22 +154,18 @@ void hb_fix_aspect( hb_job_t * job, int keep ) } } + 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 ar = par * cropped_sar; if( keep == HB_KEEP_WIDTH ) { - job->height = MULTIPLE_16( - (uint64_t) job->width * title->width * HB_ASPECT_BASE * - ( title->height - job->crop[0] - job->crop[1] ) / - ( (uint64_t) title->height * title->aspect * - ( title->width - job->crop[2] - job->crop[3] ) ) ); + job->height = MULTIPLE_16( (uint64_t)( (double)job->width * ar ) ); job->height = MAX( 16, job->height ); } else { - job->width = MULTIPLE_16( - (uint64_t) job->height * title->height * title->aspect * - ( title->width - job->crop[2] - job->crop[3] ) / - ( (uint64_t) title->width * HB_ASPECT_BASE * - ( title->height - job->crop[0] - job->crop[1] ) ) ); + job->width = MULTIPLE_16( (uint64_t)( (double)job->height / ar ) ); job->width = MAX( 16, job->width ); } } @@ -211,9 +217,21 @@ int hb_calc_bitrate( hb_job_t * job, int size ) length += 135000; length /= 90000; + if( size == -1 ) + { + hb_interjob_t * interjob = hb_interjob_get( job->h ); + avail = job->vbitrate * 125 * length; + avail += length * interjob->vrate * overhead / interjob->vrate_base; + } + /* Video overhead */ avail -= length * job->vrate * overhead / job->vrate_base; + if( size == -1 ) + { + goto ret; + } + for( i = 0; i < hb_list_count(job->list_audio); i++ ) { /* Audio data */ @@ -224,6 +242,7 @@ int hb_calc_bitrate( hb_job_t * job, int size ) switch( audio->config.out.codec ) { case HB_ACODEC_FAAC: + case HB_ACODEC_CA_AAC: case HB_ACODEC_VORBIS: samples_per_frame = 1024; break; @@ -231,6 +250,7 @@ int hb_calc_bitrate( hb_job_t * job, int size ) samples_per_frame = 1152; break; case HB_ACODEC_AC3: + case HB_ACODEC_DCA: samples_per_frame = 1536; break; default: @@ -260,6 +280,7 @@ int hb_calc_bitrate( hb_job_t * job, int size ) avail -= length * audio->config.out.samplerate * overhead / samples_per_frame; } +ret: if( avail < 0 ) { return 0; @@ -546,6 +567,44 @@ void hb_log( char * log, ... ) fprintf( stderr, "%s", string ); } +int global_verbosity_level; //Necessary for hb_deep_log +/********************************************************************** + * hb_deep_log + ********************************************************************** + * If verbose mode is >= level, print message with timestamp. Messages + * longer than 360 characters are stripped ;p + *********************************************************************/ +void hb_deep_log( hb_debug_level_t level, char * log, ... ) +{ + char string[362]; /* 360 chars + \n + \0 */ + time_t _now; + struct tm * now; + va_list args; + + if( global_verbosity_level < level ) + { + /* Hiding message */ + return; + } + + /* Get the time */ + _now = time( NULL ); + now = localtime( &_now ); + sprintf( string, "[%02d:%02d:%02d] ", + now->tm_hour, now->tm_min, now->tm_sec ); + + /* Convert the message to a string */ + va_start( args, log ); + vsnprintf( string + 11, 349, log, args ); + va_end( args ); + + /* Add the end of line */ + strcat( string, "\n" ); + + /* Print it */ + fprintf( stderr, "%s", string ); +} + /********************************************************************** * hb_error ********************************************************************** @@ -593,6 +652,9 @@ hb_title_t * hb_title_init( char * dvd, int index ) t->list_chapter = hb_list_init(); t->list_subtitle = hb_list_init(); strcat( t->dvd, dvd ); + // default to decoding mpeg2 + t->video_id = 0xE0; + t->video_codec = WORK_DECMPEG2; return t; } @@ -630,6 +692,15 @@ void hb_title_close( hb_title_t ** _t ) } hb_list_close( &t->list_subtitle ); + if( t->metadata ) + { + if( t->metadata->coverart ) + { + free( t->metadata->coverart ); + } + free( t->metadata ); + } + free( t ); *_t = NULL; } @@ -661,8 +732,13 @@ void hb_filter_close( hb_filter_object_t ** _f ) *********************************************************************/ hb_audio_t *hb_audio_copy(const hb_audio_t *src) { - hb_audio_t *audio = calloc(1, sizeof(*audio)); - memcpy(audio, src, sizeof(*audio)); + hb_audio_t *audio = NULL; + + if( src ) + { + audio = calloc(1, sizeof(*audio)); + memcpy(audio, src, sizeof(*audio)); + } return audio; } @@ -673,13 +749,13 @@ hb_audio_t *hb_audio_copy(const hb_audio_t *src) *********************************************************************/ void hb_audio_config_init(hb_audio_config_t * audiocfg) { - assert(audiocfg != NULL); - /* Set read only paramaters to invalid values */ audiocfg->in.codec = 0xDEADBEEF; audiocfg->in.bitrate = -1; audiocfg->in.samplerate = -1; audiocfg->in.channel_layout = 0; + audiocfg->in.version = 0; + audiocfg->in.mode = 0; audiocfg->flags.ac3 = 0; audiocfg->lang.description[0] = 0; audiocfg->lang.simple[0] = 0; @@ -692,6 +768,7 @@ void hb_audio_config_init(hb_audio_config_t * audiocfg) audiocfg->out.samplerate = 44100; audiocfg->out.mixdown = HB_AMIXDOWN_DOLBYPLII; audiocfg->out.dynamic_range_compression = 0; + audiocfg->out.name = NULL; } /********************************************************************** @@ -701,9 +778,6 @@ void hb_audio_config_init(hb_audio_config_t * audiocfg) *********************************************************************/ int hb_audio_add(const hb_job_t * job, const hb_audio_config_t * audiocfg) { - assert(job != NULL); - assert(audiocfg != NULL); - hb_title_t *title = job->title; hb_audio_t *audio; @@ -727,10 +801,22 @@ int hb_audio_add(const hb_job_t * job, const hb_audio_config_t * audiocfg) */ audio->config.out.track = hb_list_count(job->list_audio) + 1; audio->config.out.codec = audiocfg->out.codec; - audio->config.out.samplerate = audiocfg->out.samplerate; - audio->config.out.bitrate = audiocfg->out.bitrate; - audio->config.out.mixdown = audiocfg->out.mixdown; - audio->config.out.dynamic_range_compression = audiocfg->out.dynamic_range_compression; + if( audiocfg->out.codec == audio->config.in.codec ) + { + /* Pass-through, copy from input. */ + audio->config.out.samplerate = audio->config.in.samplerate; + audio->config.out.bitrate = audio->config.in.bitrate; + audio->config.out.dynamic_range_compression = 0; + audio->config.out.mixdown = 0; + } + else + { + /* Non pass-through, use what is given. */ + audio->config.out.samplerate = audiocfg->out.samplerate; + audio->config.out.bitrate = audiocfg->out.bitrate; + audio->config.out.dynamic_range_compression = audiocfg->out.dynamic_range_compression; + audio->config.out.mixdown = audiocfg->out.mixdown; + } hb_list_add(job->list_audio, audio); return 1; @@ -738,7 +824,6 @@ int hb_audio_add(const hb_job_t * job, const hb_audio_config_t * audiocfg) hb_audio_config_t * hb_list_audio_config_item(hb_list_t * list, int i) { - assert(list != NULL); hb_audio_t *audio = NULL; if( (audio = hb_list_item(list, i)) ) @@ -746,3 +831,72 @@ hb_audio_config_t * hb_list_audio_config_item(hb_list_t * list, int i) return NULL; } + +/********************************************************************** + * hb_subtitle_copy + ********************************************************************** + * + *********************************************************************/ +hb_subtitle_t *hb_subtitle_copy(const hb_subtitle_t *src) +{ + hb_subtitle_t *subtitle = NULL; + + if( src ) + { + subtitle = calloc(1, sizeof(*subtitle)); + memcpy(subtitle, src, sizeof(*subtitle)); + } + return subtitle; +} + +/********************************************************************** + * hb_subtitle_add + ********************************************************************** + * + *********************************************************************/ +int hb_subtitle_add(const hb_job_t * job, const hb_subtitle_config_t * subtitlecfg, int track) +{ + hb_title_t *title = job->title; + hb_subtitle_t *subtitle; + + subtitle = hb_subtitle_copy( hb_list_item( title->list_subtitle, track ) ); + if( subtitle == NULL ) + { + /* We fail! */ + return 0; + } + subtitle->config = *subtitlecfg; + hb_list_add(job->list_subtitle, subtitle); + return 1; +} + +int hb_srt_add( const hb_job_t * job, + const hb_subtitle_config_t * subtitlecfg, + const char *lang ) +{ + hb_subtitle_t *subtitle; + iso639_lang_t *language = NULL; + int retval = 0; + + subtitle = calloc( 1, sizeof( *subtitle ) ); + + subtitle->id = (hb_list_count(job->list_subtitle) << 8) | 0xFF; + subtitle->format = TEXTSUB; + subtitle->source = SRTSUB; + + language = lang_for_code2( lang ); + + if( language ) + { + + strcpy( subtitle->lang, language->eng_name ); + strncpy( subtitle->iso639_2, lang, 4 ); + + subtitle->config = *subtitlecfg; + subtitle->config.dest = PASSTHRUSUB; + + hb_list_add(job->list_subtitle, subtitle); + retval = 1; + } + return retval; +}