📄 t264.c
字号:
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 + -