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

📄 t264.c

📁 经过开源的H.264压缩算法代码
💻 C
字号:
/*****************************************************************************
*
*  T264 AVC CODEC
*
*  Copyright(C) 2004-2005 llcc <lcgate1@yahoo.com.cn>
*               2004-2005 visionany <visionany@yahoo.com.cn>
*
*  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 "config.h"

#include "stdio.h"
#include "sys/timeb.h"
#include "time.h"

#include "stdlib.h"
#include "memory.h"

#include "math.h"
#include "T264.h"
#include "utility.h"
#include "string.h"


// parameters begin
int32_t total_no = 90;
char src_path[256];
char out_path[256];

// for decoder PSNR
static int  ref_skip;

// parameters end
char file_name[] = "E:\\T264_2006_10_26\\sequences\\encoded.264";                //编码后264文件路径   
char rec_path[] = "E:\\T264_2006_10_26\\sequences\\decoded.yuv";                 //解码后YUV文件路径      

#define BUFFER_SIZE 4096

void
write_frame(T264_t* t,T264_frame_t *frame,FILE *f_rec)
{
    int	i;
    uint8_t* p;

    if (f_rec)
    {
        p = frame->Y[0];
        for(i = 0 ; i < t->height ; i ++)
        {
            fwrite(p, t->width, 1, f_rec);
            p += t->edged_stride;
        }
        p = frame->U;
        for(i = 0 ; i < t->height >> 1 ; i ++)
        {
            fwrite(p, t->width >> 1, 1, f_rec);
            p += t->edged_stride_uv;
        }
        p = frame->V;
        for(i = 0 ; i < t->height >> 1 ; i ++)
        {
            fwrite(p, t->width >> 1, 1, f_rec);
            p += t->edged_stride_uv;
        }
    }
}
static float __inline
dec_psnr(uint8_t* p1, uint8_t* p2, int32_t width1, int32_t width2, int32_t height, int print)
{
	float sad = 0, psnr;
	int32_t i, j, size, ii, jj, diff, iii, jjj;
	uint8_t* p11, *p22;
	for(j=0; j<height; j+=16)
	{
		for (i = 0 ; i < width2 ; i +=16)
		{
			p11 = p1+i;
			p22 = p2+i;
			diff = 0;
			for(jj=0; jj<16; jj++)
			{
				for(ii=0; ii<16; ii++)
				{
					int32_t tmp;
					tmp = (p11[ii] - p22[ii]);
					sad += tmp * tmp;
					if(tmp != 0 && diff != 1)
					{
						if(print)
							printf("%2d != %2d ", p11[ii], p22[ii]);
						iii = ii;
						jjj = jj;
						diff = 1;
					}
				}
				p11 += width1;
				p22 += width2;
			}
			if(diff && print)
			{
				printf("%4d, %2d, %2d\n", (j)*(width2>>4) + (i), iii, jjj);
				print = 0;
			}
		}
		p1 += width1*16;
		p2 += width2*16;
	}
	size = width2 * height;
	if(sad < 1e-6)
		psnr = 0.0f;
	else
		psnr = (float)(10 * log10(65025.0f * size / sad));
	return psnr;
}

int 
main()
{
    /* just for show how to drive the decoder */
    T264_t* t = T264dec_open();
    uint8_t buffer[BUFFER_SIZE + 4];
    int32_t run = 1,screen = 0;
    FILE* src_file = fopen(file_name, "rb");
    size_t size;
    FILE* f_rec = 0;
	//for decoder PSNR
	int frame_num = 0;
	FILE* f_ref = 0;
	uint8_t *ref_buf = NULL;
    int32_t frame_nums = 0;

    float total_time;
#ifdef _WIN32
    struct _timeb beg, end;
