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

📄 encoder.c

📁 H.264编码器
💻 C
📖 第 1 页 / 共 3 页
字号:
/* x264: h264 encoder */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "stdint.h"
//#include "malloc.h"

#include <math.h>

#include "common.h"
#include "x264.h"

#include "me.h"

#include "set.h"
#include "analyse.h"
#include "ratecontrol.h"
#include "macroblock.h"

/****************************************************************************
 *
 ******************************* x264 libs **********************************
 *
 ****************************************************************************/


static float x264_psnr( uint8_t *pix1, int i_pix_stride, uint8_t *pix2, int i_pix2_stride, int i_width, int i_height )
{
    int64_t i_sqe = 0;

    int x, y;

    for( y = 0; y < i_height; y++ )
    {
        for( x = 0; x < i_width; x++ )
        {
            int tmp;

            tmp = pix1[y*i_pix_stride+x] - pix2[y*i_pix2_stride+x];

            i_sqe += tmp * tmp;
        }
    }

    if( i_sqe == 0 )
    {
        return -1.0;
    }
    return (float)(10.0 * log( (double)65025.0 * (double)i_height * (double)i_width / (double)i_sqe ) / log( 10.0 ));
}

/* Fill "default" values */
static void x264_slice_header_init( x264_slice_header_t *sh, x264_param_t *param,
                                    x264_sps_t *sps, x264_pps_t *pps,
                                    int i_type, int i_idr_pic_id, int i_frame )
{
    /* First we fill all field */
    sh->sps = sps;
    sh->pps = pps;

    sh->i_type      = i_type;
    sh->i_first_mb  = 0;
    sh->i_pps_id    = pps->i_id;

    sh->i_frame_num = i_frame;

    sh->b_field_pic = 0;    /* Not field support for now */
    sh->b_bottom_field = 1; /* not yet used */

    sh->i_idr_pic_id = i_idr_pic_id;

    /* poc stuff, fixed later */
    sh->i_poc_lsb = 0;
    sh->i_delta_poc_bottom = 0;
    sh->i_delta_poc[0] = 0;
    sh->i_delta_poc[1] = 0;

    sh->i_redundant_pic_cnt = 0;

    sh->b_direct_spatial_mv_pred = 0;

    sh->b_num_ref_idx_override = 0;
    sh->i_num_ref_idx_l0_active = 1;
    sh->i_num_ref_idx_l1_active = 1;

    sh->i_cabac_init_idc = param->i_cabac_init_idc;

    sh->i_qp_delta = 0;
    sh->b_sp_for_swidth = 0;
    sh->i_qs_delta = 0;

    if( param->b_deblocking_filter )
    {
        sh->i_disable_deblocking_filter_idc = 0;
    }
    else
    {
        sh->i_disable_deblocking_filter_idc = 1;
    }
    sh->i_alpha_c0_offset = 0;
    sh->i_beta_offset = 0;
}

