X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=libhb%2Fencx264.c;h=270692c8abb6e41872469b18364073c5c90c431b;hb=814438ce8ec7b400d211ef9050278e283d2bba5f;hp=407df689dd50c469ae9bd07f734bd227c0348b7f;hpb=44923dc2662c30139d5f069928d2609185d29950;p=handbrake-jp%2Fhandbrake-jp-git.git diff --git a/libhb/encx264.c b/libhb/encx264.c index 407df689..270692c8 100644 --- a/libhb/encx264.c +++ b/libhb/encx264.c @@ -48,7 +48,7 @@ struct hb_work_private_s hb_job_t * job; x264_t * x264; x264_picture_t pic_in; - uint8_t *x264_allocated_pic; + uint8_t * grey_data; uint32_t frames_in; uint32_t frames_out; @@ -85,50 +85,15 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job ) x264_param_default( ¶m ); - /* Default weightp to off for baseline, - overridable through x264 option strings. */ - if( job->x264opts != NULL && *job->x264opts != '\0' ) - { - char *x264opts, *x264opts_start; - - x264opts = x264opts_start = strdup(job->x264opts); - - while( x264opts_start && *x264opts ) - { - char *name = x264opts; - char *value; - - x264opts += strcspn( x264opts, ":" ); - if( *x264opts ) - { - *x264opts = 0; - x264opts++; - } - - value = strchr( name, '=' ); - if( value ) - { - *value = 0; - value++; - } - - if( !( strcmp( name, "bframes" ) ) ) - { - if( atoi( value ) == 0 ) - { - param.analyse.i_weighted_pred = X264_WEIGHTP_NONE; - hb_log("encx264: no bframes, disabling weight-p unless told otherwise"); - } - } - } - } - - /* Temporary hack to use old b-pyramid default */ - param.i_bframe_pyramid = 0; - /* Enable metrics */ param.analyse.b_psnr = 1; param.analyse.b_ssim = 1; + + /* QuickTime has trouble with very low QPs (resulting in visual artifacts). + * Known to affect QuickTime 7, QuickTime X and iTunes. + * Testing shows that a qpmin of 3 works. + */ + param.rc.i_qp_min = 3; param.i_threads = ( hb_get_cpu_count() * 3 / 2 ); param.i_width = job->width; @@ -161,26 +126,17 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job ) we still want the same keyframe intervals as the 1st pass, so the 1st pass stats won't conflict on frame decisions. */ hb_interjob_t * interjob = hb_interjob_get( job->h ); - param.i_keyint_min = ( ( (double)interjob->vrate / (double)interjob->vrate_base ) + 0.5 ); - param.i_keyint_max = ( ( 10 * (double)interjob->vrate / (double)interjob->vrate_base ) + 0.5 ); + param.i_keyint_max = 10 * (int)( (double)interjob->vrate / (double)interjob->vrate_base + 0.5 ); } else { /* adjust +0.5 for when fps has remainder to bump { 23.976, 29.976, 59.94 } to { 24, 30, 60 } */ - param.i_keyint_min = ( ( (double)job->vrate / (double)job->vrate_base ) + 0.5 ); - param.i_keyint_max = ( ( 10 * (double)job->vrate / (double)job->vrate_base ) + 0.5 ); + param.i_keyint_max = 10 * (int)( (double)job->vrate / (double)job->vrate_base + 0.5 ); } } param.i_log_level = X264_LOG_INFO; - if( job->h264_level ) - { - param.b_cabac = 0; - param.i_level_idc = job->h264_level; - hb_log( "encx264: encoding at level %i", - param.i_level_idc ); - } /* This section passes the string x264opts to libx264 for parsing into @@ -223,18 +179,6 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job ) value++; } - if( !( strcmp( name, "b-pyramid" ) ) ) - { - if( value == NULL || !strcmp( value, "1" ) ) - { - value = "normal"; - } - else if( !strcmp( value, "0" ) ) - { - value = "none"; - } - } - /* Here's where the strings are passed to libx264 for parsing. */ ret = x264_param_parse( ¶m, name, value ); @@ -267,8 +211,26 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job ) job->areBframes = 0; } - if( param.i_keyint_min != 25 || param.i_keyint_max != 250 ) - hb_log("encx264: keyint-min: %i, keyint-max: %i", param.i_keyint_min, param.i_keyint_max); + if( param.i_keyint_min != X264_KEYINT_MIN_AUTO || param.i_keyint_max != 250 ) + { + int min_auto; + + if ( param.i_fps_num / param.i_fps_den < param.i_keyint_max / 10 ) + min_auto = param.i_fps_num / param.i_fps_den; + else + min_auto = param.i_keyint_max / 10; + + char min[40], max[40]; + param.i_keyint_min == X264_KEYINT_MIN_AUTO ? + snprintf( min, 40, "auto (%d)", min_auto ) : + snprintf( min, 40, "%d", param.i_keyint_min ); + + param.i_keyint_max == X264_KEYINT_MAX_INFINITE ? + snprintf( max, 40, "infinite" ) : + snprintf( max, 40, "%d", param.i_keyint_max ); + + hb_log( "encx264: min-keyint: %s, keyint: %s", min, max ); + } /* set up the VUI color model & gamma to match what the COLR atom * set in muxmp4.c says. See libhb/muxmp4.c for notes. */ @@ -358,11 +320,20 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job ) memcpy(w->config->h264.pps, nal[1].p_payload + 4, nal[1].i_payload - 4); w->config->h264.pps_length = nal[1].i_payload - 4; - x264_picture_alloc( &pv->pic_in, X264_CSP_I420, - job->width, job->height ); + x264_picture_init( &pv->pic_in ); + pv->pic_in.img.i_csp = X264_CSP_I420; + pv->pic_in.img.i_plane = 3; + pv->pic_in.img.i_stride[0] = job->width; pv->pic_in.img.i_stride[2] = pv->pic_in.img.i_stride[1] = ( ( job->width + 1 ) >> 1 ); - pv->x264_allocated_pic = pv->pic_in.img.plane[0]; + + if( job->grayscale ) + { + int uvsize = ( (job->width + 1) >> 1 ) * ( (job->height + 1) >> 1 ); + pv->grey_data = malloc( uvsize ); + memset( pv->grey_data, 0x80, uvsize ); + pv->pic_in.img.plane[1] = pv->pic_in.img.plane[2] = pv->grey_data; + } return 0; } @@ -376,12 +347,7 @@ void encx264Close( hb_work_object_t * w ) hb_log( "encx264: %u frames had to be split (%u in, %u out)", pv->frames_split, pv->frames_in, pv->frames_out ); } - /* - * Patch the x264 allocated data back in so that x264 can free it - * we have been using our own buffers during the encode to avoid copying. - */ - pv->pic_in.img.plane[0] = pv->x264_allocated_pic; - x264_picture_clean( &pv->pic_in ); + free( pv->grey_data ); x264_encoder_close( pv->x264 ); free( pv ); w->private_data = NULL; @@ -442,16 +408,6 @@ static hb_buffer_t *nal_encode( hb_work_object_t *w, x264_picture_t *pic_out, continue; } - if( job->mux & HB_MUX_AVI ) - { - if( nal[i].i_ref_idc == NAL_PRIORITY_HIGHEST ) - { - buf->frametype = HB_FRAME_KEY; - } - buf->size += size; - continue; - } - /* H.264 in .mp4 or .mkv */ switch( nal[i].i_type ) { @@ -541,13 +497,7 @@ static hb_buffer_t *x264_encode( hb_work_object_t *w, hb_buffer_t *in ) pv->pic_in.img.plane[0] = in->data; int uvsize = ( (job->width + 1) >> 1 ) * ( (job->height + 1) >> 1 ); - if( job->grayscale ) - { - /* XXX x264 has currently no option for grayscale encoding */ - memset( pv->pic_in.img.plane[1], 0x80, uvsize ); - memset( pv->pic_in.img.plane[2], 0x80, uvsize ); - } - else + if( !job->grayscale ) { /* Point x264 at our buffers (Y)UV data */ pv->pic_in.img.plane[1] = in->data + job->width * job->height; @@ -573,7 +523,6 @@ static hb_buffer_t *x264_encode( hb_work_object_t *w, hb_buffer_t *in ) { pv->pic_in.i_type = X264_TYPE_AUTO; } - pv->pic_in.i_qpplus1 = 0; /* XXX this is temporary debugging code to check that the upstream * modules (render & sync) have generated a continuous, self-consistent @@ -623,10 +572,12 @@ int encx264Work( hb_work_object_t * w, hb_buffer_t ** buf_in, x264_nal_t *nal; hb_buffer_t *last_buf = NULL; - while (1) + while ( x264_encoder_delayed_frames( pv->x264 ) ) { x264_encoder_encode( pv->x264, &nal, &i_nal, NULL, &pic_out ); - if ( i_nal <= 0 ) + if ( i_nal == 0 ) + continue; + if ( i_nal < 0 ) break; hb_buffer_t *buf = nal_encode( w, &pic_out, i_nal, nal );