#endif
	
    // xxx
    printf("Current fully support t264 encoder's bitstream.\n");

    if (!src_file)
    {
        printf("cannot open file %s.\n", file_name);
        return -1;
    }
    if (rec_path[0])
    {
        f_rec = fopen(rec_path, "wb");
        if (!f_rec)
        {
            printf("cannot open rec file %s.\n", rec_path);
        }
    }

#ifdef _WIN32
    _ftime(&beg);
#endif
    while (run) 
    {
        decoder_state_t state = T264dec_parse(t);
        switch(state) 
        {
        case DEC_STATE_BUFFER:
            /* read more data */
            size = fread(buffer, 1, BUFFER_SIZE, src_file);
            if (size > 0)
            {
                if (size != BUFFER_SIZE)
                {
                    buffer[size] = 0;
                    buffer[size + 1] = 0;
                    buffer[size + 2] = 0;
                    buffer[size + 3] = 1;
                    size += 4;
                }

                T264dec_buffer(t, buffer, size);
            }
            else
            {
                /* if all data has readed, here we will return */
                run = 0;
                /* NOTE: here we should get the last frame */
                write_frame(t, T264dec_flush_frame(t), f_rec);
                frame_nums ++;
            }
            break;
        case DEC_STATE_PIC:
            /* write one pic */
            break;
        case DEC_STATE_SEQ:

            if (t->frame_id > 0)
            {
                /* NOTE: here we should get the last frame */
                write_frame(t, T264dec_flush_frame(t), f_rec);

                frame_nums ++;
            }
            printf("ref frames num: %d.\n", t->ss.num_ref_frames);
            printf("width: %d.\n", (t->ss.pic_width_in_mbs_minus1 + 1) << 4);
            printf("height: %d.\n", (t->ss.pic_height_in_mbs_minus1 + 1) << 4);
            break;
        case DEC_STATE_SLICE:
            {
                if (t->output.poc >= 0)
                {
                    write_frame(t, &t->output, f_rec);
				//for decoder PSNR
				if(f_ref)
				{
					float psnr_y, psnr_u, psnr_v;
					int size;
					size = t->width*t->height;
					if(ref_buf == NULL)
					{
						ref_buf = (uint8_t *)malloc(size);
					}
					
					if(ref_buf != NULL)
					{
						uint8_t *p;
						p = t->output.Y[0];
						fread(ref_buf, 1, size, f_ref);
						psnr_y = dec_psnr(p, ref_buf, t->edged_stride, t->width, t->height, 0);

						size >>= 2;
						p = t->output.U;
						fread(ref_buf, 1, size, f_ref);
						psnr_u = dec_psnr(p, ref_buf, t->edged_stride_uv, t->width>>1, t->height>>1, 0);
						p = t->output.V;
						fread(ref_buf, 1, size, f_ref);
						psnr_v = dec_psnr(p, ref_buf, t->edged_stride_uv, t->width>>1, t->height>>1, 0);
						printf("%4d, %.2f, %.2f, %.2f\n", frame_num++, psnr_y, psnr_u, psnr_v);
						if(ref_skip > 0)
						{
							fseek(f_ref, ref_skip*size*6, SEEK_CUR);
						}
					}
				}

                    frame_nums ++;                
                }
            };
            break;
        case DEC_STATE_CUSTOM_SET:
            {
                printf("used fast interpolate: %s.\n", t->flags & USE_FASTINTERPOLATE ? "yes" : "no");
            }
            break;
        default:
            /* do not care */
            break;
        }
    };


#ifdef _WIN32
    _ftime(&end);
    total_time = (float)(end.time - beg.time) + (float)(end.millitm - beg.millitm) / 1000;
#endif
    printf("fps: %.2ffps(total decode: %d frames).\n", (float)frame_nums / total_time, frame_nums);

    T264dec_close(t);
    fclose(src_file);
    if (f_rec)
        fclose(f_rec);
	if (f_ref)
		fclose(f_ref);
	if(ref_buf != NULL)
		free(ref_buf);

    return 0;
}

⌨️ 快捷键说明

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