OSDN Git Service

Remove the set cpu count option as it doesn't do anything now
[handbrake-jp/handbrake-jp-git.git] / libhb / encx264.c
index 566fc55..270692c 100644 (file)
@@ -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,58 +85,32 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job )
 
     x264_param_default( &param );
     
-    /* 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;
     param.i_height     = job->height;
     param.i_fps_num    = job->vrate;
     param.i_fps_den    = job->vrate_base;
-    param.i_timebase_num   = 1;
-    param.i_timebase_den   = 90000;
+    if ( job->cfr == 1 )
+    {
+        param.i_timebase_num   = 0;
+        param.i_timebase_den   = 0;
+        param.b_vfr_input = 0;
+    }
+    else
+    {
+        param.i_timebase_num   = 1;
+        param.i_timebase_den   = 90000;
+    }
 
     /* Disable annexb. Inserts size into nal header instead of start code */
     param.b_annexb     = 0;
@@ -152,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
@@ -214,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( &param, name, value );
 
@@ -258,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. */
@@ -349,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;
 }
@@ -367,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;
@@ -433,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 )
         {
@@ -532,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;
@@ -564,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
@@ -614,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 );