mp4_picture.c
上传用户:hxb_1234
上传日期:2010-03-30
资源大小:8328k
文件大小:9k
源码类别:

VC书籍

开发平台:

Visual C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "mp4_decoder.h"
  5. #include "mp4_vars.h"
  6. #include "mp4_header.h"
  7. #include "mp4_mblock.h"
  8. #include "transferIDCT.h"
  9. #include "postprocess.h"
  10. #include "yuv2rgb.h"
  11. #include "store.h"
  12. /**
  13.  *
  14. **/
  15. void addblock (int comp, int bx, int by, int addflag);
  16. int find_pmv (int block, int comp);
  17. static void make_edge (unsigned char *frame_pic, int width, int height, int edge);
  18. /***/
  19. // 解码和显示一个视频对象平面
  20. void get_mp4picture (unsigned char *bmp, unsigned int stride, int render_flag)
  21. {
  22. mp4_state->hdr.mba = 0;
  23. mp4_state->hdr.mb_xpos = 0;
  24. mp4_state->hdr.mb_ypos = 0;
  25. do {
  26. macroblock();
  27. mp4_state->hdr.mba++; 
  28. } while ((nextbits_bytealigned(23) != 0) &&
  29. (mp4_state->hdr.mba < mp4_state->hdr.mba_size));
  30. // 对被解码的帧增加边界
  31. make_edge (frame_ref[0], mp4_state->coded_picture_width, mp4_state->coded_picture_height, 32);
  32. make_edge (frame_ref[1], mp4_state->chrom_width, mp4_state->chrom_height, 16);
  33. make_edge (frame_ref[2], mp4_state->chrom_width, mp4_state->chrom_height, 16);
  34. PictureDisplay(bmp, stride, render_flag);
  35. // 交换帧
  36. {
  37. int i;
  38. unsigned char *tmp;
  39. for (i = 0; i < 3; i++) {
  40. tmp = frame_ref[i];
  41. frame_ref[i] = frame_for[i];
  42. frame_for[i] = tmp;
  43. }
  44. }
  45. }
  46. /***/
  47. void addblock (int comp, int bx, int by, int addflag)
  48. {
  49.   int cc, i, iincr;
  50.   unsigned char *rfp;
  51.   short *bp;
  52.   unsigned char *curr[3];
  53. curr[0] = frame_ref[0];
  54. curr[1] = frame_ref[1];
  55. curr[2] = frame_ref[2];
  56.   bp = ld->block;
  57.   cc = (comp < 4) ? 0 : (comp & 1) + 1; 
  58.   if (cc == 0) 
  59.   {
  60. bx <<= 4;
  61. by <<= 4;
  62. rfp = curr[0] + mp4_state->coded_picture_width * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
  63.     iincr = mp4_state->coded_picture_width;
  64.   } 
  65.   else 
  66.   {
  67. bx <<= 3;
  68. by <<= 3;
  69. rfp = curr[cc] + mp4_state->chrom_width * by + bx;
  70.     iincr = mp4_state->chrom_width;
  71.   }
  72.   if (addflag)
  73.   {
  74.     for (i = 0; i < 8; i++)
  75.     {
  76.       rfp[0] = mp4_state->clp[bp[0] + rfp[0]];
  77.       rfp[1] = mp4_state->clp[bp[1] + rfp[1]];
  78.       rfp[2] = mp4_state->clp[bp[2] + rfp[2]];
  79.       rfp[3] = mp4_state->clp[bp[3] + rfp[3]];
  80.       rfp[4] = mp4_state->clp[bp[4] + rfp[4]];
  81.       rfp[5] = mp4_state->clp[bp[5] + rfp[5]];
  82.       rfp[6] = mp4_state->clp[bp[6] + rfp[6]];
  83.       rfp[7] = mp4_state->clp[bp[7] + rfp[7]];
  84.       bp += 8;
  85.       rfp += iincr;
  86.     }
  87.   } else
  88.   {
  89.     for (i = 0; i < 8; i++)
  90.     {
  91.       rfp[0] = mp4_state->clp[bp[0]];
  92.       rfp[1] = mp4_state->clp[bp[1]];
  93.       rfp[2] = mp4_state->clp[bp[2]];
  94.       rfp[3] = mp4_state->clp[bp[3]];
  95.       rfp[4] = mp4_state->clp[bp[4]];
  96.       rfp[5] = mp4_state->clp[bp[5]];
  97.       rfp[6] = mp4_state->clp[bp[6]];
  98.       rfp[7] = mp4_state->clp[bp[7]];
  99.       bp += 8;
  100.       rfp += iincr;
  101.     }
  102.   }
  103. }
  104. /***/
  105. void addblockIntra (int comp, int bx, int by)
  106. {
  107.   int cc, iincr;
  108.   unsigned char *rfp;
  109.   short *bp;
  110.   unsigned char *curr[3];
  111. curr[0] = frame_ref[0];
  112. curr[1] = frame_ref[1];
  113. curr[2] = frame_ref[2];
  114.   bp = ld->block;
  115.   cc = (comp < 4) ? 0 : (comp & 1) + 1; 
  116.   if (cc == 0) 
  117.   {
  118. bx <<= 4;
  119. by <<= 4;
  120.     
  121. rfp = curr[0] + mp4_state->coded_picture_width * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
  122.     iincr = mp4_state->coded_picture_width;
  123.   } 
  124.   else 
  125.   {
  126. bx <<= 3;
  127. by <<= 3;
  128.    
  129. rfp = curr[cc] + mp4_state->chrom_width * by + bx;
  130.     iincr = mp4_state->chrom_width;
  131.   }
  132.  transferIDCT_copy(bp, rfp, iincr);
  133. }
  134. /***/
  135. void addblockInter (int comp, int bx, int by)
  136. {
  137.   int cc, iincr;
  138.   unsigned char *rfp;
  139.   short *bp;
  140.   unsigned char *curr[3];
  141. curr[0] = frame_ref[0];
  142. curr[1] = frame_ref[1];
  143. curr[2] = frame_ref[2];
  144.   bp = ld->block;
  145.   cc = (comp < 4) ? 0 : (comp & 1) + 1; 
  146.   if (cc == 0)
  147.   {
  148. bx <<= 4;
  149. by <<= 4;
  150.  
  151. rfp = curr[0] + mp4_state->coded_picture_width * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
  152.     iincr = mp4_state->coded_picture_width;
  153.   } 
  154.   else 
  155.   {
  156. bx <<= 3;
  157. by <<= 3;
  158. rfp = curr[cc] + mp4_state->chrom_width * by + bx;
  159.     iincr = mp4_state->chrom_width;
  160.   }
  161.  transferIDCT_add(bp, rfp, iincr);
  162. }
  163. int find_pmv (int block, int comp)
  164. {
  165.   int p1, p2, p3;
  166.   int xin1, xin2, xin3;
  167.   int yin1, yin2, yin3;
  168.   int vec1, vec2, vec3;
  169. int x = mp4_state->hdr.mb_xpos;
  170. int y = mp4_state->hdr.mb_ypos;
  171. if ((y == 0) && ((block == 0) || (block == 1)))
  172. {
  173. if ((x == 0) && (block == 0))
  174. return 0;
  175. else if (block == 1)
  176. return mp4_state->MV[comp][0][y+1][x+1];
  177. else // block == 0
  178. return mp4_state->MV[comp][1][y+1][x+1-1];
  179. }
  180. else
  181. {
  182. x++;
  183. y++;
  184. switch (block)
  185. {
  186. case 0: 
  187. vec1 = 1; yin1 = y; xin1 = x-1;
  188. vec2 = 2; yin2 = y-1; xin2 = x;
  189. vec3 = 2; yin3 = y-1; xin3 = x+1;
  190. break;
  191. case 1:
  192. vec1 = 0; yin1 = y; xin1 = x;
  193. vec2 = 3; yin2 = y-1; xin2 = x;
  194. vec3 = 2; yin3 = y-1; xin3 = x+1;
  195. break;
  196. case 2:
  197. vec1 = 3; yin1 = y; xin1 = x-1;
  198. vec2 = 0; yin2 = y;   xin2 = x;
  199. vec3 = 1; yin3 = y; xin3 = x;
  200. break;
  201. default: 
  202. vec1 = 2; yin1 = y; xin1 = x;
  203. vec2 = 0; yin2 = y; xin2 = x;
  204. vec3 = 1; yin3 = y; xin3 = x;
  205. break;
  206. }
  207. p1 = mp4_state->MV[comp][vec1][yin1][xin1];
  208. p2 = mp4_state->MV[comp][vec2][yin2][xin2];
  209. p3 = mp4_state->MV[comp][vec3][yin3][xin3];
  210. return mmin(mmax(p1, p2), mmin(mmax(p2, p3), mmax(p1, p3)));
  211. }
  212. }
  213. /***/
  214. // 对被解码的帧增加边界
  215. void make_edge (unsigned char *frame_pic,
  216.                 int edged_width, int edged_height, int edge)
  217. {
  218.   int j;
  219. int width = edged_width - (2*edge);
  220. int height = edged_height - (2*edge);
  221. unsigned char *p_border;
  222. unsigned char *p_border_top, *p_border_bottom;
  223. unsigned char *p_border_top_ref, *p_border_bottom_ref;
  224. // 左右边界
  225. p_border = frame_pic;
  226. for (j = 0; j < height; j++)
  227. {
  228. unsigned char border_left = *(p_border);
  229. unsigned char border_right = *(p_border + (width-1));
  230. memset((p_border - edge), border_left, edge);
  231. memset((p_border + width), border_right, edge);
  232. p_border += edged_width;
  233. }
  234. // 上下边界
  235. p_border_top_ref = frame_pic;
  236. p_border_bottom_ref = frame_pic + (edged_width * (height -1));
  237. p_border_top = p_border_top_ref - (edge * edged_width);
  238. p_border_bottom = p_border_bottom_ref + edged_width;
  239. for (j = 0; j < edge; j++)
  240. {
  241. memcpy(p_border_top, p_border_top_ref, width);
  242. memcpy(p_border_bottom, p_border_bottom_ref, width);
  243. p_border_top += edged_width;
  244. p_border_bottom += edged_width;
  245. }
  246.   // 角
  247. {
  248. unsigned char * p_left_corner_top = frame_pic - edge - (edge * edged_width);
  249. unsigned char * p_right_corner_top = p_left_corner_top + edge + width;
  250. unsigned char * p_left_corner_bottom = frame_pic + (edged_width * height) - edge;
  251. unsigned char * p_right_corner_bottom = p_left_corner_bottom + edge + width;
  252. char left_corner_top = *(frame_pic);
  253. char right_corner_top = *(frame_pic + (width-1));
  254. char left_corner_bottom = *(frame_pic + (edged_width * (height-1)));
  255. char right_corner_bottom = *(frame_pic + (edged_width * (height-1)) + (width-1));
  256. for (j = 0; j < edge; j++)
  257. {
  258. memset(p_left_corner_top, left_corner_top, edge);
  259. memset(p_right_corner_top, right_corner_top, edge);
  260. memset(p_left_corner_bottom, left_corner_bottom, edge);
  261. memset(p_right_corner_bottom, right_corner_bottom, edge);
  262. p_left_corner_top += edged_width;
  263. p_right_corner_top += edged_width;
  264. p_left_corner_bottom += edged_width;
  265. p_right_corner_bottom += edged_width;
  266. }
  267. }
  268. }
  269. /***/
  270. // 在显示或写入一个文件前对一个帧缓存重新排序
  271. void PictureDisplay(unsigned char *bmp, unsigned int stride, int render_flag)
  272. #ifdef _DECORE
  273. if (render_flag) 
  274. {
  275. if (mp4_state->post_flag)
  276. {
  277. postprocess(frame_ref, mp4_state->coded_picture_width,
  278. display_frame, mp4_state->horizontal_size, 
  279. mp4_state->horizontal_size,  mp4_state->vertical_size, 
  280. &mp4_state->quant_store[1][1], (DEC_MBC+1), mp4_state->pp_options);
  281. mp4_state->convert_yuv(display_frame[0], mp4_state->hdr.width,
  282. display_frame[1], display_frame[2], (mp4_state->hdr.width>>1),
  283. bmp, mp4_state->hdr.width, mp4_state->flag_invert * mp4_state->hdr.height,
  284. stride);
  285. }
  286. else
  287. {
  288. mp4_state->convert_yuv(frame_ref[0], mp4_state->coded_picture_width,
  289. frame_ref[1], frame_ref[2], (mp4_state->coded_picture_width>>1),
  290. bmp, mp4_state->hdr.width, mp4_state->flag_invert * mp4_state->hdr.height,
  291. stride);
  292. }
  293. }
  294. #else
  295. // 输出到一个文件
  296. storeframe (frame_ref, mp4_state->coded_picture_width, mp4_state->vertical_size);
  297. #endif
  298. }