]> granicus.if.org Git - libx264/commitdiff
cleanup stats reporting
authorLoren Merritt <pengvado@videolan.org>
Wed, 8 Dec 2004 05:01:57 +0000 (05:01 +0000)
committerLoren Merritt <pengvado@videolan.org>
Wed, 8 Dec 2004 05:01:57 +0000 (05:01 +0000)
report B macroblock types
report average QP

git-svn-id: svn://svn.videolan.org/x264/trunk@66 df754926-b1dd-0310-bc7b-ec298dee348c

core/common.h
encoder/encoder.c
encoder/ratecontrol.c

index bc3ebfdaa6ef1f81b5549bd19131e4e6fdeef7f1..1aacd57ddb5d5e12fc67631695293d893076c29c 100644 (file)
@@ -343,6 +343,8 @@ struct x264_t
             int i_misc_bits;
             /* MB type counts */
             int i_mb_count[18];
+            int i_mb_count_p;
+            int i_mb_count_skip;
             /* Estimated (SATD) cost as Intra/Predicted frame */
             /* XXX: both omit the cost of MBs coded as P_SKIP */
             int i_intra_cost;
@@ -354,6 +356,7 @@ struct x264_t
         /* per slice info */
         int   i_slice_count[5];
         int64_t i_slice_size[5];
+        int     i_slice_qp[5];
         /* */
         int64_t i_sqe_global[5];
         float   f_psnr_average[5];
