⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 encoder.c

📁 linux下编译已经通过
💻 C
📖 第 1 页 / 共 5 页
字号:
             f_thresh_min= f_thresh_max;        /* macroblock_analyse() doesn't further analyse skipped mbs,         * so we have to guess their cost */        if( h->stat.frame.i_mbs_analysed > 0 )            i_intra_cost = i_intra_cost * i_mb / h->stat.frame.i_mbs_analysed;        if( i_gop_size < h->param.i_keyint_min / 4 )            f_bias = f_thresh_min / 4;        else if( i_gop_size <= h->param.i_keyint_min )            f_bias = f_thresh_min * i_gop_size / h->param.i_keyint_min;        else        {            f_bias = f_thresh_min                     + ( f_thresh_max - f_thresh_min )                       * ( i_gop_size - h->param.i_keyint_min )                       / ( h->param.i_keyint_max - h->param.i_keyint_min );        }        f_bias = X264_MIN( f_bias, 1.0 );        /* Bad P will be reencoded as I */        if( h->stat.frame.i_mbs_analysed > 0 &&            i_inter_cost >= (1.0 - f_bias) * i_intra_cost )        {            int b;            x264_log( h, X264_LOG_DEBUG, "scene cut at %d Icost:%.0f Pcost:%.0f ratio:%.4f bias:%.4f gop:%d (imb:%d pmb:%d smb:%d)\n",                      h->fenc->i_frame,                      (double)i_intra_cost, (double)i_inter_cost,                      1. - (double)i_inter_cost / i_intra_cost,                      f_bias, i_gop_size,                      i_mb_i, i_mb_p, i_mb_s );            /* Restore frame num */            h->i_frame_num--;            for( b = 0; h->frames.current[b] && IS_X264_TYPE_B( h->frames.current[b]->i_type ); b++ );            if( b > 0 )            {                /* If using B-frames, force GOP to be closed.                 * Even if this frame is going to be I and not IDR, forcing a                 * P-frame before the scenecut will probably help compression.                 *                  * We don't yet know exactly which frame is the scene cut, so                 * we can't assign an I-frame. Instead, change the previous                 * B-frame to P, and rearrange coding order. */                if( h->param.b_bframe_adaptive || b > 1 )                    h->fenc->i_type = X264_TYPE_AUTO;                x264_frame_sort_pts( h->frames.current );                x264_frame_unshift( h->frames.next, h->fenc );                h->fenc = h->frames.current[b-1];                h->frames.current[b-1] = NULL;                h->fenc->i_type = X264_TYPE_P;                x264_frame_sort_dts( h->frames.current );            }            /* Do IDR if needed */            else if( i_gop_size >= h->param.i_keyint_min )            {                /* Reset */                h->i_frame_num = 0;                /* Reinit field of fenc */                h->fenc->i_type = X264_TYPE_IDR;                h->fenc->i_poc = 0;                /* Put enqueued frames back in the pool */                while( h->frames.current[0] )                    x264_frame_push( h->frames.next, x264_frame_shift( h->frames.current ) );                x264_frame_sort_pts( h->frames.next );            }            else            {                h->fenc->i_type = X264_TYPE_I;            }            goto do_encode;        }    }    x264_encoder_frame_end( thread_oldest, thread_current, pp_nal, pi_nal, pic_out );    return 0;}static void x264_encoder_frame_end( x264_t *h, x264_t *thread_current,                                    x264_nal_t **pp_nal, int *pi_nal,                                    x264_picture_t *pic_out ){    int i;    char psz_message[80];    if( h->b_thread_active )    {        x264_pthread_join( h->thread_handle, NULL );        h->b_thread_active = 0;    }    if( !h->out.i_nal )    {        pic_out->i_type = X264_TYPE_AUTO;        return;    }    x264_frame_push_unused( thread_current, h->fenc );    /* End bitstream, set output  */    *pi_nal = h->out.i_nal;    *pp_nal = h->out.nal;    h->out.i_nal = 0;    /* Set output picture properties */    if( h->sh.i_type == SLICE_TYPE_I )        pic_out->i_type = h->i_nal_type == NAL_SLICE_IDR ? X264_TYPE_IDR : X264_TYPE_I;    else if( h->sh.i_type == SLICE_TYPE_P )        pic_out->i_type = X264_TYPE_P;    else        pic_out->i_type = X264_TYPE_B;    pic_out->i_pts = h->fenc->i_pts;    pic_out->img.i_plane = h->fdec->i_plane;    for(i = 0; i < 4; i++){        pic_out->img.i_stride[i] = h->fdec->i_stride[i];        pic_out->img.plane[i] = h->fdec->plane[i];    }    /* ---------------------- Update encoder state ------------------------- */    /* update rc */    x264_cpu_restore( h->param.cpu );    x264_ratecontrol_end( h, h->out.i_frame_size * 8 );    /* restore CPU state (before using float again) */    x264_cpu_restore( h->param.cpu );    x264_noise_reduction_update( h );    TIMER_STOP( i_mtime_encode_frame );    /* ---------------------- Compute/Print statistics --------------------- */    x264_thread_sync_stat( h, h->thread[0] );    /* Slice stat */    h->stat.i_slice_count[h->sh.i_type]++;    h->stat.i_slice_size[h->sh.i_type] += h->out.i_frame_size + NALU_OVERHEAD;    h->stat.i_slice_qp[h->sh.i_type] += h->fdec->i_qpplus1 - 1;    for( i = 0; i < X264_MBTYPE_MAX; i++ )        h->stat.i_mb_count[h->sh.i_type][i] += h->stat.frame.i_mb_count[i];    for( i = 0; i < 2; i++ )        h->stat.i_mb_count_8x8dct[i] += h->stat.frame.i_mb_count_8x8dct[i];    if( h->sh.i_type != SLICE_TYPE_I )    {        for( i = 0; i < 7; i++ )            h->stat.i_mb_count_size[h->sh.i_type][i] += h->stat.frame.i_mb_count_size[i];        for( i = 0; i < 32; i++ )            h->stat.i_mb_count_ref[h->sh.i_type][i] += h->stat.frame.i_mb_count_ref[i];    }    if( h->sh.i_type == SLICE_TYPE_B )    {        h->stat.i_direct_frames[ h->sh.b_direct_spatial_mv_pred ] ++;        if( h->mb.b_direct_auto_write )        {            //FIXME somewhat arbitrary time constants            if( h->stat.i_direct_score[0] + h->stat.i_direct_score[1] > h->mb.i_mb_count )            {                for( i = 0; i < 2; i++ )                    h->stat.i_direct_score[i] = h->stat.i_direct_score[i] * 9/10;            }            for( i = 0; i < 2; i++ )                h->stat.i_direct_score[i] += h->stat.frame.i_direct_score[i];        }    }    psz_message[0] = '\0';    if( h->param.analyse.b_psnr )    {        int64_t sqe[3];        for( i=0; i<3; i++ )        {            sqe[i] = x264_pixel_ssd_wxh( &h->pixf,                         h->fdec->plane[i], h->fdec->i_stride[i],                         h->fenc->plane[i], h->fenc->i_stride[i],                         h->param.i_width >> !!i, h->param.i_height >> !!i );        }        x264_cpu_restore( h->param.cpu );        h->stat.i_sqe_global[h->sh.i_type] += sqe[0] + sqe[1] + sqe[2];        h->stat.f_psnr_average[h->sh.i_type] += x264_psnr( sqe[0] + sqe[1] + sqe[2], 3 * h->param.i_width * h->param.i_height / 2 );        h->stat.f_psnr_mean_y[h->sh.i_type] += x264_psnr( sqe[0], h->param.i_width * h->param.i_height );        h->stat.f_psnr_mean_u[h->sh.i_type] += x264_psnr( sqe[1], h->param.i_width * h->param.i_height / 4 );        h->stat.f_psnr_mean_v[h->sh.i_type] += x264_psnr( sqe[2], h->param.i_width * h->param.i_height / 4 );        snprintf( psz_message, 80, " PSNR Y:%5.2f U:%5.2f V:%5.2f",                  x264_psnr( sqe[0], h->param.i_width * h->param.i_height ),                  x264_psnr( sqe[1], h->param.i_width * h->param.i_height / 4),                  x264_psnr( sqe[2], h->param.i_width * h->param.i_height / 4) );    }    if( h->param.analyse.b_ssim )    {        // offset by 2 pixels to avoid alignment of ssim blocks with dct blocks        float ssim_y = x264_pixel_ssim_wxh( &h->pixf,                         h->fdec->plane[0] + 2+2*h->fdec->i_stride[0], h->fdec->i_stride[0],                         h->fenc->plane[0] + 2+2*h->fenc->i_stride[0], h->fenc->i_stride[0],                         h->param.i_width-2, h->param.i_height-2 );        h->stat.f_ssim_mean_y[h->sh.i_type] += ssim_y;        snprintf( psz_message + strlen(psz_message), 80 - strlen(psz_message),                  " SSIM Y:%.5f", ssim_y );    }    psz_message[79] = '\0';        x264_log( h, X264_LOG_DEBUG,                  "frame=%4d QP=%i NAL=%d Slice:%c Poc:%-3d I:%-4d P:%-4d SKIP:%-4d size=%d bytes%s\n",              h->i_frame,              h->fdec->i_qpplus1 - 1,              h->i_nal_ref_idc,              h->sh.i_type == SLICE_TYPE_I ? 'I' : (h->sh.i_type == SLICE_TYPE_P ? 'P' : 'B' ),              h->fdec->i_poc,              h->stat.frame.i_mb_count_i,              h->stat.frame.i_mb_count_p,              h->stat.frame.i_mb_count_skip,              h->out.i_frame_size,              psz_message );    // keep stats all in one place    x264_thread_sync_stat( h->thread[0], h );    // for the use of the next frame    x264_thread_sync_stat( thread_current, h );#ifdef DEBUG_MB_TYPE{    static const char mb_chars[] = { 'i', '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++ )    {        if( h->mb.type[mb_xy] < X264_MBTYPE_MAX && h->mb.type[mb_xy] >= 0 )            fprintf( stderr, "%c ", mb_chars[ h->mb.type[mb_xy] ] );        else            fprintf( stderr, "? " );        if( (mb_xy+1) % h->sps->i_mb_width == 0 )            fprintf( stderr, "\n" );    }}#endif#ifdef DEBUG_DUMP_FRAME    /* Dump reconstructed frame */    x264_frame_dump( h, h->fdec, "fdec.yuv" );#endif}/**************************************************************************** * x264_encoder_close: ****************************************************************************/void    x264_encoder_close  ( x264_t *h ){#ifdef DEBUG_BENCHMARK    int64_t i_mtime_total = i_mtime_analyse + i_mtime_encode + i_mtime_write + i_mtime_filter + 1;#endif    int64_t i_yuv_size = 3 * h->param.i_width * h->param.i_height / 2;    int i;    for( i=0; i<h->param.i_threads; i++ )    {        // don't strictly have to wait for the other threads, but it's simpler than cancelling them        if( h->thread[i]->b_thread_active )            x264_pthread_join( h->thread[i]->thread_handle, NULL );    }#ifdef DEBUG_BENCHMARK    x264_log( h, X264_LOG_INFO,              "analyse=%d(%lldms) encode=%d(%lldms) write=%d(%lldms) filter=%d(%lldms)\n",              (int)(100*i_mtime_analyse/i_mtime_total), i_mtime_analyse/1000,              (int)(100*i_mtime_encode/i_mtime_total), i_mtime_encode/1000,              (int)(100*i_mtime_write/i_mtime_total), i_mtime_write/1000,              (int)(100*i_mtime_filter/i_mtime_total), i_mtime_filter/1000 );#endif    /* 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:%-5d Avg QP:%5.2f  size:%6.0f  PSNR Mean Y:%5.2f U:%5.2f V:%5.2f Avg:%5.2f Global:%5.2f\n",                          slice_name[i_slice],                          i_count,                          (double)h->stat.i_slice_qp[i_slice] / i_count,                          (double)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 ) );            }            else            {                x264_log( h, X264_LOG_INFO,                          "slice %s:%-5d Avg QP:%5.2f  size:%6.0f\n",                          slice_name[i_slice],                          i_count,                          (double)h->stat.i_slice_qp[i_slice] / i_count,                          (double)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 double i_count = h->stat.i_slice_count[SLICE_TYPE_I] * h->mb.i_mb_count / 100.0;        x264_log( h, X264_LOG_INFO,                  "mb I  I16..4: %4.1f%% %4.1f%% %4.1f%%\n",                  i_mb_count[I_16x16]/ i_count,                  i_mb_count[I_8x8]  / i_count,                  i_mb_count[I_4x4]  / 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 int64_t *i_mb_size = h->stat.i_mb_count_size[SLICE_TYPE_P];        const double i_count = h->stat.i_slice_count[SLICE_TYPE_P] * h->mb.i_mb_count / 100.0;        x264_log( h, X264_LOG_INFO,                  "mb P  I16..4: %4.1f%% %4.1f%% %4.1f%%  P16..4: %4.1f%% %4.1f%% %4.1f%% %4.1f%% %4.1f%%    skip:%4.1f%%\n",                  i_mb_count[I_16x16]/ i_count,                  i_mb_count[I_8x8]  / i_count,                  i_mb_count[I_4x4]  / i_count,                  i_mb_size[PIXEL_16x16] / (i_count*4),                  (i_mb_size[PIXEL_16x8] + i_mb_size[PIXEL_8x16]) / (i_count*4),                  i_mb_size[PIXEL_8x8] / (i_count*4),                  (i_mb_size[PIXEL_8x4] + i_mb_size[PIXEL_4x8]) / (i_count*4),                  i_mb_size[PIXEL_4x4] / (i_count*4),                  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 int64_t *i_mb_size = h->stat.i_mb_count_size[SLICE_TYPE_B];        const double i_count = h->stat.i_slice_count[SLICE_TYPE_B] * h->mb.i_mb_count / 100.0;        x264_log( h, X264_LOG_INFO,                  "mb B  I16..4: %4.1f%% %4.1f%% %4.1f%%  B16..8: %4.1f%% %4.1f%% %4.1f%%  direct:%4.1f%%  skip:%4.1f%%\n",                  i_mb_count[I_16x16]  / i_count,                  i_mb_count[I_8x8]    / i_count,                  i_mb_count[I_4x4]    / i_count,                  i_mb_size[PIXEL_16x16] / (i_count*4),                  (i_mb_size[PIXEL_16x8] + i_mb_size[PIXEL_8x16]) / (i_count*4),                  i_mb_size[PIXEL_8x8] / (i_count*4),                  i_mb_count[B_DIRECT] / i_count,                  i_mb_count[B_SKIP]   / i_count );    }    x264_ratecontrol_summary( h );    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 )    {        const int i_count = h->stat.i_slice_count[SLICE_TYPE_I] +                            h->stat.i_slice_count[SLICE_TYPE_P] +                            h->stat.i_slice_count[SLICE_TYPE_B];        float fps = (float) h->param.i_fps_num / h->param.i_fps_den;#define SUM3(p) (p[SLICE_TYPE_I] + p[SLICE_TYPE_P] + p[SLICE_TYPE_B])#define SUM3b(p,o) (p[SLICE_TYPE_I][o] + p[SLICE_TYPE_P][o] + p[SLICE_TYPE_B][o])        float f_bitrate = fps * SUM3(h->stat.i_slice_size) / i_count / 125;        if( h->pps->b_transform_8x8_mode )        {            int64_t i_i8x8 = SUM3b( h->stat.i_mb_count, I_8x8 );            int64_t i_i

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -