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

📄 x264.c

📁 H.264编码器
💻 C
字号:
/* x264: h264 encoder/decoder testing program */

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

#include <math.h>

//#include <signal.h>
#define _GNU_SOURCE

#ifdef _MSC_VER
#include <io.h>     /* _setmode() */
#include <fcntl.h>  /* _O_BINARY */
#endif

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

#define DATA_MAX 3000000
uint8_t data[DATA_MAX];

x264_t *h;
x264_param_t param;
x264_picture_t *pic;
int64_t i_size;
FILE    *fyuv;
FILE    *fout = stdout;
int     i_frame, i_frame_total;
int64_t i_start, i_end;
int64_t i_file;


char* rY;
char* rU;
char* rV;

x264_frame_t * recon_temp;

/* Ctrl-C handler */
static int     i_ctrl_c = 0;
static void    SigIntHandler( int a )
{
    i_ctrl_c = 1;
}

/****************************************************************************
 * main:
 ****************************************************************************/
void init_x264(int width, int height)
{
    x264_param_default( &param );

	if( ( fyuv = fopen("e:\\foreman.qcif", "rb" ) ) == NULL )
	{
//		cout<<"could not open yuv input file"<<endl;
		;
	}

	i_size = ftell( fyuv );
	
	if( ( fout = fopen("c:\\out.h26l", "wb" ) ) == NULL )
	{
//		cout<<"cannot open output file"<<endl;
	}

	param.i_width = width;
	param.i_height = height;
	
    i_frame_total = 0;
	if( !fseek( fyuv, 0, SEEK_END ) )
	{
		int64_t i_size = ftell( fyuv );
		fseek( fyuv, 0, SEEK_SET );
		i_frame_total = i_size / ( param.i_width * param.i_height * 3 / 2 );
	}
	
 	if( ( h = x264_encoder_open( &param ) ) == NULL )
	{
//		cout<< "x264_encoder_open failed"<<endl;
	}
    pic = x264_picture_new( h );
}

void x264_encode_one_frame(char* Y, char* U, char* V)
{
	int         i_nal;
    x264_nal_t  *nal;
    int         i;
	
	pic->plane[0]=Y;
	pic->plane[1]=U;
	pic->plane[2]=V;
        
	if( x264_encoder_encode( h, &nal, &i_nal, pic) < 0 )
	{
		fprintf( stderr, "x264_encoder_encode failed\n" );
	}
		
	for( i = 0; i < i_nal; i++ )
	{
		int i_size;
		int i_data;
	
		i_data = DATA_MAX;
		if( ( i_size = x264_nal_encode( data, &i_data, 1, &nal[i] ) ) > 0 )
		{
			i_file += fwrite( data, 1, i_size, fout );
		}
		else if( i_size < 0 )
		{
			fprintf( stderr,"need to increase buffer size (size=%d)\n", -i_size );
		}
	}
}


void x264_get_recon(char * reconY, char * reconU, char * reconV)
{
    int y;
	int stride=h->fdec->i_stride[0];
    for( y = 0; y < h->param.i_height; y++ )
    {
		//memcpy(&reconY[y*h->param.i_width], &h->fdec->plane[0][y*stride], h->param.i_width);
		memcpy(&reconY[y*h->param.i_width], &recon_temp->plane[0][y*stride], h->param.i_width);
    }
    for( y = 0; y < h->param.i_height/2; y++ )
    {
		//memcpy(&reconU[y*h->param.i_width/2], &h->fdec->plane[1][y*stride/2], h->param.i_width/2);
		memcpy(&reconU[y*h->param.i_width/2], &recon_temp->plane[1][y*stride/2], h->param.i_width/2);
    }
    for( y = 0; y < h->param.i_height/2; y++ )
    {
		//memcpy(&reconV[y*h->param.i_width/2], &h->fdec->plane[2][y*stride/2], h->param.i_width/2);
		memcpy(&reconV[y*h->param.i_width/2], &recon_temp->plane[2][y*stride/2], h->param.i_width/2);
    }
}



void close_x264()
{
	x264_picture_delete( pic );
	x264_encoder_close( h );
	fprintf( stderr, "\n" );

	fclose( fyuv );
	if( fout != stdout )
	{
		fclose( fout );
	}
	
	if( i_frame > 0 )
	{
		double fps = (double)i_frame * (double)1000000 /(double)( i_end - i_start );
		fprintf( stderr, "encoded %d frames %ffps %lld kb/s\n", i_frame, fps, i_file * 8 * 25 / i_frame / 1000 );
	}
}


