www.pudn.com > T264-src-0.02.zip > T264.c


/***************************************************************************** 
 * 
 *  T264 AVC CODEC 
 * 
 *  Copyright(C) 2004-2005 llcc  
 *               2004-2005 visionany  
 * 
 *  This program is free software ; you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation ; either version 2 of the License, or 
 *  (at your option) any later version. 
 * 
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY ; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details. 
 * 
 *  You should have received a copy of the GNU General Public License 
 *  along with this program ; if not, write to the Free Software 
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
 * 
 ****************************************************************************/ 
 
// T264.cpp : Defines the entry point for the console application. 
// 
 
#include "stdio.h" 
#include "stdlib.h" 
#include "memory.h" 
#include "math.h" 
#include "T264.h" 
#include "timer.h" 
 
// parameters begin 
int32_t total_no = 300; 
char src_path[256]; 
char out_path[256]; 
char rec_path[256]; 
// parameters end 
 
void 
init_param(T264_param_t* param, const char* file) 
{ 
    FILE* fd;  
    char line[255]; 
    int32_t b; 
    if (!(fd = fopen(file,"r"))) 
    { 
        printf("Couldn't open parameter file %s.\n", file); 
        exit(-1); 
    } 
 
    memset(param, 0, sizeof(*param)); 
    fgets(line, 254, fd);   // discard 
    fgets(line, 254, fd); sscanf(line,"%d", ¶m->width); 
    fgets(line, 254, fd); sscanf(line,"%d", ¶m->height); 
    fgets(line, 254, fd); sscanf(line,"%d", ¶m->search_x); 
    fgets(line, 254, fd); sscanf(line,"%d", ¶m->search_y); 
    fgets(line, 254, fd); sscanf(line,"%d", &total_no); 
    fgets(line, 254, fd); sscanf(line,"%d", ¶m->iframe); 
    fgets(line, 254, fd); sscanf(line,"%d", ¶m->idrframe); 
    fgets(line, 254, fd); sscanf(line,"%d", ¶m->bitrate); 
    fgets(line, 254, fd); sscanf(line,"%f", ¶m->framerate); 
    fgets(line, 254, fd); sscanf(line,"%d", ¶m->qp); 
    fgets(line, 254, fd); sscanf(line,"%d", ¶m->min_qp); 
    fgets(line, 254, fd); sscanf(line,"%d", ¶m->max_qp); 
    fgets(line, 254, fd); sscanf(line,"%d", ¶m->disable_filter); 
    fgets(line, 254, fd); sscanf(line,"%d", ¶m->aspect_ratio); 
    fgets(line, 254, fd); sscanf(line,"%d", ¶m->video_format); 
    fgets(line, 254, fd); sscanf(line,"%d", ¶m->luma_coeff_cost); 
    fgets(line, 254, fd); sscanf(line,"%d", &b); 
    param->flags |= (USE_INTRA16x16) * b; 
    fgets(line, 254, fd); sscanf(line,"%d", &b); 
    param->flags |= (USE_INTRA4x4) * b; 
    fgets(line, 254, fd); sscanf(line,"%d", &b); 
    param->flags |= (USE_HALFPEL) * b; 
    fgets(line, 254, fd); sscanf(line,"%d", &b); 
    param->flags |= (USE_QUARTPEL) * b; 
    fgets(line, 254, fd); sscanf(line,"%d", &b); 
    param->flags |= (USE_SUBBLOCK) * b; 
    fgets(line, 254, fd); sscanf(line,"%d", &b); 
    param->flags |= (USE_FULLSEARCH) * b; 
    fgets(line, 254, fd); sscanf(line,"%d", &b); 
    param->flags |= (USE_DIAMONDSEACH) * b; 
    fgets(line, 254, fd); sscanf(line,"%d", &b); 
    param->flags |= (USE_FORCEBLOCKSIZE) * b; 
    fgets(line, 254, fd); sscanf(line,"%d", &b); 
    param->flags |= (USE_EXTPSKIPDETECT) * b; 
    fgets(line, 254, fd); sscanf(line,"%d", &b); 
    param->flags |= (USE_SAD) * b; 
    fgets(line, 254, fd); sscanf(line,"%d", &b); 
    param->block_size |= (SEARCH_16x16P) * b; 
    fgets(line, 254, fd); sscanf(line,"%d", &b); 
    param->block_size |= (SEARCH_16x8P) * b; 
    fgets(line, 254, fd); sscanf(line,"%d", &b); 
    param->block_size |= (SEARCH_8x16P) * b; 
    fgets(line, 254, fd); sscanf(line,"%d", &b); 
    param->block_size |= (SEARCH_8x8P) * b; 
    fgets(line, 254, fd); sscanf(line,"%d", &b); 
    param->block_size |= (SEARCH_8x4P) * b; 
    fgets(line, 254, fd); sscanf(line,"%d", &b); 
    param->block_size |= (SEARCH_4x8P) * b; 
    fgets(line, 254, fd); sscanf(line,"%d", &b); 
    param->block_size |= (SEARCH_4x4P) * b; 
    fgets(line, 254, fd); sscanf(line,"%d", ¶m->cpu); 
 
    fgets(line, 254, fd); sscanf(line,"%s", src_path); 
    fgets(line, 254, fd); sscanf(line,"%s", out_path); 
    fgets(line, 254, fd); sscanf(line,"%s", rec_path); 
 
    fclose(fd); 
} 
 
