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

📄 encoder.c

📁 图象压缩程序
💻 C
📖 第 1 页 / 共 3 页
字号:
    {        if( h->freference[i]->i_poc >= 0 )        {            if( h->freference[i]->i_poc < h->fdec->i_poc )            {                h->fref0[h->i_ref0++] = h->freference[i];            }            else if( h->freference[i]->i_poc > h->fdec->i_poc )            {                h->fref1[h->i_ref1++] = h->freference[i];            }        }    }    /* Order ref0 from higher to lower poc */    do    {        b_ok = 1;        for( i = 0; i < h->i_ref0 - 1; i++ )        {            if( h->fref0[i]->i_poc < h->fref0[i+1]->i_poc )            {                x264_frame_t *tmp = h->fref0[i+1];                h->fref0[i+1] = h->fref0[i];                h->fref0[i] = tmp;                b_ok = 0;                break;            }        }    } while( !b_ok );    /* Order ref1 from lower to higher poc (bubble sort) for B-frame */    do    {        b_ok = 1;        for( i = 0; i < h->i_ref1 - 1; i++ )        {            if( h->fref1[i]->i_poc > h->fref1[i+1]->i_poc )            {                x264_frame_t *tmp = h->fref1[i+1];                h->fref1[i+1] = h->fref1[i];                h->fref1[i] = tmp;                b_ok = 0;                break;            }        }    } while( !b_ok );    if( h->i_ref0 > h->param.i_frame_reference )    {        h->i_ref0 = h->param.i_frame_reference;    }    if( h->i_ref1 > 1 )    {        h->i_ref1 = 1;    }    /* Init the rate control */    x264_ratecontrol_start( h->rc, i_slice_type );    /* ------------------------ Create slice header  ----------------------- */    if( i_nal_type == NAL_SLICE_IDR )    {        x264_slice_header_init( &h->sh, &h->param, h->sps, h->pps, i_slice_type, h->i_idr_pic_id, h->i_frame_num - 1 );        /* increment id */        h->i_idr_pic_id = ( h->i_idr_pic_id + 1 ) % 65535;    }    else    {        x264_slice_header_init( &h->sh, &h->param, h->sps, h->pps, i_slice_type, -1, h->i_frame_num - 1 );        /* always set the real higher num of ref frame used */        h->sh.b_num_ref_idx_override = 1;        h->sh.i_num_ref_idx_l0_active = h->i_ref0 <= 0 ? 1 : h->i_ref0;        h->sh.i_num_ref_idx_l1_active = h->i_ref1 <= 0 ? 1 : h->i_ref1;    }    if( h->sps->i_poc_type == 0 )    {        h->sh.i_poc_lsb = h->fdec->i_poc & ( (1 << h->sps->i_log2_max_poc_lsb) - 1 );        h->sh.i_delta_poc_bottom = 0;   /* XXX won't work for field */    }    else if( h->sps->i_poc_type == 1 )    {        /* FIXME TODO FIXME */    }    else    {        /* Nothing to do ? */    }    /* global qp */    h->sh.i_qp_delta = x264_ratecontrol_qp( h->rc ) - h->pps->i_pic_init_qp;    /* get adapative cabac model if needed */    if( h->param.b_cabac )    {        if( h->param.i_cabac_init_idc == -1 )        {            h->sh.i_cabac_init_idc = x264_cabac_model_get( &h->cabac, i_slice_type );        }    }    /* ---------------------- Write the bitstream -------------------------- */    /* init bitstream context */    h->i_nal = 0;    bs_init( &h->bs, h->p_bitstream, h->i_bitstream );    /* Put SPS and PPS */    if( h->i_frame == 0 )    {        /* generate sequence parameters */        x264_nal_start( h, NAL_SPS, NAL_PRIORITY_HIGHEST );        x264_sps_write( &h->bs, h->sps );        x264_nal_end( h );        /* generate picture parameters */        x264_nal_start( h, NAL_PPS, NAL_PRIORITY_HIGHEST );        x264_pps_write( &h->bs, h->pps );        x264_nal_end( h );    }    /* Reset stats */    for( i = 0; i < 18; i++ ) h->stat.i_mb_count[i] = 0;    /* Slice */    x264_nal_start( h, i_nal_type, i_nal_ref_idc );    /* Slice header */    x264_slice_header_write( &h->bs, &h->sh, i_nal_ref_idc );    if( h->param.b_cabac )    {        /* alignement needed */        bs_align_1( &h->bs );        /* init cabac */        x264_cabac_context_init( &h->cabac, h->sh.i_type, h->sh.pps->i_pic_init_qp + h->sh.i_qp_delta, h->sh.i_cabac_init_idc );        x264_cabac_encode_init ( &h->cabac, &h->bs );    }    for( mb_xy = 0, i_skip = 0; mb_xy < h->sps->i_mb_width * h->sps->i_mb_height; mb_xy++ )    {        x264_mb_context_t context;        x264_macroblock_t *mb;        mb = &h->mb[mb_xy];        /* load neighbour */        x264_macroblock_context_load( h, mb, &context );        /* analyse parameters         * Slice I: choose I_4x4 or I_16x16 mode         * Slice P: choose between using P mode or intra (4x4 or 16x16)         * */        TIMER_START( i_mtime_analyse );        x264_macroblock_analyse( h, &h->mb[mb_xy] );        TIMER_STOP( i_mtime_analyse );        /* encode this macrobock -> be carefull it can change the mb type to P_SKIP if needed */        TIMER_START( i_mtime_encode );        x264_macroblock_encode( h, mb );        TIMER_STOP( i_mtime_encode );        TIMER_START( i_mtime_write );        if( IS_SKIP( mb->i_type ) )        {            if( h->param.b_cabac )            {                if( mb_xy > 0 )                {                    /* not end_of_slice_flag */                    x264_cabac_encode_terminal( &h->cabac, 0 );                }                x264_cabac_mb_skip( h, mb, 1 );            }            else            {                i_skip++;            }        }        else        {            if( h->param.b_cabac )            {                if( mb_xy > 0 )                {                    /* not end_of_slice_flag */                    x264_cabac_encode_terminal( &h->cabac, 0 );                }                if( i_slice_type != SLICE_TYPE_I )                {                    x264_cabac_mb_skip( h, mb, 0 );                }                x264_macroblock_write_cabac( h, &h->bs, mb );            }            else            {                if( i_slice_type != SLICE_TYPE_I )                {                    bs_write_ue( &h->bs, i_skip );  /* skip run */                    i_skip = 0;                }                x264_macroblock_write_cavlc( h, &h->bs, mb );            }        }        TIMER_STOP( i_mtime_write );        h->stat.i_mb_count[mb->i_type]++;    }    if( h->param.b_cabac )    {        /* end of slice */        x264_cabac_encode_terminal( &h->cabac, 1 );    }    else if( i_skip > 0 )    {        bs_write_ue( &h->bs, i_skip );  /* last skip run */    }    if( h->param.b_cabac )    {        int i_cabac_word;        x264_cabac_encode_flush( &h->cabac );        /* TODO cabac stuffing things (p209) */        i_cabac_word = (((3 * h->cabac.i_sym_cnt - 3 * 96 * h->sps->i_mb_width * h->sps->i_mb_height)/32) - bs_pos( &h->bs)/8)/3;        while( i_cabac_word > 0 )        {            bs_write( &h->bs, 16, 0x0000 );            i_cabac_word--;        }    }    else    {        /* rbsp_slice_trailing_bits */        bs_rbsp_trailing( &h->bs );    }    x264_nal_end( h );    /* now set output*/    *pi_nal = h->i_nal;    *pp_nal = &h->nal[0];    /* update cabac */    if( h->param.b_cabac )    {        x264_cabac_model_update( &h->cabac, i_slice_type, h->sh.pps->i_pic_init_qp + h->sh.i_qp_delta );    }    /* update rc */    x264_ratecontrol_end( h->rc, h->nal[h->i_nal-1].i_payload * 8 );    /* ----------------------- handle frame reference ---------------------- */    if( i_nal_ref_idc != NAL_PRIORITY_DISPOSABLE )    {        /* apply deblocking filter to the current decoded picture */        if( h->param.b_deblocking_filter )        {            TIMER_START( i_mtime_filter );            x264_frame_deblocking_filter( h, i_slice_type );            TIMER_STOP( i_mtime_filter );        }        /* expand border */        x264_frame_expand_border( h->fdec );        /* move frame in the buffer */        h->fdec = h->freference[h->param.i_frame_reference+1];        for( i = h->param.i_frame_reference+1; i > 0; i-- )        {            h->freference[i] = h->freference[i-1];        }        h->freference[0] = h->fdec;    }    /* increase frame count */    h->i_frame++;    /* restore CPU state (before using float again) */    x264_cpu_restore( h->cpu );    /* PSNR */    psnr_y = x264_psnr( frame_psnr->plane[0], frame_psnr->i_stride[0], h->picture->plane[0], h->picture->i_stride[0], h->param.i_width, h->param.i_height );    psnr_u = x264_psnr( frame_psnr->plane[1], frame_psnr->i_stride[1], h->picture->plane[1], h->picture->i_stride[1], h->param.i_width/2, h->param.i_height/2);    psnr_v = x264_psnr( frame_psnr->plane[2], frame_psnr->i_stride[2], h->picture->plane[2], h->picture->i_stride[2], h->param.i_width/2, h->param.i_height/2);    /* print stat */    fprintf( stderr, "frame=%4d NAL=%d Slice:%c Poc:%-3d I4x4:%-5d I16x16:%-5d P:%-5d SKIP:%-3d size=%d bytes PSNR Y:%2.2f U:%2.2f V:%2.2f\n",             h->i_frame - 1,             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.i_mb_count[I_4x4],             h->stat.i_mb_count[I_16x16],             h->stat.i_mb_count[P_L0] + h->stat.i_mb_count[P_8x8],             h->stat.i_mb_count[P_SKIP],             h->nal[h->i_nal-1].i_payload,             psnr_y, psnr_u, psnr_v );#if 0    /* Dump reconstructed frame */    x264_frame_dump( h, frame_psnr, "fdec.yuv" );#endif#if 0    if( h->i_ref0 > 0 )    {        x264_frame_dump( h, h->fref0[0], "ref0.yuv" );    }    if( h->i_ref1 > 0 )    {        x264_frame_dump( h, h->fref1[0], "ref1.yuv" );    }#endif    return 0;}/**************************************************************************** * x264_encoder_close: ****************************************************************************/void    x264_encoder_close  ( x264_t *h ){    int64_t i_mtime_total = i_mtime_analyse + i_mtime_encode + i_mtime_write + i_mtime_filter + 1;    int i;    fprintf( stderr, "x264: analyse=%d(%lldms) encode=%d(%lldms) write=%d(%lldms) filter=%d(%lldms)",             (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 );    /* ref frames */    for( i = 0; i < h->param.i_frame_reference+2; i++ )    {        x264_frame_delete( h->freference[i] );    }    /* empty all allocated picture for bframes */    for( i = 0; i < h->param.i_bframe; i++ )    {        if( h->frame_unused[i] )        {            x264_frame_delete( h->frame_unused[i] );        }        if( h->bframe_current[i] )        {            x264_frame_delete( h->bframe_current[i] );        }        if( h->frame_next[i] )        {            x264_frame_delete( h->frame_next[i] );        }    }    /* rc */    x264_ratecontrol_delete( h->rc );    x264_free( h->mb );    x264_free( h->p_bitstream );    x264_free( h );}

⌨️ 快捷键说明

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