void main()
{
	char* bufU;
	char* bufV;
	char* bufY;
	char* rY;
	char* rU;
	char* rV;

	FILE * recon;
	int len;
    int  i, numread, numwritten;
	
/////////////////////////////////////////////////

	init_x264(176,144);	
	//recon_temp = h->fdec;
	

//////////////////////////////////////////////////

	bufU=(char*) malloc(param.i_width * param.i_height/2);	
	bufV=(char*) malloc(param.i_width * param.i_height/2);
	bufY=(char*) malloc(param.i_width * param.i_height);

	rU=(char*) malloc(param.i_width * param.i_height/2);
	rV=(char*) malloc(param.i_width * param.i_height/2);
	rY=(char*) malloc(param.i_width * param.i_height);

 	recon = fopen( "c:\\repak.yuv", "w+t" );

    //   fseek( recon, 0, SEEK_SET );

    i_start = x264_mdate();

	//   
	for( i_frame = 0, i_file = 0;i_frame < 50 && i_ctrl_c == 0 ; i_frame++ )
	{
		int         i_nal;
        x264_nal_t  *nal;
	
        int         i;
	
        // read a frame 
		if( fread(bufY, 1, param.i_width * param.i_height, fyuv ) <= 0 ||
            fread(bufU, 1, param.i_width * param.i_height / 4, fyuv ) <= 0 ||
            fread(bufV, 1, param.i_width * param.i_height / 4, fyuv ) <= 0 )
		{
			break;
		}
	
		recon_temp = h->fdec;
		
		x264_encode_one_frame(bufY, bufU, bufV);
		x264_get_recon(rY, rU, rV);


     	len=h->param.i_height*h->param.i_width;

		fwrite( rY, sizeof(char), len, recon );
		fwrite( rU, sizeof(char), len/4, recon );
		fwrite( rV, sizeof(char), len/4, recon );
	}

	i_end = x264_mdate();
	close_x264();
    fclose( recon );

	free(bufU);
	free(bufV);
	free(bufY);
	free(rU);
	free(rV);
	free(rY);
}



/*
void main()
{
    x264_t *h;
    x264_param_t param;
    x264_picture_t *pic;
    int64_t i_size;
    FILE    *fyuv;
    FILE    *fout = stdout;
    int     i_frame, i_frame_total;
    int64_t i_start, i_end;
    int64_t i_file;


#ifdef _MSC_VER
    _setmode(_fileno(stdin), _O_BINARY);    // thanks to Marcos Morais <morais at dee.ufcg.edu.br> 
    _setmode(_fileno(stdout), _O_BINARY);
#endif

    x264_param_default( &param );
	
	if( ( fyuv = fopen("d:\\in.yuv", "rb" ) ) == NULL )
	{
//		cout<<"could not open yuv input file"<<endl;
		;
	}

	i_size = ftell( fyuv );
	
	if( ( fout = fopen("d:\\out.h26l", "wb" ) ) == NULL )
	{
//		cout<<"cannot open output file"<<endl;
	}
	
	param.i_width = 176;
	param.i_height = 144;
	
    i_frame_total = 0;
	if( !fseek( fyuv, 0, SEEK_END ) )
	{
		int64_t i_size = ftell( fyuv );
		fseek( fyuv, 0, SEEK_SET );
		i_frame_total = i_size / ( param.i_width * param.i_height * 3 / 2 );
	}
	
 	if( ( h = x264_encoder_open( &param ) ) == NULL )
	{
//		cout<< "x264_encoder_open failed"<<endl;
	}

    pic = x264_picture_new( h );
	
    i_start = x264_mdate();
	
	for( i_frame = 0, i_file = 0; i_ctrl_c == 0 ; i_frame++ )
	{
		int         i_nal;
        x264_nal_t  *nal;
	
        int         i;
	
        // read a frame 
		if( fread( pic->plane[0], 1, param.i_width * param.i_height, fyuv ) <= 0 ||
            fread( pic->plane[1], 1, param.i_width * param.i_height / 4, fyuv ) <= 0 ||
            fread( pic->plane[2], 1, param.i_width * param.i_height / 4, fyuv ) <= 0 )
		{
			break;
		}
	
        if( x264_encoder_encode( h, &nal, &i_nal, pic ) < 0 )
		{
			fprintf( stderr, "x264_encoder_encode failed\n" );
		}
		
		for( i = 0; i < i_nal; i++ )
		{
			int i_size;
			int i_data;
	
			i_data = DATA_MAX;
			if( ( i_size = x264_nal_encode( data, &i_data, 1, &nal[i] ) ) > 0 )
			{
				i_file += fwrite( data, 1, i_size, fout );
			}
			else if( i_size < 0 )
			{
				fprintf( stderr,"need to increase buffer size (size=%d)\n", -i_size );
			}
		}
	}
	
	i_end = x264_mdate();
	x264_picture_delete( pic );
	x264_encoder_close( h );
	fprintf( stderr, "\n" );

	fclose( fyuv );
	if( fout != stdout )
	{
		fclose( fout );
	}
	
	if( i_frame > 0 )
	{
		double fps = (double)i_frame * (double)1000000 /(double)( i_end - i_start );
		fprintf( stderr, "encoded %d frames %ffps %lld kb/s\n", i_frame, fps, i_file * 8 * 25 / i_frame / 1000 );
	}
}
*/



⌨️ 快捷键说明

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