int  
main(int argc, char* argv[]) 
{ 
    T264_param_t param; 
    T264_t* t; 
    uint8_t* buf, *dst; 
    int32_t size; 
    FILE* in_file, *rec_file, *out_file; 
    uint32_t len; 
	int32_t frame_no; 
	int32_t bs_len = 0; 
  
    int32_t i; 
    uint8_t* rec; 
 
	T264_stat_t stat_prev; 
    timer_t timer; 
    float cpu_freq = 0.0f; 
 
    printf("T264 ver: %d.%02d\n", T264_MAJOR, T264_MINOR); 
    printf("Detect cpu freq..."); 
    for(i = 0 ; i < 4 ; i ++) 
    { 
        init_timer(&timer); 
        start_timer(&timer); 
        _sleep(1000); 
        stop_timer_all(&timer); 
        cpu_freq += (float)timer.all; 
    } 
    cpu_freq /= 4.0f; 
    printf("%.2fGhz\n", cpu_freq / 1000000000.0f); 
 
    if (argc < 2) 
    { 
        printf("Usage: T264 enconfig.txt.\n"); 
        return 0; 
    } 
 
    init_param(¶m, argv[1]); 
 
    param.ref_num  = 1; 
    t = T264_open(¶m); 
 
    /* YV12p */ 
    size = param.height * param.width + (param.height * param.width >> 1); 
    buf = T264_malloc(size, CACHE_SIZE); 
    in_file = fopen(src_path, "rb"); 
	if (!in_file) 
    { 
        printf("cannot open input file."); 
        return 0; 
    } 
 
    rec_file = fopen(rec_path, "wb"); 
    if (!rec_file) 
    { 
        printf("cannot open write file."); 
        return 0; 
    } 
 
    out_file = fopen(out_path, "wb"); 
    if (!out_file) 
    { 
        printf("cannot write 264 file.\n"); 
        return 0; 
    } 
 
    dst = T264_malloc(size, CACHE_SIZE); 
    rec = T264_malloc(size, CACHE_SIZE); 
 
	stat_prev.i_block_num[0] = stat_prev.i_block_num[1] = 0; 
	for(i = 0; i < 8; i++) 
		stat_prev.p_block_num[i] = 0; 
	stat_prev.skip_block_num = 0; 
	 
    init_timer(&timer); 
    start_timer(&timer); 
	for(frame_no = 0; frame_no < total_no; frame_no++) 
	{ 
		if (fread(buf, size, 1, in_file) <= 0) 
			printf("cannot read from input file."); 
 
	    len = T264_encode(t, buf, dst, size); 
		bs_len += len; 
 
		for(i = 0 ; i < param.height ; i ++) 
        { 
            memcpy(rec + i * param.width, t->refn[1].Y[0] + i * t->edged_stride, param.width); 
            if (fwrite(t->refn[1].Y[0] + i * t->edged_stride, param.width, 1, rec_file) <= 0) 
			    printf("cannot write to file."); 
        } 
 
        for(i = 0 ; i < param.height >> 1; i ++) 
        { 
            memcpy(rec + param.height * param.width + (i * param.width >> 1), t->refn[1].U + i * t->edged_stride_uv, param.width >> 1); 
            if (fwrite(t->refn[1].U + i * t->edged_stride_uv, param.width >> 1, 1, rec_file) <= 0) 
                printf("cannot write to file."); 
        } 
 
        for(i = 0 ; i < param.height >> 1; i ++) 
        { 
            memcpy(rec + (int32_t)(param.height * param.width * 1.25) + (i * param.width >> 1), t->refn[1].V + i * t->edged_stride_uv, param.width >> 1); 
            if (fwrite(t->refn[1].V + i * t->edged_stride_uv, param.width >> 1, 1, rec_file) <= 0) 
                printf("cannot write to file."); 
        } 
 
        if (fwrite(dst, len, 1, out_file) < 0) 
			printf("cannot write 264 file.\n"); 
		 
        printf("No:%d\t i4x4:%d\t i16x16:%d\t skip:%d\n\t p16x16:%d\t p16x8:%d\t p8x16:%d\t p8x8:%d\n\t QP=%d\t\t Len=%d \n\t Y:%.4f\t U:%.4f\t V:%.4f.\n",  
			   frame_no,  
               t->stat.i_block_num[I_4x4] - stat_prev.i_block_num[I_4x4],  
               t->stat.i_block_num[I_16x16] - stat_prev.i_block_num[I_16x16],  
               t->stat.skip_block_num - stat_prev.skip_block_num, 
			   t->stat.p_block_num[MB_16x16] - stat_prev.p_block_num[MB_16x16],  
               t->stat.p_block_num[MB_16x8] - stat_prev.p_block_num[MB_16x8],  
               t->stat.p_block_num[MB_8x16] - stat_prev.p_block_num[MB_8x16],  
               t->stat.p_block_num[MB_8x8] - stat_prev.p_block_num[MB_8x8],  
               t->qp_y, len, 
               psnr(rec, buf, param.width * param.height), 
               psnr(rec + param.width * param.height, buf + param.width * param.height, param.width * param.height >> 2), 
               psnr(rec + (int32_t)(param.width * param.height * 1.25), buf + (int32_t)(param.width * param.height * 1.25), param.width * param.height >> 2)); 
 
		stat_prev = t->stat; 
	} 
    stop_timer_all(&timer); 
    printf("fps: %.2ffps with cpu %.2fGHz, Length of Bitstream = %d Compact Ratio = %.2f\n", (total_no / ((float)timer.all / cpu_freq)), cpu_freq / 1000000000.0f, bs_len, 1.0 * total_no * size / bs_len); 
 
    fclose(in_file); 
    fclose(out_file); 
    fclose(rec_file); 
    T264_free(dst); 
    T264_free(rec); 
    T264_close(t); 
 
	return 0; 
}