static void x264_slice_header_write( bs_t *s, x264_slice_header_t *sh, int i_nal_ref_idc )
{
    bs_write_ue( s, sh->i_first_mb );
    bs_write_ue( s, sh->i_type + 5 );   /* same type things */
    bs_write_ue( s, sh->i_pps_id );
    bs_write( s, sh->sps->i_log2_max_frame_num, sh->i_frame_num );

    if( sh->i_idr_pic_id >= 0 ) /* NAL IDR */
    {
        bs_write_ue( s, sh->i_idr_pic_id );
    }

    if( sh->sps->i_poc_type == 0 )
    {
        bs_write( s, sh->sps->i_log2_max_poc_lsb, sh->i_poc_lsb );
        if( sh->pps->b_pic_order && !sh->b_field_pic )
        {
            bs_write_se( s, sh->i_delta_poc_bottom );
        }
    }
    else if( sh->sps->i_poc_type == 1 && !sh->sps->b_delta_pic_order_always_zero )
    {
        bs_write_se( s, sh->i_delta_poc[0] );
        if( sh->pps->b_pic_order && !sh->b_field_pic )
        {
            bs_write_se( s, sh->i_delta_poc[1] );
        }
    }

    if( sh->pps->b_redundant_pic_cnt )
    {
        bs_write_ue( s, sh->i_redundant_pic_cnt );
    }

    if( sh->i_type == SLICE_TYPE_B )
    {
        bs_write1( s, sh->b_direct_spatial_mv_pred );
    }
    if( sh->i_type == SLICE_TYPE_P || sh->i_type == SLICE_TYPE_SP || sh->i_type == SLICE_TYPE_B )
    {
        bs_write1( s, sh->b_num_ref_idx_override );
        if( sh->b_num_ref_idx_override )
        {
            bs_write_ue( s, sh->i_num_ref_idx_l0_active - 1 );
            if( sh->i_type == SLICE_TYPE_B )
            {
                bs_write_ue( s, sh->i_num_ref_idx_l1_active - 1 );
            }
        }
    }

    /* ref pic list reordering */
    if( sh->i_type != SLICE_TYPE_I )
    {
        int b_ref_pic_list_reordering_l0 = 0;
        bs_write1( s, b_ref_pic_list_reordering_l0 );
        if( b_ref_pic_list_reordering_l0 )
        {
            /* FIXME */
        }
    }
    if( sh->i_type == SLICE_TYPE_B )
    {
        int b_ref_pic_list_reordering_l1 = 0;
        bs_write1( s, b_ref_pic_list_reordering_l1 );
        if( b_ref_pic_list_reordering_l1 )
        {
            /* FIXME */
        }
    }

    if( ( sh->pps->b_weighted_pred && ( sh->i_type == SLICE_TYPE_P || sh->i_type == SLICE_TYPE_SP ) ) ||
        ( sh->pps->b_weighted_bipred == 1 && sh->i_type == SLICE_TYPE_B ) )
    {
        /* FIXME */
    }

    if( i_nal_ref_idc != 0 )
    {
        if( sh->i_idr_pic_id >= 0 )
        {
            bs_write1( s, 0 );  /* no output of prior pics flag */
            bs_write1( s, 0 );  /* long term reference flag */
        }
        else
        {
            bs_write1( s, 0 );  /* adaptive_ref_pic_marking_mode_flag */
            /* FIXME */
        }
    }

    if( sh->pps->b_cabac && sh->i_type != SLICE_TYPE_I )
    {
        bs_write_ue( s, sh->i_cabac_init_idc );
    }
    bs_write_se( s, sh->i_qp_delta );      /* slice qp delta */
#if 0
    if( sh->i_type == SLICE_TYPE_SP || sh->i_type == SLICE_TYPE_SI )
    {
        if( sh->i_type == SLICE_TYPE_SP )
        {
            bs_write1( s, sh->b_sp_for_swidth );
        }
        bs_write_se( s, sh->i_qs_delta );
    }
#endif

    if( sh->pps->b_deblocking_filter_control )
    {
        bs_write_ue( s, sh->i_disable_deblocking_filter_idc );
        if( sh->i_disable_deblocking_filter_idc != 1 )
        {
            bs_write_se( s, sh->i_alpha_c0_offset >> 1 );
            bs_write_se( s, sh->i_beta_offset >> 1 );
        }
    }
}
#if 0
static void x264_frame_dump( x264_t *h, x264_frame_t *fr, char *name )
{
    FILE * f = fopen( name, "a" );
    int i, y;

    fseek( f, 0, SEEK_END );

    for( i = 0; i < fr->i_plane; i++ )
    {
        for( y = 0; y < h->param.i_height / ( i == 0 ? 1 : 2 ); y++ )
        {
            fwrite( &fr->plane[i][y*fr->i_stride[i]], 1, h->param.i_width / ( i == 0 ? 1 : 2 ), f );
        }
    }
    fclose( f );
}
#endif
/*
static void x264_write_recon( x264_t *h, x264_frame_t *fr, char* recY, char* recU, char* recV)
{
    int y;

    for( y = 0; y < h->param.i_height; y++ )
    {
   //   	fwrite( &fr->plane[0][y*fr->i_stride[0]], 1, h->param.i_width, f );
		memcpy(&recY[y*fr->i_stride[0]], &fr->plane[0][y*fr->i_stride[0]], h->param.i_width);
    }
    for( y = 0; y < h->param.i_height/2; y++ )
    {
		memcpy(&recU[y*fr->i_stride[1]], &fr->plane[1][y*fr->i_stride[1]], h->param.i_width/2);
    }
    for( y = 0; y < h->param.i_height/2; y++ )
    {
		memcpy(&recV[y*fr->i_stride[2]], &fr->plane[2][y*fr->i_stride[2]], h->param.i_width/2);
    }
}
*/
/****************************************************************************
 *
 ****************************************************************************
 ****************************** External API*********************************
 ****************************************************************************
 *
 ****************************************************************************/

/****************************************************************************
 * x264_encoder_open:
 ****************************************************************************/
x264_t *x264_encoder_open   ( x264_param_t *param )
{
	int i;
    x264_me_t me[2];    
	x264_t *h;	
	h =(x264_t * )x264_malloc(sizeof( x264_t ));
   

	if( param->i_width <= 0  || param->i_height <= 0 )
    {
        fprintf( stderr, "invalid width x height (%dx%d)\n",
                 param->i_width, param->i_height );
        free( h );
        return NULL;
    }

    if( param->i_width % 16 != 0 || param->i_height % 16 != 0 )
    {
        fprintf( stderr, "width %% 16 != 0 pr height %% 16 != 0 (%dx%d)\n",
                 param->i_width, param->i_height );
        free( h );
        return NULL;
    }
    
//    h->param.b_cabac=param->b_cabac; 
/*	h->param.b_deblocking_filter=param->b_deblocking_filter;
	h->param.cpu = param->cpu ;
	h->param.f_fps = param->f_fps; 
	h->param.i_bframe = param->i_bframe; 
	h->param.i_bitrate = param->i_bitrate; 
	h->param.i_cabac_init_idc = param->i_cabac_init_idc; 
	h->param.i_frame_reference = param->i_frame_reference; 
	h->param.i_height = param->i_height ;
	h->param.i_idrframe = param->i_idrframe; 
	h->param.i_iframe = param->i_iframe ;
	h->param.i_me = param->i_me ;
	h->param.i_qp_constant = param->i_qp_constant ;
	h->param.i_width = param->i_width ;
	h->param.vui = param->vui ;
*/	
    memcpy( &h->param, param, sizeof(x264_param_t ));
    if( h->param.i_frame_reference <= 0 )
    {
        h->param.i_frame_reference = 1;
    }
    else if( h->param.i_frame_reference > 15 )
    {
        h->param.i_frame_reference = 15;
    }
    if( h->param.i_idrframe <= 0 )
    {
        h->param.i_idrframe = 1;
    }
    if( h->param.i_iframe <= 0 )
    {
        h->param.i_iframe = 1;
    }
    if( h->param.i_bframe < 0 )
    {
        h->param.i_bframe = 0;
    }
    else if( h->param.i_bframe > X264_BFRAME_MAX )
    {
        h->param.i_bframe = X264_BFRAME_MAX;
    }
    /* XXX for now we use fixed patern IB...BPB...BPB...BP */
    if( h->param.i_bframe > 0 )
    {
        h->param.i_iframe = ((h->param.i_iframe - 1)/(h->param.i_bframe+1))*(h->param.i_bframe+1) + 1;

        if( h->param.b_cabac )
        {
            fprintf( stderr, "cabac not supported with B frame (cabac disabled)\n" );
            h->param.b_cabac = 0;
        }
    }

    if( h->param.i_cabac_init_idc < -1 )	
    {
        h->param.i_cabac_init_idc = -1;
    }
    else if( h->param.i_cabac_init_idc > 2 )
    {
        h->param.i_cabac_init_idc = 2;
    }

	
//    h->cpu = param->cpu;

    h->i_nal = 0;
    h->i_bitstream = 1000000; /* FIXME calculate max size from width/height */
    h->p_bitstream =(uint8_t *) x264_malloc( h->i_bitstream );

    h->i_frame = 0;
    h->i_frame_num = 0;
    h->i_poc   = 0;
    h->i_idr_pic_id = 0;

    h->sps = &h->sps_array[0];
    x264_sps_init( h->sps, 0, &h->param );

    h->pps = &h->pps_array[0];
    x264_pps_init( h->pps, 0, &h->param, h->sps);

    /* init picture and bframe context */
    h->picture = NULL;
    for( i = 0; i < X264_BFRAME_MAX; i++ )
    {
        h->bframe_current[i]= NULL;

⌨️ 快捷键说明

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