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

📄 encoder.c

📁 linux下编译已经通过
💻 C
📖 第 1 页 / 共 5 页
字号:
    // can only twiddle these if they were enabled to begin with:    if( h->pps->b_transform_8x8_mode )        COPY( analyse.b_transform_8x8 );    if( h->frames.i_max_ref1 > 1 )        COPY( b_bframe_pyramid );#undef COPY    mbcmp_init( h );    return x264_validate_parameters( h );}/* internal usage */static void x264_nal_start( x264_t *h, int i_type, int i_ref_idc ){    x264_nal_t *nal = &h->out.nal[h->out.i_nal];    nal->i_ref_idc = i_ref_idc;    nal->i_type    = i_type;    nal->i_payload= 0;    nal->p_payload= &h->out.p_bitstream[bs_pos( &h->out.bs ) / 8];}static void x264_nal_end( x264_t *h ){    x264_nal_t *nal = &h->out.nal[h->out.i_nal];    nal->i_payload = &h->out.p_bitstream[bs_pos( &h->out.bs ) / 8] - nal->p_payload;    h->out.i_nal++;}/**************************************************************************** * x264_encoder_headers: ****************************************************************************/int x264_encoder_headers( x264_t *h, x264_nal_t **pp_nal, int *pi_nal ){    /* init bitstream context */    h->out.i_nal = 0;    bs_init( &h->out.bs, h->out.p_bitstream, h->out.i_bitstream );    /* Put SPS and PPS */    if( h->i_frame == 0 )    {        /* identify ourself */        x264_nal_start( h, NAL_SEI, NAL_PRIORITY_DISPOSABLE );        x264_sei_version_write( h, &h->out.bs );        x264_nal_end( h );        /* generate sequence parameters */        x264_nal_start( h, NAL_SPS, NAL_PRIORITY_HIGHEST );        x264_sps_write( &h->out.bs, h->sps );        x264_nal_end( h );        /* generate picture parameters */        x264_nal_start( h, NAL_PPS, NAL_PRIORITY_HIGHEST );        x264_pps_write( &h->out.bs, h->pps );        x264_nal_end( h );    }    /* now set output*/    *pi_nal = h->out.i_nal;    *pp_nal = &h->out.nal[0];    h->out.i_nal = 0;    return 0;}static inline void x264_reference_build_list( x264_t *h, int i_poc ){    int i;    int b_ok;    /* build ref list 0/1 */    h->i_ref0 = 0;    h->i_ref1 = 0;    for( i = 0; h->frames.reference[i]; i++ )    {        if( h->frames.reference[i]->i_poc < i_poc )        {            h->fref0[h->i_ref0++] = h->frames.reference[i];        }        else if( h->frames.reference[i]->i_poc > i_poc )        {            h->fref1[h->i_ref1++] = h->frames.reference[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 )            {                XCHG( x264_frame_t*, h->fref0[i], h->fref0[i+1] );                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 )            {                XCHG( x264_frame_t*, h->fref1[i], h->fref1[i+1] );                b_ok = 0;                break;            }        }    } while( !b_ok );    /* In the standard, a P-frame's ref list is sorted by frame_num.     * We use POC, but check whether explicit reordering is needed */    h->b_ref_reorder[0] =    h->b_ref_reorder[1] = 0;    if( h->sh.i_type == SLICE_TYPE_P )    {        for( i = 0; i < h->i_ref0 - 1; i++ )            if( h->fref0[i]->i_frame_num < h->fref0[i+1]->i_frame_num )            {                h->b_ref_reorder[0] = 1;                break;            }    }    h->i_ref1 = X264_MIN( h->i_ref1, h->frames.i_max_ref1 );    h->i_ref0 = X264_MIN( h->i_ref0, h->frames.i_max_ref0 );    h->i_ref0 = X264_MIN( h->i_ref0, h->param.i_frame_reference ); // if reconfig() has lowered the limit    h->i_ref0 = X264_MIN( h->i_ref0, 16 - h->i_ref1 );    h->mb.pic.i_fref[0] = h->i_ref0;    h->mb.pic.i_fref[1] = h->i_ref1;}static void x264_fdec_filter_row( x264_t *h, int mb_y ){    /* mb_y is the mb to be encoded next, not the mb to be filtered here */    int b_hpel = h->fdec->b_kept_as_ref;    int b_deblock = !h->sh.i_disable_deblocking_filter_idc;    int b_end = mb_y == h->sps->i_mb_height;    int min_y = mb_y - (1 << h->sh.b_mbaff);#ifndef DEBUG_DUMP_FRAME    b_deblock &= b_hpel;#endif    if( mb_y & h->sh.b_mbaff )        return;    if( min_y < 0 )        return;    if( !b_end )    {        int i, j;        for( j=0; j<=h->sh.b_mbaff; j++ )            for( i=0; i<3; i++ )            {                memcpy( h->mb.intra_border_backup[j][i],                        h->fdec->plane[i] + ((mb_y*16 >> !!i) + j - 1 - h->sh.b_mbaff) * h->fdec->i_stride[i],                        h->sps->i_mb_width*16 >> !!i );            }    }    if( b_deblock )    {        int max_y = b_end ? h->sps->i_mb_height : mb_y;        int y;        for( y = min_y; y < max_y; y += (1 << h->sh.b_mbaff) )            x264_frame_deblock_row( h, y );    }    if( b_hpel )    {        x264_frame_expand_border( h, h->fdec, min_y, b_end );        x264_frame_filter( h->param.cpu, h->fdec, h->sh.b_mbaff, min_y, b_end );        x264_frame_expand_border_filtered( h, h->fdec, min_y, b_end );    }    if( h->param.i_threads > 1 && h->fdec->b_kept_as_ref )    {        x264_frame_cond_broadcast( h->fdec, mb_y*16 + (b_end ? 10000 : -(X264_THREAD_HEIGHT << h->sh.b_mbaff)) );    }}static inline void x264_reference_update( x264_t *h ){    int i;    if( h->fdec->i_frame >= 0 )        h->i_frame++;    if( !h->fdec->b_kept_as_ref )    {        if( h->param.i_threads > 1 )        {            x264_frame_push_unused( h, h->fdec );            h->fdec = x264_frame_pop_unused( h );        }        return;    }    /* move lowres copy of the image to the ref frame */    for( i = 0; i < 4; i++)    {        XCHG( uint8_t*, h->fdec->lowres[i], h->fenc->lowres[i] );        XCHG( uint8_t*, h->fdec->buffer_lowres[i], h->fenc->buffer_lowres[i] );    }    /* adaptive B decision needs a pointer, since it can't use the ref lists */    if( h->sh.i_type != SLICE_TYPE_B )        h->frames.last_nonb = h->fdec;    /* move frame in the buffer */    x264_frame_push( h->frames.reference, h->fdec );    if( h->frames.reference[h->frames.i_max_dpb] )        x264_frame_push_unused( h, x264_frame_shift( h->frames.reference ) );    h->fdec = x264_frame_pop_unused( h );}static inline void x264_reference_reset( x264_t *h ){    while( h->frames.reference[0] )        x264_frame_push_unused( h, x264_frame_pop( h->frames.reference ) );    h->fdec->i_poc =    h->fenc->i_poc = 0;}static inline void x264_slice_init( x264_t *h, int i_nal_type, int i_global_qp ){    /* ------------------------ Create slice header  ----------------------- */    if( i_nal_type == NAL_SLICE_IDR )    {        x264_slice_header_init( h, &h->sh, h->sps, h->pps, h->i_idr_pic_id, h->i_frame_num, i_global_qp );        /* increment id */        h->i_idr_pic_id = ( h->i_idr_pic_id + 1 ) % 65536;    }    else    {        x264_slice_header_init( h, &h->sh, h->sps, h->pps, -1, h->i_frame_num, i_global_qp );        /* 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;    }    h->fdec->i_frame_num = h->sh.i_frame_num;    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 ? */    }    x264_macroblock_slice_init( h );}static void x264_slice_write( x264_t *h ){    int i_skip;    int mb_xy;    int i;    /* init stats */    memset( &h->stat.frame, 0, sizeof(h->stat.frame) );    /* Slice */    x264_nal_start( h, h->i_nal_type, h->i_nal_ref_idc );    /* Slice header */    x264_slice_header_write( &h->out.bs, &h->sh, h->i_nal_ref_idc );    if( h->param.b_cabac )    {        /* alignment needed */        bs_align_1( &h->out.bs );        /* init cabac */        x264_cabac_context_init( &h->cabac, h->sh.i_type, h->sh.i_qp, h->sh.i_cabac_init_idc );        x264_cabac_encode_init ( &h->cabac, h->out.bs.p, h->out.bs.p_end );    }    h->mb.i_last_qp = h->sh.i_qp;    h->mb.i_last_dqp = 0;    for( mb_xy = h->sh.i_first_mb, i_skip = 0; mb_xy < h->sh.i_last_mb; )    {        const int i_mb_y = mb_xy / h->sps->i_mb_width;        const int i_mb_x = mb_xy % h->sps->i_mb_width;        int mb_spos = bs_pos(&h->out.bs) + x264_cabac_pos(&h->cabac);        if( i_mb_x == 0 )            x264_fdec_filter_row( h, i_mb_y );        /* load cache */        x264_macroblock_cache_load( h, i_mb_x, i_mb_y );        /* 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 );        TIMER_STOP( i_mtime_analyse );        /* encode this macroblock -> be careful it can change the mb type to P_SKIP if needed */        TIMER_START( i_mtime_encode );        x264_macroblock_encode( h );        TIMER_STOP( i_mtime_encode );        TIMER_START( i_mtime_write );        if( h->param.b_cabac )        {            if( mb_xy > h->sh.i_first_mb && !(h->sh.b_mbaff && (i_mb_y&1)) )                x264_cabac_encode_terminal( &h->cabac, 0 );            if( IS_SKIP( h->mb.i_type ) )                x264_cabac_mb_skip( h, 1 );            else            {                if( h->sh.i_type != SLICE_TYPE_I )                    x264_cabac_mb_skip( h, 0 );                x264_macroblock_write_cabac( h, &h->cabac );            }        }        else        {            if( IS_SKIP( h->mb.i_type ) )                i_skip++;            else            {                if( h->sh.i_type != SLICE_TYPE_I )                {                    bs_write_ue( &h->out.bs, i_skip );  /* skip run */                    i_skip = 0;                }                x264_macroblock_write_cavlc( h, &h->out.bs );            }        }        TIMER_STOP( i_mtime_write );#if VISUALIZE        if( h->param.b_visualize )            x264_visualize_mb( h );#endif        /* save cache */        x264_macroblock_cache_save( h );        /* accumulate mb stats */        h->stat.frame.i_mb_count[h->mb.i_type]++;        if( !IS_SKIP(h->mb.i_type) && !IS_INTRA(h->mb.i_type) && !IS_DIRECT(h->mb.i_type) )        {            if( h->mb.i_partition != D_8x8 )                h->stat.frame.i_mb_count_size[ x264_mb_partition_pixel_table[ h->mb.i_partition ] ] += 4;            else                for( i = 0; i < 4; i++ )                    h->stat.frame.i_mb_count_size[ x264_mb_partition_pixel_table[ h->mb.i_sub_partition[i] ] ] ++;            if( h->param.i_frame_reference > 1 )            {                for( i = 0; i < 4; i++ )                {                    int i_ref = h->mb.cache.ref[0][ x264_scan8[4*i] ];                    if( i_ref >= 0 )                        h->stat.frame.i_mb_count_ref[i_ref] ++;                }            }        }        if( h->mb.i_cbp_luma && !IS_INTRA(h->mb.i_type) )

⌨️ 快捷键说明

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