index ee601d446779c2fdfcf3728bc9d2714fabe793d0..214237c05800c302e030b808729c7d05b4eaee5f 100644 (file)
@@ -296,7 +296,7 @@ static void x264_slice_header_write( bs_t *s, x264_slice_header_t *sh, int i_nal
 x264_t *x264_encoder_open   ( x264_param_t *param )
 {
     x264_t *h = x264_malloc( sizeof( x264_t ) );
-    int i;
+    int i, i_slice;
 
     /* Create a copy of param */
     memcpy( &h->param, param, sizeof( x264_param_t ) );
@@ -457,30 +457,18 @@ x264_t *x264_encoder_open   ( x264_param_t *param )
     h->i_last_inter_size = 0;
 
     /* stat */
-    h->stat.i_slice_count[SLICE_TYPE_I] = 0;
-    h->stat.i_slice_count[SLICE_TYPE_P] = 0;
-    h->stat.i_slice_count[SLICE_TYPE_B] = 0;
-    h->stat.i_slice_size[SLICE_TYPE_I] = 0;
-    h->stat.i_slice_size[SLICE_TYPE_P] = 0;
-    h->stat.i_slice_size[SLICE_TYPE_B] = 0;
-
-    h->stat.i_sqe_global[SLICE_TYPE_I] = 0;
-    h->stat.f_psnr_average[SLICE_TYPE_I] = 0.0;
-    h->stat.f_psnr_mean_y[SLICE_TYPE_I] = h->stat.f_psnr_mean_u[SLICE_TYPE_I] = h->stat.f_psnr_mean_v[SLICE_TYPE_I] = 0.0;
-
-    h->stat.i_sqe_global[SLICE_TYPE_P] = 0;
-    h->stat.f_psnr_average[SLICE_TYPE_P] = 0.0;
-    h->stat.f_psnr_mean_y[SLICE_TYPE_P] = h->stat.f_psnr_mean_u[SLICE_TYPE_P] = h->stat.f_psnr_mean_v[SLICE_TYPE_P] = 0.0;
-
-    h->stat.i_sqe_global[SLICE_TYPE_B] = 0;
-    h->stat.f_psnr_average[SLICE_TYPE_B] = 0.0;
-    h->stat.f_psnr_mean_y[SLICE_TYPE_B] = h->stat.f_psnr_mean_u[SLICE_TYPE_B] = h->stat.f_psnr_mean_v[SLICE_TYPE_B] = 0.0;
-
-    for( i = 0; i < 17; i++ )
+    for( i_slice = 0; i_slice < 5; i_slice++ )
     {
-        h->stat.i_mb_count[SLICE_TYPE_I][i] = 0;
-        h->stat.i_mb_count[SLICE_TYPE_P][i] = 0;
-        h->stat.i_mb_count[SLICE_TYPE_B][i] = 0;
+        h->stat.i_slice_count[i_slice] = 0;
+        h->stat.i_slice_size[i_slice] = 0;
+        h->stat.i_slice_qp[i_slice] = 0;
+
+        h->stat.i_sqe_global[i_slice] = 0;
+        h->stat.f_psnr_average[i_slice] = 0.0;
+        h->stat.f_psnr_mean_y[i_slice] = h->stat.f_psnr_mean_u[i_slice] = h->stat.f_psnr_mean_v[i_slice] = 0.0;
+        
+        for( i = 0; i < 18; i++ )
+            h->stat.i_mb_count[i_slice][i] = 0;
     }
 
     x264_log( h, X264_LOG_INFO, "using cpu capabilities %s%s%s%s%s%s\n",
@@ -733,7 +721,7 @@ static inline void x264_slice_write( x264_t *h, int i_nal_type, int i_nal_ref_id
     h->stat.frame.i_misc_bits =
     h->stat.frame.i_intra_cost =
     h->stat.frame.i_inter_cost = 0;
-    for( i = 0; i < 17; i++ )
+    for( i = 0; i < 18; i++ )
         h->stat.frame.i_mb_count[i] = 0;
 
     /* Slice */
@@ -893,6 +881,8 @@ int     x264_encoder_encode( x264_t *h,
 
     int   i_global_qp;
 
+    char psz_message[80];
+
     /* no data out */
     *pi_nal = 0;
     *pp_nal = NULL;
@@ -1080,6 +1070,7 @@ do_encode:
     pic->i_type     =
     h->fdec->i_type = h->fenc->i_type;
     h->fdec->i_poc  = h->fenc->i_poc;
+    h->fdec->i_frame = h->fenc->i_frame;
 
 
 
@@ -1244,8 +1235,9 @@ do_encode:
     /* Slice stat */
     h->stat.i_slice_count[i_slice_type]++;
     h->stat.i_slice_size[i_slice_type] += bs_pos( &h->out.bs) / 8;
+    h->stat.i_slice_qp[i_slice_type] += i_global_qp;
 
-    for( i = 0; i < 17; i++ )
+    for( i = 0; i < 18; i++ )
     {
         h->stat.i_mb_count[h->sh.i_type][i] += h->stat.frame.i_mb_count[i];
     }
@@ -1265,63 +1257,48 @@ do_encode:
         h->stat.f_psnr_mean_u[i_slice_type] += x264_psnr( i_sqe_u, h->param.i_width * h->param.i_height / 4 );
         h->stat.f_psnr_mean_v[i_slice_type] += x264_psnr( i_sqe_v, h->param.i_width * h->param.i_height / 4 );
 
-        x264_log( h, X264_LOG_DEBUG,
-                  "frame=%4d QP=%i NAL=%d Slice:%c Poc:%-3d I4x4:%-4d I16x16:%-4d P:%-4d SKIP:%-4d size=%d bytes PSNR Y:%2.2f U:%2.2f V:%2.2f\n",
-                  h->i_frame - 1,
-                  i_global_qp,
-                  i_nal_ref_idc,
-                  i_slice_type == SLICE_TYPE_I ? 'I' : (i_slice_type == SLICE_TYPE_P ? 'P' : 'B' ),
-                  frame_psnr->i_poc,
-                  h->stat.frame.i_mb_count[I_4x4],
-                  h->stat.frame.i_mb_count[I_16x16],
-                  h->stat.frame.i_mb_count[P_L0] + h->stat.frame.i_mb_count[P_8x8],
-                  h->stat.frame.i_mb_count[P_SKIP],
-                  h->out.nal[h->out.i_nal-1].i_payload,
+        snprintf( psz_message, 80, " PSNR Y:%2.2f U:%2.2f V:%2.2f",
                   x264_psnr( i_sqe_y, h->param.i_width * h->param.i_height ),
                   x264_psnr( i_sqe_u, h->param.i_width * h->param.i_height / 4),
                   x264_psnr( i_sqe_v, h->param.i_width * h->param.i_height / 4) );
+        psz_message[79] = '\0';
     }
     else
     {
-        x264_log( h, X264_LOG_DEBUG,
-                  "frame=%4d QP=%i NAL=%d Slice:%c Poc:%-3d I4x4:%-4d I16x16:%-4d P:%-4d SKIP:%-4d size=%d bytes\n",
-                  h->i_frame - 1,
-                  i_global_qp,
-                  i_nal_ref_idc,
-                  i_slice_type == SLICE_TYPE_I ? 'I' : (i_slice_type == SLICE_TYPE_P ? 'P' : 'B' ),
-                  frame_psnr->i_poc,
-                  h->stat.frame.i_mb_count[I_4x4],
-                  h->stat.frame.i_mb_count[I_16x16],
-                  h->stat.frame.i_mb_count[P_L0] + h->stat.frame.i_mb_count[P_8x8],
-                  h->stat.frame.i_mb_count[P_SKIP],
-                  h->out.nal[h->out.i_nal-1].i_payload );
+        psz_message[0] = '\0';
     }
+    
+    x264_log( h, X264_LOG_DEBUG,
+                  "frame=%4d QP=%i NAL=%d Slice:%c Poc:%-3d I4x4:%-4d I16x16:%-4d P:%-4d SKIP:%-4d size=%d bytes%s\n",
+              h->i_frame - 1,
+              i_global_qp,
+              i_nal_ref_idc,
+              i_slice_type == SLICE_TYPE_I ? 'I' : (i_slice_type == SLICE_TYPE_P ? 'P' : 'B' ),
+              frame_psnr->i_poc,
+              h->stat.frame.i_mb_count[I_4x4],
+              h->stat.frame.i_mb_count[I_16x16],
+              h->stat.frame.i_mb_count_p,
+              h->stat.frame.i_mb_count_skip,
+              h->out.nal[h->out.i_nal-1].i_payload,
+              psz_message );
 
 
 #ifdef DEBUG_MB_TYPE
+{
+    static const char mb_chars[] = { 'i', 'I', 'C', 'P', '8', 'S',
+        'D', '<', 'X', 'B', 'X', '>', 'B', 'B', 'B', 'B', '8', 'S' };
+    int mb_xy;
     for( mb_xy = 0; mb_xy < h->sps->i_mb_width * h->sps->i_mb_height; mb_xy++ )
     {
-        const int i_mb_y = mb_xy / h->sps->i_mb_width;
-        const int i_mb_x = mb_xy % h->sps->i_mb_width;
-
-        if( i_mb_y > 0 && i_mb_x == 0 )
-            fprintf( stderr, "\n" );
-
-        if( h->mb.type[mb_xy] == I_4x4 )
-            fprintf( stderr, "i" );
-        else if( h->mb.type[mb_xy] == I_16x16 )
-            fprintf( stderr, "I" );
-        else if( h->mb.type[mb_xy] == P_SKIP )
-            fprintf( stderr, "S" );
-        else if( h->mb.type[mb_xy] == P_8x8 )
-            fprintf( stderr, "8" );
-        else if( h->mb.type[mb_xy] == P_L0 )
-            fprintf( stderr, "P" );
+        if( h->mb.type[mb_xy] < 18 && h->mb.type[mb_xy] >= 0 )
+            fprintf( stderr, "%c ", mb_chars[ h->mb.type[mb_xy] ] );
         else
-            fprintf( stderr, "?" );
+            fprintf( stderr, "? " );
 
-        fprintf( stderr, " " );
+        if( (mb_xy+1) % h->sps->i_mb_width == 0 )
+            fprintf( stderr, "\n" );
     }
+}
 #endif
 
 #ifdef DEBUG_DUMP_FRAME
@@ -1357,63 +1334,76 @@ void    x264_encoder_close  ( x264_t *h )
               (int)(100*i_mtime_write/i_mtime_total), i_mtime_write/1000,
               (int)(100*i_mtime_filter/i_mtime_total), i_mtime_filter/1000 );
 
-    /* Slices used and PNSR */
+    /* Slices used and PSNR */
+    for( i=0; i<5; i++ )
+    {
+        static const int slice_order[] = { SLICE_TYPE_I, SLICE_TYPE_SI, SLICE_TYPE_P, SLICE_TYPE_SP, SLICE_TYPE_B };
+        static const char *slice_name[] = { "P", "B", "I", "SP", "SI" };
+        int i_slice = slice_order[i];
+
+        if( h->stat.i_slice_count[i_slice] > 0 )
+        {
+            const int i_count = h->stat.i_slice_count[i_slice];
+            if( h->param.analyse.b_psnr )
+            {
+                x264_log( h, X264_LOG_INFO,
+                          "slice %s:%-4d Avg QP:%5.2f Avg size:%-5lld PSNR Mean Y:%5.2f U:%5.2f V:%5.2f Avg:%5.2f Global:%5.2f MSE*Size:%5.3f\n",
+                          slice_name[i_slice],
+                          i_count,
+                          (float)h->stat.i_slice_qp[i_slice] / i_count,
+                          h->stat.i_slice_size[i_slice] / i_count,
+                          h->stat.f_psnr_mean_y[i_slice] / i_count, h->stat.f_psnr_mean_u[i_slice] / i_count, h->stat.f_psnr_mean_v[i_slice] / i_count,
+                          h->stat.f_psnr_average[i_slice] / i_count,
+                          x264_psnr( h->stat.i_sqe_global[i_slice], i_count * i_yuv_size ),
+                          x264_mse( h->stat.i_sqe_global[i_slice], i_count * i_yuv_size ) * h->stat.i_slice_size[i_slice] / i_count );
+            }
+            else
+            {
+                x264_log( h, X264_LOG_INFO,
+                          "slice %s:%-4d Avg QP:%5.2f Avg size:%-5lld\n",
+                          slice_name[i_slice],
+                          i_count,
+                          (float)h->stat.i_slice_qp[i_slice] / i_count,
+                          h->stat.i_slice_size[i_slice] / i_count );
+            }
+        }
+    }
+
+    /* MB types used */
     if( h->stat.i_slice_count[SLICE_TYPE_I] > 0 )
     {
+        const int64_t *i_mb_count = h->stat.i_mb_count[SLICE_TYPE_I];
         const int i_count = h->stat.i_slice_count[SLICE_TYPE_I];
         x264_log( h, X264_LOG_INFO,
-                  "slice I:%-4d Avg size:%-5lld PSNR Mean Y:%5.2f U:%5.2f V:%5.2f Avg:%5.2f Global:%5.2f MSE*Size:%5.3f\n",
-                   i_count,
-                   h->stat.i_slice_size[SLICE_TYPE_I] / i_count,
-                   h->stat.f_psnr_mean_y[SLICE_TYPE_I] / i_count, h->stat.f_psnr_mean_u[SLICE_TYPE_I] / i_count, h->stat.f_psnr_mean_v[SLICE_TYPE_I] / i_count,
-                   h->stat.f_psnr_average[SLICE_TYPE_I] / i_count,
-                   x264_psnr( h->stat.i_sqe_global[SLICE_TYPE_I], i_count * i_yuv_size ),
-                   x264_mse( h->stat.i_sqe_global[SLICE_TYPE_I], i_count * i_yuv_size ) * h->stat.i_slice_size[SLICE_TYPE_I] / i_count );
+                  "slice I      Avg I4x4:%-4lld I16x16:%-4lld\n",
+                  i_mb_count[I_4x4]  / i_count,
+                  i_mb_count[I_16x16]/ i_count );
     }
     if( h->stat.i_slice_count[SLICE_TYPE_P] > 0 )
     {
+        const int64_t *i_mb_count = h->stat.i_mb_count[SLICE_TYPE_P];
         const int i_count = h->stat.i_slice_count[SLICE_TYPE_P];
         x264_log( h, X264_LOG_INFO,
-                  "slice P:%-4d Avg size:%-5lld PSNR Mean Y:%5.2f U:%5.2f V:%5.2f Avg:%5.2f Global:%5.2f MSE*Size:%5.3f\n",
-                  i_count,
-                  h->stat.i_slice_size[SLICE_TYPE_P] / i_count,
-                  h->stat.f_psnr_mean_y[SLICE_TYPE_P] / i_count, h->stat.f_psnr_mean_u[SLICE_TYPE_P] / i_count, h->stat.f_psnr_mean_v[SLICE_TYPE_P] / i_count,
-                  h->stat.f_psnr_average[SLICE_TYPE_P] / i_count,
-                  x264_psnr( h->stat.i_sqe_global[SLICE_TYPE_P], i_count * i_yuv_size ),
-                  x264_mse( h->stat.i_sqe_global[SLICE_TYPE_P], i_count * i_yuv_size ) * h->stat.i_slice_size[SLICE_TYPE_P] / i_count );
+                  "slice P      Avg I4x4:%-4lld I16x16:%-4lld P:%-4lld P8x8:%-4lld PSKIP:%-4lld\n",
+                  i_mb_count[I_4x4]  / i_count,
+                  i_mb_count[I_16x16]/ i_count,
+                  i_mb_count[P_L0]   / i_count,
+                  i_mb_count[P_8x8]  / i_count,
+                  i_mb_count[P_SKIP] / i_count );
     }
     if( h->stat.i_slice_count[SLICE_TYPE_B] > 0 )
     {
+        const int64_t *i_mb_count = h->stat.i_mb_count[SLICE_TYPE_B];
         const int i_count = h->stat.i_slice_count[SLICE_TYPE_B];
         x264_log( h, X264_LOG_INFO,
-                  "slice B:%-4d Avg size:%-5lld PSNR Mean Y:%5.2f U:%5.2f V:%5.2f Avg:%5.2f Global:%5.2f MSE*Size:%5.3f\n",
-                   h->stat.i_slice_count[SLICE_TYPE_B],
-                   h->stat.i_slice_size[SLICE_TYPE_B] / i_count,
-                   h->stat.f_psnr_mean_y[SLICE_TYPE_B] / i_count, h->stat.f_psnr_mean_u[SLICE_TYPE_B] / i_count, h->stat.f_psnr_mean_v[SLICE_TYPE_B] / i_count,
-                   h->stat.f_psnr_average[SLICE_TYPE_B] / i_count,
-                   x264_psnr( h->stat.i_sqe_global[SLICE_TYPE_B], i_count * i_yuv_size ),
-                   x264_mse( h->stat.i_sqe_global[SLICE_TYPE_B], i_count * i_yuv_size ) * h->stat.i_slice_size[SLICE_TYPE_B] / i_count );
-    }
-
-    /* MB types used */
-    if( h->stat.i_slice_count[SLICE_TYPE_I] > 0 )
-    {
-        const int i_count =  h->stat.i_slice_count[SLICE_TYPE_I];
-        x264_log( h, X264_LOG_INFO,
-                  "slice I      Avg I4x4:%-5lld I16x16:%-5lld\n",
-                  h->stat.i_mb_count[SLICE_TYPE_I][I_4x4]  / i_count,
-                  h->stat.i_mb_count[SLICE_TYPE_I][I_16x16]/ i_count );
-    }
-    if( h->stat.i_slice_count[SLICE_TYPE_P] > 0 )
-    {
-        const int i_count = h->stat.i_slice_count[SLICE_TYPE_P];
-        x264_log( h, X264_LOG_INFO,
-                  "slice P      Avg I4x4:%-5lld I16x16:%-5lld P:%-5lld P8x8:%-5lld PSKIP:%-5lld\n",
-                  h->stat.i_mb_count[SLICE_TYPE_P][I_4x4]  / i_count,
-                  h->stat.i_mb_count[SLICE_TYPE_P][I_16x16]/ i_count,
-                  h->stat.i_mb_count[SLICE_TYPE_P][P_L0] / i_count,
-                  h->stat.i_mb_count[SLICE_TYPE_P][P_8x8] / i_count,
-                  h->stat.i_mb_count[SLICE_TYPE_P][P_SKIP] /i_count );
+                  "slice B      Avg I4x4:%-4lld I16x16:%-4lld P:%-4lld B:%-4lld B8x8:%-4lld DIRECT:%-4lld BSKIP:%-4lld\n",
+                  i_mb_count[I_4x4]    / i_count,
+                  i_mb_count[I_16x16]  / i_count,
+                  (i_mb_count[B_L0_L0] + i_mb_count[B_L1_L1] + i_mb_count[B_L1_L0] + i_mb_count[B_L0_L1]) / i_count,
+                  (i_mb_count[B_BI_BI] + i_mb_count[B_L0_BI] + i_mb_count[B_L1_BI] + i_mb_count[B_BI_L0] + i_mb_count[B_BI_L1]) / i_count,
+                  i_mb_count[B_8x8]    / i_count,
+                  i_mb_count[B_DIRECT] / i_count,
+                  i_mb_count[B_SKIP]   / i_count );
     }
 
     if( h->stat.i_slice_count[SLICE_TYPE_I] + h->stat.i_slice_count[SLICE_TYPE_P] + h->stat.i_slice_count[SLICE_TYPE_B] > 0 )
index 4baf165f17a3ec219b6174a036c8932166ebdff9..36030c0730d0d60be7d463dffe470ef6a17510b0 100644 (file)
@@ -558,9 +558,15 @@ int x264_ratecontrol_slice_type( x264_t *h, int frame_num )
 void x264_ratecontrol_end( x264_t *h, int bits )
 {
     x264_ratecontrol_t *rc = h->rc;
+    int i;
 
     x264_cpu_restore( h->param.cpu );
 
+    h->stat.frame.i_mb_count_skip = h->stat.frame.i_mb_count[P_SKIP] + h->stat.frame.i_mb_count[B_SKIP];
+    h->stat.frame.i_mb_count_p = h->stat.frame.i_mb_count[P_L0] + h->stat.frame.i_mb_count[P_8x8];
+    for( i = B_DIRECT; i < B_8x8; i++ )
+        h->stat.frame.i_mb_count_p += h->stat.frame.i_mb_count[i];
+
     if( h->param.rc.b_stat_write )
     {
         fprintf( rc->p_stat_file_out,
@@ -570,8 +576,8 @@ void x264_ratecontrol_end( x264_t *h, int bits )
                  h->stat.frame.i_itex_bits, h->stat.frame.i_ptex_bits,
                  h->stat.frame.i_hdr_bits, h->stat.frame.i_misc_bits,
                  h->stat.frame.i_mb_count[I_4x4] + h->stat.frame.i_mb_count[I_16x16],
-                 h->stat.frame.i_mb_count[P_L0]  + h->stat.frame.i_mb_count[P_8x8],
-                 h->stat.frame.i_mb_count[P_SKIP]);
+                 h->stat.frame.i_mb_count_p,
+                 h->stat.frame.i_mb_count_skip);
     }
 
     if( !h->param.rc.b_cbr || h->param.rc.b_stat_read )