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

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. #include "stdio.h"
  24. #include "stdlib.h"
  25. #include "T264.h"
  26. #include "stat.h"
  27. #include "math.h"
  28. #ifndef CHIP_DM642
  29. #include "memory.h"
  30. #endif
  31. #include "deblock.h"
  32. typedef struct  
  33. {
  34.     T264_stat_t stat_prev;
  35.     FILE* rec;
  36.     uint8_t* buf;
  37.     uint8_t* bufb;
  38.     int32_t frame_no;
  39.     float psnr_y;
  40.     float psnr_u;
  41.     float psnr_v;
  42. } stat_t;
  43. static float __inline
  44. psnr(uint8_t* p1, uint8_t* p2, int32_t size)
  45. {
  46.     float sad = 0;
  47.     int32_t i;
  48.     for (i = 0 ; i < size ; i ++)
  49.     {
  50.         int32_t tmp;
  51.         tmp = (p1[i] - p2[i]);
  52.         sad += tmp * tmp;
  53.     }
  54.     return (float)(10 * log10(65025.0f * size / sad));
  55. }
  56. static void
  57. stat_proc(T264_t* t, void* data, int32_t state)
  58. {
  59.     T264_frame_t* f;
  60.     float y, u, v;
  61.     int32_t i;
  62.     uint8_t* d, *buf, *bufs;
  63.     stat_t* stat = data;
  64.     T264_stat_t* stat_prev = &stat->stat_prev;
  65.     static const char type[] = {'P', 'B', 'I'};
  66.     
  67.     switch (state) 
  68.     {
  69.     case STATE_AFTERPIC:
  70.         if (t->slice_type == SLICE_B)
  71.         {
  72.             f = &t->refn[0];
  73.             bufs = buf = stat->bufb;
  74.             if (t->param.disable_filter == 0)
  75.                 T264_deblock_frame(t, f);
  76.         }
  77.         else
  78.         {
  79.             f = &t->refn[1];
  80.             bufs = buf = stat->buf;
  81.         }
  82.         d = f->Y[0];
  83.         for (i = 0 ; i < t->param.height ; i ++)
  84.         {
  85.             memcpy(buf, d, t->param.width);
  86.             d += t->edged_stride;
  87.             buf += t->stride;
  88.         }
  89.         y = psnr(t->cur.Y[0], bufs, t->width * t->height);
  90.         d = f->U;
  91.         for (i = 0 ; i < t->param.height >> 1 ; i ++)
  92.         {
  93.             memcpy(buf, d, t->param.width >> 1);
  94.             d += t->edged_stride_uv;
  95.             buf += t->stride_uv;
  96.         }
  97.         u = psnr(t->cur.U, bufs + t->width * t->height, t->width * t->height >> 2);
  98.         d = f->V;
  99.         for (i = 0 ; i < t->param.height >> 1 ; i ++)
  100.         {
  101.             memcpy(buf, d, t->param.width >> 1);
  102.             d += t->edged_stride_uv;
  103.             buf += t->stride_uv;
  104.         }
  105.         v = psnr(t->cur.V, bufs + t->width * t->height + (t->width * t->height >> 2), t->width * t->height >> 2);
  106.         if (stat->rec)
  107.         {
  108.             if (t->slice_type == SLICE_B)
  109.             {
  110.                 fwrite(stat->bufb, t->param.height * t->param.width + (t->param.height * t->param.width >> 1), 1, stat->rec);
  111.                 if (t->pending_bframes_num == 0)
  112.                     fwrite(stat->buf, t->param.height * t->param.width + (t->param.height * t->param.width >> 1), 1, stat->rec);
  113.             }
  114.             else if ((t->slice_type == SLICE_I && t->param.b_num == 0) // no b slice we write it immediately
  115.                 || (t->slice_type == SLICE_I && (t->frame_id - 1) % t->param.idrframe == 0)) // if we have b slice we only write it when it is an idr frame
  116.             {
  117.                 fwrite(stat->buf, t->param.height * t->param.width + (t->param.height * t->param.width >> 1), 1, stat->rec);
  118.             }
  119.             else if (t->param.b_num == 0)
  120.             {
  121.                 fwrite(stat->buf, t->param.height * t->param.width + (t->param.height * t->param.width >> 1), 1, stat->rec);
  122.             }
  123.         }
  124.         if (t->param.enable_stat & DISPLAY_PSNR)
  125.             printf("%4d(%c) %4d %5d %d %.4f %.4f %.4fn", 
  126.                 stat->frame_no ++,
  127.                 type[t->slice_type],
  128.                 t->cur.poc,
  129.                 t->frame_bits / 8,
  130.                 t->qp_y,
  131.                 y, u, v);
  132.         if (t->param.enable_stat & DISPLAY_BLOCK)
  133.             printf(" i4x4:%d, i16x16:%d, pskip:%d, p16x16:%d, p16x8:%d, p8x16:%d, p8x8:%d.n",
  134.                 t->stat.i_block_num[I_4x4] - stat_prev->i_block_num[I_4x4], 
  135.                 t->stat.i_block_num[I_16x16] - stat_prev->i_block_num[I_16x16], 
  136.                 t->stat.skip_block_num - stat_prev->skip_block_num,
  137.                 t->stat.p_block_num[MB_16x16] - stat_prev->p_block_num[MB_16x16], 
  138.                 t->stat.p_block_num[MB_16x8] - stat_prev->p_block_num[MB_16x8], 
  139.                 t->stat.p_block_num[MB_8x16] - stat_prev->p_block_num[MB_8x16], 
  140.                 t->stat.p_block_num[MB_8x8] - stat_prev->p_block_num[MB_8x8]);
  141.         stat->psnr_y += y;
  142.         stat->psnr_u += u;
  143.         stat->psnr_v += v;
  144.         *stat_prev = t->stat;
  145.         break;
  146.     }
  147. }
  148. void 
  149. stat_create(T264_t* t, T264_plugin_t* plugin)
  150. {
  151.     stat_t* s = malloc(sizeof(stat_t));
  152.     s->rec = fopen(t->param.rec_name, "wb");
  153.     memset(&s->stat_prev, 0, sizeof(s->stat_prev));
  154.     s->buf = malloc(t->width * t->height + (t->width * t->height >> 1));
  155.     s->bufb = malloc(t->width * t->height + (t->width * t->height >> 1));
  156.     s->frame_no = 0;
  157.     s->psnr_y = 0;
  158.     s->psnr_u = 0;
  159.     s->psnr_v = 0;
  160.     plugin->handle = s;
  161.     plugin->proc = stat_proc;
  162.     plugin->close = stat_destroy;
  163.     plugin->ret = 0;
  164. }
  165. void 
  166. stat_destroy(T264_t* t, T264_plugin_t* plugin)
  167. {
  168.     stat_t* s = plugin->handle;
  169.     printf("Average PSNR Y: %.2f U: %.2f V: %.2f.n", s->psnr_y / s->frame_no, s->psnr_u / s->frame_no, s->psnr_v / s->frame_no);
  170.     free(s->buf);
  171.     free(s->bufb);
  172.     if (s->rec)
  173.     {
  174.         fclose(s->rec);
  175.     }
  176. }