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

📄 t264.c

📁 T.264源代码(基于VC开发环境 最新版本)
💻 C
📖 第 1 页 / 共 2 页
字号:
            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;
}

int32_t 
decode(const char* filename)
{
    /* just for show how to drive the decoder */
#define BUFFER_SIZE 4096
    T264_t* t = T264dec_open();
    uint8_t buffer[BUFFER_SIZE + 4];
    int32_t run = 1,screen = 0;
    FILE* src_file = fopen(filename, "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", filename);
        return -1;
    }
    if (rec_path[0])
    {
        f_rec = fopen(rec_path, "wb");
        if (!f_rec)
        {
            printf("cannot open rec file %s.\n", rec_path);
        }
    }
	//for decoder PSNR
	if(ref_path[0])
	{
		f_ref = fopen(ref_path, "rb");
		if(!f_ref)
		{
			printf("cannot open ref file %s.\n", ref_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);
#ifdef USE_DISPLAY
                winDisplay(t, T264dec_flush_frame(t));
#endif
                frame_nums ++;
            }
            break;
        case DEC_STATE_PIC:
            /* write one pic */
            break;
        case DEC_STATE_SEQ:

#ifdef USE_DISPLAY
            if (screen == 0)
            {
#ifndef __GCC__
                initDisplay(t->width, t->height);
#else
                init_display("",t->width, t->height);
#endif
                screen++;
            }

#endif
            if (t->frame_id > 0)
            {
                /* NOTE: here we should get the last frame */
                write_frame(t, T264dec_flush_frame(t), f_rec);
    #ifdef USE_DISPLAY
                winDisplay(t, T264dec_flush_frame(t));
    #endif
                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);
						}
					}
				}
#ifdef USE_DISPLAY
                    winDisplay(t, &t->output);
#endif
                    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;
        }
    };

#ifndef CHIP_DM642
#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);
#endif    
#ifdef CHIP_DM642
	printf("fps: %.2ffps(total decode: %d frames).\n", (float)frame_nums / total_time, frame_nums);
#endif
    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);
#ifdef USE_DISPLAY
    uninit_display();
#endif

    return 0;
}

void
help()
{
    printf("Usage:\n"
        "\tt264 -d test.264 [rec_path] [reference_path] [skip_num](to decode a 264 file.)\n"
        "\tt264 -e enconfig.txt (to encode a 264 file.)\n");
}

int 
main(int argc, char* argv[])
{
    int32_t i;
    int32_t is_encode = 0;
    int32_t is_decode = 0;
    char* file_name;

    printf("T264 ver: %d.%02d\n", T264_MAJOR, T264_MINOR);
    if (argc < 3)
    {
        help();
        return 0;
    }

    for (i = 1 ; i < 3 ; i ++)
    {
        if (strcmp(argv[i], "-d") == 0)
        {
            is_decode = 1;
        }
        else if(strcmp(argv[i], "-e") == 0)
        {
            is_encode = 1;
        }
        else
        {
            file_name = argv[i];
        }
    }

    if (is_encode)
    {
        return encode(file_name);
    }

    if (is_decode)
    {
        if (argc <= 3)
            rec_path[0] = 0;
        else
		{
			strcpy(rec_path, argv[3]);
		}
		if(argc <= 4)
		{
			ref_path[0] = 0;
		}
		else
		{
			strcpy(ref_path, argv[4]);
		}
		if(argc > 5)
		{
			ref_skip = atoi(argv[5]);
		}
        return decode(file_name);
    }

    help();

    return -1;
}

⌨️ 快捷键说明

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