mp4_picture.c
资源名称:VC++视频传输.rar [点击查看]
上传用户:hxb_1234
上传日期:2010-03-30
资源大小:8328k
文件大小:9k
源码类别:
VC书籍
开发平台:
Visual C++
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "mp4_decoder.h"
- #include "mp4_vars.h"
- #include "mp4_header.h"
- #include "mp4_mblock.h"
- #include "transferIDCT.h"
- #include "postprocess.h"
- #include "yuv2rgb.h"
- #include "store.h"
- /**
- *
- **/
- void addblock (int comp, int bx, int by, int addflag);
- int find_pmv (int block, int comp);
- static void make_edge (unsigned char *frame_pic, int width, int height, int edge);
- /***/
- // 解码和显示一个视频对象平面
- void get_mp4picture (unsigned char *bmp, unsigned int stride, int render_flag)
- {
- mp4_state->hdr.mba = 0;
- mp4_state->hdr.mb_xpos = 0;
- mp4_state->hdr.mb_ypos = 0;
- do {
- macroblock();
- mp4_state->hdr.mba++;
- } while ((nextbits_bytealigned(23) != 0) &&
- (mp4_state->hdr.mba < mp4_state->hdr.mba_size));
- // 对被解码的帧增加边界
- make_edge (frame_ref[0], mp4_state->coded_picture_width, mp4_state->coded_picture_height, 32);
- make_edge (frame_ref[1], mp4_state->chrom_width, mp4_state->chrom_height, 16);
- make_edge (frame_ref[2], mp4_state->chrom_width, mp4_state->chrom_height, 16);
- PictureDisplay(bmp, stride, render_flag);
- // 交换帧
- {
- int i;
- unsigned char *tmp;
- for (i = 0; i < 3; i++) {
- tmp = frame_ref[i];
- frame_ref[i] = frame_for[i];
- frame_for[i] = tmp;
- }
- }
- }
- /***/
- void addblock (int comp, int bx, int by, int addflag)
- {
- int cc, i, iincr;
- unsigned char *rfp;
- short *bp;
- unsigned char *curr[3];
- curr[0] = frame_ref[0];
- curr[1] = frame_ref[1];
- curr[2] = frame_ref[2];
- bp = ld->block;
- cc = (comp < 4) ? 0 : (comp & 1) + 1;
- if (cc == 0)
- {
- bx <<= 4;
- by <<= 4;
- rfp = curr[0] + mp4_state->coded_picture_width * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
- iincr = mp4_state->coded_picture_width;
- }
- else
- {
- bx <<= 3;
- by <<= 3;
- rfp = curr[cc] + mp4_state->chrom_width * by + bx;
- iincr = mp4_state->chrom_width;
- }
- if (addflag)
- {
- for (i = 0; i < 8; i++)
- {
- rfp[0] = mp4_state->clp[bp[0] + rfp[0]];
- rfp[1] = mp4_state->clp[bp[1] + rfp[1]];
- rfp[2] = mp4_state->clp[bp[2] + rfp[2]];
- rfp[3] = mp4_state->clp[bp[3] + rfp[3]];
- rfp[4] = mp4_state->clp[bp[4] + rfp[4]];
- rfp[5] = mp4_state->clp[bp[5] + rfp[5]];
- rfp[6] = mp4_state->clp[bp[6] + rfp[6]];
- rfp[7] = mp4_state->clp[bp[7] + rfp[7]];
- bp += 8;
- rfp += iincr;
- }
- } else
- {
- for (i = 0; i < 8; i++)
- {
- rfp[0] = mp4_state->clp[bp[0]];
- rfp[1] = mp4_state->clp[bp[1]];
- rfp[2] = mp4_state->clp[bp[2]];
- rfp[3] = mp4_state->clp[bp[3]];
- rfp[4] = mp4_state->clp[bp[4]];
- rfp[5] = mp4_state->clp[bp[5]];
- rfp[6] = mp4_state->clp[bp[6]];
- rfp[7] = mp4_state->clp[bp[7]];
- bp += 8;
- rfp += iincr;
- }
- }
- }
- /***/
- void addblockIntra (int comp, int bx, int by)
- {
- int cc, iincr;
- unsigned char *rfp;
- short *bp;
- unsigned char *curr[3];
- curr[0] = frame_ref[0];
- curr[1] = frame_ref[1];
- curr[2] = frame_ref[2];
- bp = ld->block;
- cc = (comp < 4) ? 0 : (comp & 1) + 1;
- if (cc == 0)
- {
- bx <<= 4;
- by <<= 4;
- rfp = curr[0] + mp4_state->coded_picture_width * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
- iincr = mp4_state->coded_picture_width;
- }
- else
- {
- bx <<= 3;
- by <<= 3;
- rfp = curr[cc] + mp4_state->chrom_width * by + bx;
- iincr = mp4_state->chrom_width;
- }
- transferIDCT_copy(bp, rfp, iincr);
- }
- /***/
- void addblockInter (int comp, int bx, int by)
- {
- int cc, iincr;
- unsigned char *rfp;
- short *bp;
- unsigned char *curr[3];
- curr[0] = frame_ref[0];
- curr[1] = frame_ref[1];
- curr[2] = frame_ref[2];
- bp = ld->block;
- cc = (comp < 4) ? 0 : (comp & 1) + 1;
- if (cc == 0)
- {
- bx <<= 4;
- by <<= 4;
- rfp = curr[0] + mp4_state->coded_picture_width * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
- iincr = mp4_state->coded_picture_width;
- }
- else
- {
- bx <<= 3;
- by <<= 3;
- rfp = curr[cc] + mp4_state->chrom_width * by + bx;
- iincr = mp4_state->chrom_width;
- }
- transferIDCT_add(bp, rfp, iincr);
- }
- int find_pmv (int block, int comp)
- {
- int p1, p2, p3;
- int xin1, xin2, xin3;
- int yin1, yin2, yin3;
- int vec1, vec2, vec3;
- int x = mp4_state->hdr.mb_xpos;
- int y = mp4_state->hdr.mb_ypos;
- if ((y == 0) && ((block == 0) || (block == 1)))
- {
- if ((x == 0) && (block == 0))
- return 0;
- else if (block == 1)
- return mp4_state->MV[comp][0][y+1][x+1];
- else // block == 0
- return mp4_state->MV[comp][1][y+1][x+1-1];
- }
- else
- {
- x++;
- y++;
- switch (block)
- {
- case 0:
- vec1 = 1; yin1 = y; xin1 = x-1;
- vec2 = 2; yin2 = y-1; xin2 = x;
- vec3 = 2; yin3 = y-1; xin3 = x+1;
- break;
- case 1:
- vec1 = 0; yin1 = y; xin1 = x;
- vec2 = 3; yin2 = y-1; xin2 = x;
- vec3 = 2; yin3 = y-1; xin3 = x+1;
- break;
- case 2:
- vec1 = 3; yin1 = y; xin1 = x-1;
- vec2 = 0; yin2 = y; xin2 = x;
- vec3 = 1; yin3 = y; xin3 = x;
- break;
- default:
- vec1 = 2; yin1 = y; xin1 = x;
- vec2 = 0; yin2 = y; xin2 = x;
- vec3 = 1; yin3 = y; xin3 = x;
- break;
- }
- p1 = mp4_state->MV[comp][vec1][yin1][xin1];
- p2 = mp4_state->MV[comp][vec2][yin2][xin2];
- p3 = mp4_state->MV[comp][vec3][yin3][xin3];
- return mmin(mmax(p1, p2), mmin(mmax(p2, p3), mmax(p1, p3)));
- }
- }
- /***/
- // 对被解码的帧增加边界
- void make_edge (unsigned char *frame_pic,
- int edged_width, int edged_height, int edge)
- {
- int j;
- int width = edged_width - (2*edge);
- int height = edged_height - (2*edge);
- unsigned char *p_border;
- unsigned char *p_border_top, *p_border_bottom;
- unsigned char *p_border_top_ref, *p_border_bottom_ref;
- // 左右边界
- p_border = frame_pic;
- for (j = 0; j < height; j++)
- {
- unsigned char border_left = *(p_border);
- unsigned char border_right = *(p_border + (width-1));
- memset((p_border - edge), border_left, edge);
- memset((p_border + width), border_right, edge);
- p_border += edged_width;
- }
- // 上下边界
- p_border_top_ref = frame_pic;
- p_border_bottom_ref = frame_pic + (edged_width * (height -1));
- p_border_top = p_border_top_ref - (edge * edged_width);
- p_border_bottom = p_border_bottom_ref + edged_width;
- for (j = 0; j < edge; j++)
- {
- memcpy(p_border_top, p_border_top_ref, width);
- memcpy(p_border_bottom, p_border_bottom_ref, width);
- p_border_top += edged_width;
- p_border_bottom += edged_width;
- }
- // 角
- {
- unsigned char * p_left_corner_top = frame_pic - edge - (edge * edged_width);
- unsigned char * p_right_corner_top = p_left_corner_top + edge + width;
- unsigned char * p_left_corner_bottom = frame_pic + (edged_width * height) - edge;
- unsigned char * p_right_corner_bottom = p_left_corner_bottom + edge + width;
- char left_corner_top = *(frame_pic);
- char right_corner_top = *(frame_pic + (width-1));
- char left_corner_bottom = *(frame_pic + (edged_width * (height-1)));
- char right_corner_bottom = *(frame_pic + (edged_width * (height-1)) + (width-1));
- for (j = 0; j < edge; j++)
- {
- memset(p_left_corner_top, left_corner_top, edge);
- memset(p_right_corner_top, right_corner_top, edge);
- memset(p_left_corner_bottom, left_corner_bottom, edge);
- memset(p_right_corner_bottom, right_corner_bottom, edge);
- p_left_corner_top += edged_width;
- p_right_corner_top += edged_width;
- p_left_corner_bottom += edged_width;
- p_right_corner_bottom += edged_width;
- }
- }
- }
- /***/
- // 在显示或写入一个文件前对一个帧缓存重新排序
- void PictureDisplay(unsigned char *bmp, unsigned int stride, int render_flag)
- {
- #ifdef _DECORE
- if (render_flag)
- {
- if (mp4_state->post_flag)
- {
- postprocess(frame_ref, mp4_state->coded_picture_width,
- display_frame, mp4_state->horizontal_size,
- mp4_state->horizontal_size, mp4_state->vertical_size,
- &mp4_state->quant_store[1][1], (DEC_MBC+1), mp4_state->pp_options);
- mp4_state->convert_yuv(display_frame[0], mp4_state->hdr.width,
- display_frame[1], display_frame[2], (mp4_state->hdr.width>>1),
- bmp, mp4_state->hdr.width, mp4_state->flag_invert * mp4_state->hdr.height,
- stride);
- }
- else
- {
- mp4_state->convert_yuv(frame_ref[0], mp4_state->coded_picture_width,
- frame_ref[1], frame_ref[2], (mp4_state->coded_picture_width>>1),
- bmp, mp4_state->hdr.width, mp4_state->flag_invert * mp4_state->hdr.height,
- stride);
- }
- }
- #else
- // 输出到一个文件
- storeframe (frame_ref, mp4_state->coded_picture_width, mp4_state->vertical_size);
- #endif
- }