T264.c
上传用户:sunbaby
上传日期:2013-05-31
资源大小:242k
文件大小:17k
源码类别:

mpeg/mp3

开发平台:

Visual C++

  1. /*****************************************************************************
  2. *
  3. *  T264 AVC CODEC
  4. *
  5. *  Copyright(C) 2004-2005 llcc <lcgate1@yahoo.com.cn>
  6. *               2004-2005 visionany <visionany@yahoo.com.cn>
  7. *
  8. *  This program is free software ; you can redistribute it and/or modify
  9. *  it under the terms of the GNU General Public License as published by
  10. *  the Free Software Foundation ; either version 2 of the License, or
  11. *  (at your option) any later version.
  12. *
  13. *  This program is distributed in the hope that it will be useful,
  14. *  but WITHOUT ANY WARRANTY ; without even the implied warranty of
  15. *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. *  GNU General Public License for more details.
  17. *
  18. *  You should have received a copy of the GNU General Public License
  19. *  along with this program ; if not, write to the Free Software
  20. *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  21. *
  22. ****************************************************************************/
  23. // T264.cpp : Defines the entry point for the console application.
  24. //
  25. //#define USE_DISPLAY
  26. #include "config.h"
  27. #ifdef USE_DISPLAY
  28. #ifndef __GCC__
  29. #include "win.h"
  30. #else
  31. #include "display.h"
  32. #endif
  33. #endif
  34. //Ti_DSP Platform ported by YouXiaoquan,HFUT-Ti United Lab,China
  35. //YouXiaoquan@126.com
  36. #include "stdio.h"
  37. #ifndef CHIP_DM642
  38. #include "sys/timeb.h"
  39. #endif
  40. #include "time.h"
  41. #include "stdlib.h"
  42. #ifndef CHIP_DM642
  43. #include "memory.h"
  44. #endif
  45. #include "math.h"
  46. #include "T264.h"
  47. #include "utility.h"
  48. #include "string.h"
  49. // parameters begin
  50. int32_t total_no = 300;
  51. char src_path[256];
  52. char out_path[256];
  53. char rec_path[256];
  54. // for decoder PSNR
  55. char ref_path[256];
  56. static int  ref_skip;
  57. // parameters end
  58. #ifdef USE_DISPLAY
  59. void
  60. winDisplay(T264_t* t, T264_frame_t* f)
  61. {
  62.     uint8_t* p;
  63.     unsigned char* buffer1, *buffer2, *buffer3, *Y, *U, *V;
  64.     unsigned char *src[3];
  65.     int32_t i;
  66.     src[0] = Y = buffer1 = malloc(t->width*t->height*sizeof(char));
  67.     p = f->Y[0];
  68.     for (i = 0 ; i < t->height ; i++)
  69.     {
  70.         memcpy(buffer1, p, t->width);
  71.         buffer1 += t->width;
  72.         p += t->edged_stride;
  73.     }
  74.     src[2] = V = buffer2 = malloc((t->width*t->height*sizeof(char))>>2);
  75.     p = f->V;
  76.     for (i = 0 ; i < (t->height >> 1); i++)
  77.     {
  78.         memcpy(buffer2, p, t->width >> 1);
  79.         buffer2 += (t->width >> 1);
  80.         p += t->edged_stride_uv;
  81.     }
  82.     src[1] = U = buffer3 = malloc((t->width*t->height*sizeof(char))>>2);
  83.     p = f->U;
  84.     for (i = 0 ; i < (t->height >> 1); i++)
  85.     {
  86.         memcpy(buffer3, p, t->width >> 1);
  87.         buffer3 += (t->width >> 1);
  88.         p += t->edged_stride_uv;
  89.     }
  90. #ifndef __GCC__
  91.     displayImage(Y,V,U);
  92. #else
  93.     dither(src);
  94.     free(src[1]);
  95.     free(src[2]);
  96.     free(src[0]);
  97. #endif
  98. }
  99. void
  100. uninit_display()
  101. {
  102. #ifndef __GCC__
  103.     closeDisplay ();
  104. #else
  105.     exit_display();
  106. #endif
  107. }
  108. #endif
  109. void
  110. init_param(T264_param_t* param, const char* file)
  111. {
  112.     FILE* fd; 
  113.     char line[255];
  114.     int32_t b;
  115.     if (!(fd = fopen(file,"r")))
  116.     {
  117.         printf("Couldn't open parameter file %s.n", file);
  118.         exit(-1);
  119.     }
  120.     memset(param, 0, sizeof(*param));
  121.     fgets(line, 254, fd); sscanf(line,"%d", &b);
  122.     if (b != 4)
  123.     {
  124.         printf("wrong param file version, expect v4.0n");
  125.         exit(-1);
  126.     }
  127.     fgets(line, 254, fd); sscanf(line,"%d", &param->width);
  128.     fgets(line, 254, fd); sscanf(line,"%d", &param->height);
  129.     fgets(line, 254, fd); sscanf(line,"%d", &param->search_x);
  130.     fgets(line, 254, fd); sscanf(line,"%d", &param->search_y);
  131.     fgets(line, 254, fd); sscanf(line,"%d", &total_no);
  132.     fgets(line, 254, fd); sscanf(line,"%d", &param->iframe);
  133.     fgets(line, 254, fd); sscanf(line,"%d", &param->idrframe);
  134.     fgets(line, 254, fd); sscanf(line,"%d", &param->b_num);
  135.     fgets(line, 254, fd); sscanf(line,"%d", &param->ref_num);
  136.     fgets(line, 254, fd); sscanf(line,"%d", &param->enable_rc);
  137.     fgets(line, 254, fd); sscanf(line,"%d", &param->bitrate);
  138.     fgets(line, 254, fd); sscanf(line,"%f", &param->framerate);
  139.     fgets(line, 254, fd); sscanf(line,"%d", &param->qp);
  140.     fgets(line, 254, fd); sscanf(line,"%d", &param->min_qp);
  141.     fgets(line, 254, fd); sscanf(line,"%d", &param->max_qp);
  142.     fgets(line, 254, fd); sscanf(line,"%d", &param->enable_stat);
  143.     fgets(line, 254, fd); sscanf(line,"%d", &param->disable_filter);
  144.     fgets(line, 254, fd); sscanf(line,"%d", &param->aspect_ratio);
  145.     fgets(line, 254, fd); sscanf(line,"%d", &param->video_format);
  146.     fgets(line, 254, fd); sscanf(line,"%d", &param->luma_coeff_cost);
  147.     fgets(line, 254, fd); sscanf(line,"%d", &b);
  148.     param->flags |= (USE_INTRA16x16) * (!!b);
  149.     fgets(line, 254, fd); sscanf(line,"%d", &b);
  150.     param->flags |= (USE_INTRA4x4) * (!!b);
  151.     fgets(line, 254, fd); sscanf(line,"%d", &b);
  152.     param->flags |= (USE_INTRAININTER) * (!!b);
  153.     fgets(line, 254, fd); sscanf(line,"%d", &b);
  154.     param->flags |= (USE_HALFPEL) * (!!b);
  155.     fgets(line, 254, fd); sscanf(line,"%d", &b);
  156.     param->flags |= (USE_QUARTPEL) * (!!b);
  157.     fgets(line, 254, fd); sscanf(line,"%d", &b);
  158.     param->flags |= (USE_SUBBLOCK) * (!!b);
  159.     fgets(line, 254, fd); sscanf(line,"%d", &b);
  160.     param->flags |= (USE_FULLSEARCH) * (!!b);
  161.     fgets(line, 254, fd); sscanf(line,"%d", &b);
  162.     param->flags |= (USE_DIAMONDSEACH) * (!!b);
  163.     fgets(line, 254, fd); sscanf(line,"%d", &b);
  164.     param->flags |= (USE_FORCEBLOCKSIZE) * (!!b);
  165.     fgets(line, 254, fd); sscanf(line,"%d", &b);
  166.     param->flags |= (USE_FASTINTERPOLATE) * (!!b);
  167.     fgets(line, 254, fd); sscanf(line,"%d", &b);
  168.     param->flags |= (USE_SAD) * (!!b);
  169.     fgets(line, 254, fd); sscanf(line,"%d", &b);
  170.     param->flags |= (USE_EXTRASUBPELSEARCH) * (!!b);
  171.     fgets(line, 254, fd); sscanf(line,"%d", &b);
  172.     param->flags |= (USE_SCENEDETECT) * (!!b);
  173.     fgets(line, 254, fd); sscanf(line,"%d", &b);
  174.     param->block_size |= (SEARCH_16x16P) * (!!b);
  175.     fgets(line, 254, fd); sscanf(line,"%d", &b);
  176.     param->block_size |= (SEARCH_16x8P) * (!!b);
  177.     fgets(line, 254, fd); sscanf(line,"%d", &b);
  178.     param->block_size |= (SEARCH_8x16P) * (!!b);
  179.     fgets(line, 254, fd); sscanf(line,"%d", &b);
  180.     param->block_size |= (SEARCH_8x8P) * (!!b);
  181.     fgets(line, 254, fd); sscanf(line,"%d", &b);
  182.     param->block_size |= (SEARCH_8x4P) * (!!b);
  183.     fgets(line, 254, fd); sscanf(line,"%d", &b);
  184.     param->block_size |= (SEARCH_4x8P) * (!!b);
  185.     fgets(line, 254, fd); sscanf(line,"%d", &b);
  186.     param->block_size |= (SEARCH_4x4P) * (!!b);
  187.     fgets(line, 254, fd); sscanf(line,"%d", &b);
  188.     param->block_size |= (SEARCH_16x16B) * (!!b);
  189.     fgets(line, 254, fd); sscanf(line,"%d", &b);
  190.     param->block_size |= (SEARCH_16x8B) * (!!b);
  191.     fgets(line, 254, fd); sscanf(line,"%d", &b);
  192.     param->block_size |= (SEARCH_8x16B) * (!!b);
  193.     fgets(line, 254, fd); sscanf(line,"%d", &b);
  194.     param->block_size |= (SEARCH_8x8B) * (!!b);
  195.     fgets(line, 254, fd); sscanf(line,"%d", &param->cpu);
  196.     fgets(line, 254, fd); sscanf(line, "%d", &param->cabac);
  197.     fgets(line, 254, fd); sscanf(line,"%s", src_path);
  198.     fgets(line, 254, fd); sscanf(line,"%s", out_path);
  199.     fgets(line, 254, fd); sscanf(line,"%s", rec_path);
  200.     param->rec_name = rec_path;
  201.     fclose(fd);
  202. }
  203. int32_t 
  204. encode(const char* paramfile)
  205. {
  206.     T264_param_t param;
  207.     T264_t* t;
  208.     uint8_t* buf, *dst;
  209.     int32_t size;
  210.     FILE* in_file, *out_file;
  211.     uint32_t len;
  212.     int32_t frame_no;
  213.     int32_t bs_len = 0;
  214.     uint8_t* rec;
  215.     float total_time;
  216. #ifdef _WIN32
  217.     struct _timeb beg, end;
  218. #endif
  219. #ifdef CHIP_DM642 
  220. clock_t start_T=0,end_T=0,total_T=0;
  221. #endif
  222.     init_param(&param, paramfile);
  223.     param.direct_flag = 1;
  224.     // NOTE: currently we force p reference frame num = 1
  225.     t = T264_open(&param);
  226.     /* YV12p */
  227.     size = param.height * param.width + (param.height * param.width >> 1);
  228.     buf = T264_malloc(size, CACHE_SIZE);
  229.     in_file = fopen(src_path, "rb");
  230.     if (!in_file)
  231.     {
  232.         printf("cannot open input file.");
  233.         return 0;
  234.     }
  235.     out_file = fopen(out_path, "wb");
  236.     if (!out_file)
  237.     {
  238.         printf("cannot write 264 file.n");
  239.         return 0;
  240.     }
  241.     dst = T264_malloc(size, CACHE_SIZE);
  242.     rec = T264_malloc(size, CACHE_SIZE);
  243. #ifdef _WIN32
  244.     _ftime(&beg);
  245. #endif
  246.     printf("frame poc length qp Y U Vn");
  247.     for(frame_no = 0; frame_no < total_no; frame_no++)
  248.     {        
  249.         if (fread(buf, size, 1, in_file) <= 0)
  250.             printf("cannot read from input file.");
  251. #ifdef CHIP_DM642
  252. start_T=clock();
  253. #endif
  254.         len = T264_encode(t, buf, dst, size);
  255. #ifdef CHIP_DM642 
  256. end_T=clock();
  257. total_T=total_T+end_T-start_T-192;
  258. #endif    
  259.         bs_len += len;
  260.         if (fwrite(dst, len, 1, out_file) < 0)
  261.             printf("cannot write 264 file.n");
  262.     }
  263. #ifndef CHIP_DM642
  264. #ifdef _WIN32
  265.     _ftime(&end);
  266.     total_time = (float)(end.time - beg.time) + (float)(end.millitm - beg.millitm) / 1000;
  267. #endif
  268.     printf("fps: %.2ffps, Length of Bitstream = %d Compact Ratio = %.2fn", (float)(total_no) / total_time, bs_len, 1.0 * total_no * size / bs_len);
  269. #endif
  270. #ifdef CHIP_DM642
  271. printf("fps: %.2ffps with cpu 600MHz, Length of Bitstream = %d Compact Ratio = %.2fn", ((float)total_no /((float)total_T/(float)600000000)),  bs_len, 1.0 * total_no * size / bs_len);
  272. #endif
  273.     fclose(in_file);
  274.     fclose(out_file);
  275.     T264_free(dst);
  276.     T264_close(t);
  277.     return 0;
  278. }
  279. void
  280. write_frame(T264_t* t,T264_frame_t *frame,FILE *f_rec)
  281. {
  282.     int i;
  283.     uint8_t* p;
  284.     if (f_rec)
  285.     {
  286.         p = frame->Y[0];
  287.         for(i = 0 ; i < t->height ; i ++)
  288.         {
  289.             fwrite(p, t->width, 1, f_rec);
  290.             p += t->edged_stride;
  291.         }
  292.         p = frame->U;
  293.         for(i = 0 ; i < t->height >> 1 ; i ++)
  294.         {
  295.             fwrite(p, t->width >> 1, 1, f_rec);
  296.             p += t->edged_stride_uv;
  297.         }
  298.         p = frame->V;
  299.         for(i = 0 ; i < t->height >> 1 ; i ++)
  300.         {
  301.             fwrite(p, t->width >> 1, 1, f_rec);
  302.             p += t->edged_stride_uv;
  303.         }
  304.     }
  305. }
  306. static float __inline
  307. dec_psnr(uint8_t* p1, uint8_t* p2, int32_t width1, int32_t width2, int32_t height, int print)
  308. {
  309. float sad = 0, psnr;
  310. int32_t i, j, size, ii, jj, diff, iii, jjj;
  311. uint8_t* p11, *p22;
  312. for(j=0; j<height; j+=16)
  313. {
  314. for (i = 0 ; i < width2 ; i +=16)
  315. {
  316. p11 = p1+i;
  317. p22 = p2+i;
  318. diff = 0;
  319. for(jj=0; jj<16; jj++)
  320. {
  321. for(ii=0; ii<16; ii++)
  322. {
  323. int32_t tmp;
  324. tmp = (p11[ii] - p22[ii]);
  325. sad += tmp * tmp;
  326. if(tmp != 0 && diff != 1)
  327. {
  328. if(print)
  329. printf("%2d != %2d ", p11[ii], p22[ii]);
  330. iii = ii;
  331. jjj = jj;
  332. diff = 1;
  333. }
  334. }
  335. p11 += width1;
  336. p22 += width2;
  337. }
  338. if(diff && print)
  339. {
  340. printf("%4d, %2d, %2dn", (j)*(width2>>4) + (i), iii, jjj);
  341. print = 0;
  342. }
  343. }
  344. p1 += width1*16;
  345. p2 += width2*16;
  346. }
  347. size = width2 * height;
  348. if(sad < 1e-6)
  349. psnr = 0.0f;
  350. else
  351. psnr = (float)(10 * log10(65025.0f * size / sad));
  352. return psnr;
  353. }
  354. int32_t 
  355. decode(const char* filename)
  356. {
  357.     /* just for show how to drive the decoder */
  358. #define BUFFER_SIZE 4096
  359.     T264_t* t = T264dec_open();
  360.     uint8_t buffer[BUFFER_SIZE + 4];
  361.     int32_t run = 1,screen = 0;
  362.     FILE* src_file = fopen(filename, "rb");
  363.     size_t size;
  364.     FILE* f_rec = 0;
  365. //for decoder PSNR
  366. int frame_num = 0;
  367. FILE* f_ref = 0;
  368. uint8_t *ref_buf = NULL;
  369.     int32_t frame_nums = 0;
  370.     float total_time;
  371. #ifdef _WIN32
  372.     struct _timeb beg, end;
  373. #endif
  374.     // xxx
  375.     printf("Current fully support t264 encoder's bitstream.n");
  376.     if (!src_file)
  377.     {
  378.         printf("cannot open file %s.n", filename);
  379.         return -1;
  380.     }
  381.     if (rec_path[0])
  382.     {
  383.         f_rec = fopen(rec_path, "wb");
  384.         if (!f_rec)
  385.         {
  386.             printf("cannot open rec file %s.n", rec_path);
  387.         }
  388.     }
  389. //for decoder PSNR
  390. if(ref_path[0])
  391. {
  392. f_ref = fopen(ref_path, "rb");
  393. if(!f_ref)
  394. {
  395. printf("cannot open ref file %s.n", ref_path);
  396. }
  397. }
  398. #ifdef _WIN32
  399.     _ftime(&beg);
  400. #endif
  401.     while (run) 
  402.     {
  403.         decoder_state_t state = T264dec_parse(t);
  404.         switch(state) 
  405.         {
  406.         case DEC_STATE_BUFFER:
  407.             /* read more data */
  408.             size = fread(buffer, 1, BUFFER_SIZE, src_file);
  409.             if (size > 0)
  410.             {
  411.                 if (size != BUFFER_SIZE)
  412.                 {
  413.                     buffer[size] = 0;
  414.                     buffer[size + 1] = 0;
  415.                     buffer[size + 2] = 0;
  416.                     buffer[size + 3] = 1;
  417.                     size += 4;
  418.                 }
  419.                 T264dec_buffer(t, buffer, size);
  420.             }
  421.             else
  422.             {
  423.                 /* if all data has readed, here we will return */
  424.                 run = 0;
  425.                 /* NOTE: here we should get the last frame */
  426.                 write_frame(t, T264dec_flush_frame(t), f_rec);
  427. #ifdef USE_DISPLAY
  428.                 winDisplay(t, T264dec_flush_frame(t));
  429. #endif
  430.                 frame_nums ++;
  431.             }
  432.             break;
  433.         case DEC_STATE_PIC:
  434.             /* write one pic */
  435.             break;
  436.         case DEC_STATE_SEQ:
  437. #ifdef USE_DISPLAY
  438.             if (screen == 0)
  439.             {
  440. #ifndef __GCC__
  441.                 initDisplay(t->width, t->height);
  442. #else
  443.                 init_display("",t->width, t->height);
  444. #endif
  445.                 screen++;
  446.             }
  447. #endif
  448.             if (t->frame_id > 0)
  449.             {
  450.                 /* NOTE: here we should get the last frame */
  451.                 write_frame(t, T264dec_flush_frame(t), f_rec);
  452.     #ifdef USE_DISPLAY
  453.                 winDisplay(t, T264dec_flush_frame(t));
  454.     #endif
  455.                 frame_nums ++;
  456.             }
  457.             printf("ref frames num: %d.n", t->ss.num_ref_frames);
  458.             printf("width: %d.n", (t->ss.pic_width_in_mbs_minus1 + 1) << 4);
  459.             printf("height: %d.n", (t->ss.pic_height_in_mbs_minus1 + 1) << 4);
  460.             break;
  461.         case DEC_STATE_SLICE:
  462.             {
  463.                 if (t->output.poc >= 0)
  464.                 {
  465.                     write_frame(t, &t->output, f_rec);
  466. //for decoder PSNR
  467. if(f_ref)
  468. {
  469. float psnr_y, psnr_u, psnr_v;
  470. int size;
  471. size = t->width*t->height;
  472. if(ref_buf == NULL)
  473. {
  474. ref_buf = (uint8_t *)malloc(size);
  475. }
  476. if(ref_buf != NULL)
  477. {
  478. uint8_t *p;
  479. p = t->output.Y[0];
  480. fread(ref_buf, 1, size, f_ref);
  481. psnr_y = dec_psnr(p, ref_buf, t->edged_stride, t->width, t->height, 0);
  482. size >>= 2;
  483. p = t->output.U;
  484. fread(ref_buf, 1, size, f_ref);
  485. psnr_u = dec_psnr(p, ref_buf, t->edged_stride_uv, t->width>>1, t->height>>1, 0);
  486. p = t->output.V;
  487. fread(ref_buf, 1, size, f_ref);
  488. psnr_v = dec_psnr(p, ref_buf, t->edged_stride_uv, t->width>>1, t->height>>1, 0);
  489. printf("%4d, %.2f, %.2f, %.2fn", frame_num++, psnr_y, psnr_u, psnr_v);
  490. if(ref_skip > 0)
  491. {
  492. fseek(f_ref, ref_skip*size*6, SEEK_CUR);
  493. }
  494. }
  495. }
  496. #ifdef USE_DISPLAY
  497.                     winDisplay(t, &t->output);
  498. #endif
  499.                     frame_nums ++;                
  500.                 }
  501.             };
  502.             break;
  503.         case DEC_STATE_CUSTOM_SET:
  504.             {
  505.                 printf("used fast interpolate: %s.n", t->flags & USE_FASTINTERPOLATE ? "yes" : "no");
  506.             }
  507.             break;
  508.         default:
  509.             /* do not care */
  510.             break;
  511.         }
  512.     };
  513. #ifndef CHIP_DM642
  514. #ifdef _WIN32
  515.     _ftime(&end);
  516.     total_time = (float)(end.time - beg.time) + (float)(end.millitm - beg.millitm) / 1000;
  517. #endif
  518.     printf("fps: %.2ffps(total decode: %d frames).n", (float)frame_nums / total_time, frame_nums);
  519. #endif    
  520. #ifdef CHIP_DM642
  521. printf("fps: %.2ffps(total decode: %d frames).n", (float)frame_nums / total_time, frame_nums);
  522. #endif
  523.     T264dec_close(t);
  524.     fclose(src_file);
  525.     if (f_rec)
  526.         fclose(f_rec);
  527. if (f_ref)
  528. fclose(f_ref);
  529. if(ref_buf != NULL)
  530. free(ref_buf);
  531. #ifdef USE_DISPLAY
  532.     uninit_display();
  533. #endif
  534.     return 0;
  535. }
  536. void
  537. help()
  538. {
  539.     printf("Usage:n"
  540.         "tt264 -d test.264 [rec_path] [reference_path] [skip_num](to decode a 264 file.)n"
  541.         "tt264 -e enconfig.txt (to encode a 264 file.)n");
  542. }
  543. int 
  544. main(int argc, char* argv[])
  545. {
  546.     int32_t i;
  547.     int32_t is_encode = 0;
  548.     int32_t is_decode = 0;
  549.     char* file_name;
  550.     printf("T264 ver: %d.%02dn", T264_MAJOR, T264_MINOR);
  551.     if (argc < 3)
  552.     {
  553.         help();
  554.         return 0;
  555.     }
  556.     for (i = 1 ; i < 3 ; i ++)
  557.     {
  558.         if (strcmp(argv[i], "-d") == 0)
  559.         {
  560.             is_decode = 1;
  561.         }
  562.         else if(strcmp(argv[i], "-e") == 0)
  563.         {
  564.             is_encode = 1;
  565.         }
  566.         else
  567.         {
  568.             file_name = argv[i];
  569.         }
  570.     }
  571.     if (is_encode)
  572.     {
  573.         return encode(file_name);
  574.     }
  575.     if (is_decode)
  576.     {
  577.         if (argc <= 3)
  578.             rec_path[0] = 0;
  579.         else
  580. {
  581. strcpy(rec_path, argv[3]);
  582. }
  583. if(argc <= 4)
  584. {
  585. ref_path[0] = 0;
  586. }
  587. else
  588. {
  589. strcpy(ref_path, argv[4]);
  590. }
  591. if(argc > 5)
  592. {
  593. ref_skip = atoi(argv[5]);
  594. }
  595.         return decode(file_name);
  596.     }
  597.     help();
  598.     return -1;
  599. }