X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=libhb%2Fhb.c;h=6c2e5034f79a080d7f69e387c011c34e3584e8b1;hb=ba2864fb60482a5bacb552d17c538b0ed5303a4a;hp=b2d6728726aaa6075d6300274cfc52634077a0ad;hpb=365c4fcd07f5d852cc281224d6addef8abda6cd0;p=handbrake-jp%2Fhandbrake-jp-git.git diff --git a/libhb/hb.c b/libhb/hb.c index b2d67287..6c2e5034 100644 --- a/libhb/hb.c +++ b/libhb/hb.c @@ -427,94 +427,250 @@ void hb_get_preview( hb_handle_t * h, hb_title_t * title, int picture, } /** - * Calculates job width, height, and cropping parameters. - * @param job Handle to hb_job_t. - * @param aspect Desired aspect ratio. Value of -1 uses title aspect. - * @param pixels Maximum desired pixel count. - * @param par If true, skip the cropping and keep-aspect-ratio stuff. + * Calculates job width and height for anamorphic content, + * + * @param job Handle to hb_job_t + * @param output_width Pointer to returned storage width + * @param output_height Pointer to returned storage height + * @param output_par_width Pointer to returned pixel width + @ param output_par_height Pointer to returned pixel height */ -void hb_set_size( hb_job_t * job, int aspect, int pixels, int par ) +void hb_set_anamorphic_size( hb_job_t * job, + int *output_width, int *output_height, + int *output_par_width, int *output_par_height ) { + /* "Loose" anamorphic. + - Uses mod16-compliant dimensions, + - Allows users to set the width + - Handles ITU pixel aspects + */ + + /* Set up some variables to make the math easier to follow. */ hb_title_t * title = job->title; - - int croppedWidth = title->width - title->crop[2] - title->crop[3]; - int croppedHeight = title->height - title->crop[0] - title->crop[1]; - - int croppedAspect; - if (par) + int cropped_width = title->width - job->crop[2] - job->crop[3] ; + int cropped_height = title->height - job->crop[0] - job->crop[1] ; + int storage_aspect = cropped_width * 10000 / cropped_height; + int width = job->width; + int height; // Gets set later, ignore user value + int mod = job->modulus; + int aspect = title->aspect; + + /* Gotta handle bounding dimensions differently + than for non-anamorphic encodes: + If the width is too big, just reset it with no rescaling. + Instead of using the aspect-scaled job height, + we need to see if the job width divided by the storage aspect + is bigger than the max. If so, set it to the max (this is sloppy). + If not, set job height to job width divided by storage aspect. + */ + + if ( job->maxWidth && (job->maxWidth < job->width) ) + width = job->maxWidth; + + if ( job->maxHeight && (job->maxHeight < (width / storage_aspect * 10000)) ) { - /* That means we're setting size for video with non-square pixels */ - croppedAspect = croppedWidth * HB_ASPECT_BASE / croppedHeight; - aspect = croppedAspect; + height = job->maxHeight; } else { - /* We're free to change cropping and maintain display aspect ratio */ - croppedAspect = title->aspect * title->height * croppedWidth / - croppedHeight / title->width; - - int addCrop; + height = width * 10000 / storage_aspect; + } + + + /* Time to get picture dimensions that divide cleanly. + These variables will store temporary dimensions as we iterate. */ + int i, w, h; - if( aspect <= 0 ) + /* In case the user specified a modulus, use it */ + if (job->modulus) + mod = job->modulus; + else + mod = 16; + + /* Iterate through multiples of mod to find one close to job->width. */ + for( i = 1;; i++ ) + { + w = mod * i; + + if (w < width) { - /* Keep the best possible aspect ratio */ - aspect = croppedAspect; + if ( ( width - w ) <= ( mod / 2 ) ) + /* We'll take a width that's + smaller, but close enough. */ + break; } - - /* Crop if necessary to obtain the desired ratio */ - memcpy( job->crop, title->crop, 4 * sizeof( int ) ); - if( aspect < croppedAspect ) + if (w == width) + /* Mod 16 dimensions, how nice! */ + break; + if( w > width ) { - /* Need to crop on the left and right */ - addCrop = croppedWidth - aspect * croppedHeight * title->width / - title->aspect / title->height; - if( addCrop & 3 ) + if ( ( w - width ) < (mod/2) ) + /* We'll take a width that's bigger, if we have to. */ + break; + } + } + width = mod * (i); + + /* Now do the same for a mod-friendly value near job->height. */ + for( i = 1;; i++) + { + h = i * mod; + + if (h < height) { - addCrop = ( addCrop + 1 ) / 2; - job->crop[2] += addCrop; - job->crop[3] += addCrop; + if ( ( height - h ) <= ( mod / 2 )) + /* Go with a smaller height, + if it's close enough. */ + break; } - else if( addCrop & 2 ) + if (h == height) + /* Mod 16 dimensions, how nice! */ + break; + + if ( h > height) + { + if ( ( h - height ) < ( mod / 2 )) + /* Use a taller height if necessary */ + break; + } + } + height = mod * (i); + + int pixel_aspect_width = job->pixel_aspect_width; + int pixel_aspect_height = job->pixel_aspect_height; + + if (cropped_width <= 706) + { + /* Handle ITU PARs */ + if (title->height == 480) + { + /* It's NTSC */ + if (aspect == 16) { - addCrop /= 2; - job->crop[2] += addCrop - 1; - job->crop[3] += addCrop + 1; + /* It's widescreen */ + pixel_aspect_width = 40; + pixel_aspect_height = 33; } else { - addCrop /= 2; - job->crop[2] += addCrop; - job->crop[3] += addCrop; + /* It's 4:3 */ + pixel_aspect_width = 10; + pixel_aspect_height = 11; } } - else if( aspect > croppedAspect ) + else if (title->height == 576) { - /* Need to crop on the top and bottom */ - addCrop = croppedHeight - croppedWidth * title->aspect * - title->height / aspect / title->width; - if( addCrop & 3 ) - { - addCrop = ( addCrop + 1 ) / 2; - job->crop[0] += addCrop; - job->crop[1] += addCrop; - } - else if( addCrop & 2 ) + /* It's PAL */ + if(aspect == 16) { - addCrop /= 2; - job->crop[0] += addCrop - 1; - job->crop[1] += addCrop + 1; + /* It's widescreen */ + pixel_aspect_width = 16; + pixel_aspect_height = 11; } else { - addCrop /= 2; - job->crop[0] += addCrop; - job->crop[1] += addCrop; + /* It's 4:3 */ + pixel_aspect_width = 12; + pixel_aspect_height = 11; } } - } + + /* Figure out what dimensions the source would display at. */ + int source_display_width = cropped_width * ((float)pixel_aspect_width / (float)pixel_aspect_height) ; + /* The film AR is the source's display width / cropped source height. + The output display width is the output height * film AR. + The output PAR is the output display width / output storage width. */ + pixel_aspect_width = height * source_display_width / cropped_height; + pixel_aspect_height = width; + + /* While x264 is smart enough to reduce fractions on its own, libavcodec + needs some help with the math, so lose superfluous factors. */ + hb_reduce( &pixel_aspect_width, &pixel_aspect_height, + pixel_aspect_width, pixel_aspect_height ); + + /* Pass the results back to the caller */ + *output_width = width; + *output_height = height; + *output_par_width = pixel_aspect_width; + *output_par_height = pixel_aspect_height; +} + +/** + * Calculates job width, height, and cropping parameters. + * @param job Handle to hb_job_t. + * @param aspect Desired aspect ratio. Value of -1 uses title aspect. + * @param pixels Maximum desired pixel count. + */ +void hb_set_size( hb_job_t * job, int aspect, int pixels ) +{ + hb_title_t * title = job->title; + + int croppedWidth = title->width - title->crop[2] - title->crop[3]; + int croppedHeight = title->height - title->crop[0] - title->crop[1]; + int croppedAspect = title->aspect * title->height * croppedWidth / + croppedHeight / title->width; + int addCrop; int i, w, h; + + if( aspect <= 0 ) + { + /* Keep the best possible aspect ratio */ + aspect = croppedAspect; + } + + /* Crop if necessary to obtain the desired ratio */ + memcpy( job->crop, title->crop, 4 * sizeof( int ) ); + if( aspect < croppedAspect ) + { + /* Need to crop on the left and right */ + addCrop = croppedWidth - aspect * croppedHeight * title->width / + title->aspect / title->height; + if( addCrop & 3 ) + { + addCrop = ( addCrop + 1 ) / 2; + job->crop[2] += addCrop; + job->crop[3] += addCrop; + } + else if( addCrop & 2 ) + { + addCrop /= 2; + job->crop[2] += addCrop - 1; + job->crop[3] += addCrop + 1; + } + else + { + addCrop /= 2; + job->crop[2] += addCrop; + job->crop[3] += addCrop; + } + } + else if( aspect > croppedAspect ) + { + /* Need to crop on the top and bottom */ + addCrop = croppedHeight - croppedWidth * title->aspect * + title->height / aspect / title->width; + if( addCrop & 3 ) + { + addCrop = ( addCrop + 1 ) / 2; + job->crop[0] += addCrop; + job->crop[1] += addCrop; + } + else if( addCrop & 2 ) + { + addCrop /= 2; + job->crop[0] += addCrop - 1; + job->crop[1] += addCrop + 1; + } + else + { + addCrop /= 2; + job->crop[0] += addCrop; + job->crop[1] += addCrop; + } + } + /* Compute a resolution from the number of pixels and aspect */ for( i = 0;; i++ ) { @@ -829,6 +985,7 @@ void hb_start( hb_handle_t * h ) p.hours = -1; p.minutes = -1; p.seconds = -1; + p.sequence_id = 0; #undef p hb_unlock( h->state_lock ); @@ -1068,6 +1225,12 @@ void hb_set_state( hb_handle_t * h, hb_state_t * s ) h->state.param.working.job_cur = h->job_count_permanent - hb_list_count( h->jobs ); h->state.param.working.job_count = h->job_count_permanent; + + // Set which job is being worked on + if (h->current_job) + h->state.param.working.sequence_id = h->current_job->sequence_id; + else + h->state.param.working.sequence_id = 0; } hb_unlock( h->state_lock ); hb_unlock( h->pause_lock );