📄 picture.c
字号:
//*******************************************
//File name: picture.c
//Author: Anna
//Date:
//*******************************************
#include <stdio.h>
#define mmax(a, b) ((a) > (b) ? (a) : (b))
#define mmin(a, b) ((a) < (b) ? (a) : (b))
#define DEC_MBC 45
#define DEC_MBR 36
extern int MV[2][6][DEC_MBR+1][DEC_MBC+2];
extern int mba;
extern int mb_xpos;
extern int mb_ypos;
extern int mba_size;
extern int coded_picture_width;
extern int chrom_width;
extern int chrom_height;
extern short block[64];
extern char * outputname;
extern int width;
extern int height;
extern int horizontal_size;
extern int picnum;
//extern int blockintra_num;
extern unsigned char *edged_ref[3],
*edged_for[3],
*frame_ref[3],
*frame_for[3],
*display_frame[3];
extern int macroblock();
void transferIDCT_copy(short *sourceS16, unsigned char *destU8, int stride);
void transferIDCT_add(short *sourceS16, unsigned char *destU8, int stride);
void PictureDisplay (unsigned char *bmp, unsigned int stride, int render_flag);
static void make_edge (unsigned char *frame_pic, int width, int height, int edge);
#define RGB_GET
#ifdef RGB_GET
void storeframe_rgb();
#define RGB
#endif
int nextbits_bytealigned(int nbit);
void get_mp4picture (unsigned char *bmp, unsigned int stride, int render_flag)
{
mba = 0;
mb_xpos = 0;
mb_ypos = 0;
//blockintra_num=0;
do {
macroblock();
mba++;
} while ((nextbits_bytealigned(23) != 0) &&
(mba < mba_size));
// add edge to decoded fram make_edge (frame_ref[0], mp4_state->coded_picture_width, mp4_state->coded_picture_height, 32);
make_edge (frame_ref[1], chrom_width, chrom_height, 16);
make_edge (frame_ref[2], chrom_width, chrom_height, 16);
PictureDisplay(bmp, stride, render_flag);
// exchange ref and for frames
{
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;
}
}
}//first end
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=block;
cc = (comp < 4) ? 0 : (comp & 1) + 1; /* color component index */
if (cc == 0) // luminance
{
// pixel coordinates
bx <<= 4;
by <<= 4;
// frame DCT coding
rfp = curr[0] + coded_picture_width * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
iincr = coded_picture_width;
}
else // chrominance
{
// pixel coordinates
bx <<= 3;
by <<= 3;
// frame DCT coding
rfp = curr[cc] + chrom_width * by + bx;
iincr = 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 = block;
cc = (comp < 4) ? 0 : (comp & 1) + 1; /* color component index */
if (cc == 0) // luminance
{
// pixel coordinates
bx <<= 4;
by <<= 4;
// frame DCT coding
rfp = curr[0] + coded_picture_width * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
iincr = coded_picture_width;
}
else // chrominance
{
// pixel coordinates
bx <<= 3;
by <<= 3;
// frame DCT coding
rfp = curr[cc] + chrom_width * by + bx;
iincr = chrom_width;
}
/***
for (int i = 0; i < 8; i++)
{
rfp[0] = clp[bp[0] + rfp[0]];
rfp[1] = clp[bp[1] + rfp[1]];
rfp[2] = clp[bp[2] + rfp[2]];
rfp[3] = clp[bp[3] + rfp[3]];
rfp[4] = clp[bp[4] + rfp[4]];
rfp[5] = clp[bp[5] + rfp[5]];
rfp[6] = clp[bp[6] + rfp[6]];
rfp[7] = clp[bp[7] + rfp[7]];
bp += 8;
rfp += iincr;
}
***/ transferIDCT_add(bp, rfp, iincr);
}
/***/
// Purpose: compute motion vector prediction
int find_pmv (int block_num, int comp)
{
int p1, p2, p3;
int xin1, xin2, xin3;
int yin1, yin2, yin3;
int vec1, vec2, vec3;
int x = mb_xpos;
int y = mb_ypos;
if ((y == 0) && ((block_num == 0) || (block_num == 1)))
{
if ((x == 0) && (block_num == 0))
return 0;
else if (block_num == 1)
return MV[comp][0][y+1][x+1];
else // block == 0
return MV[comp][1][y+1][x+1-1];
}
else
{
// considerate border (avoid increment inside each single array index)
x++;
y++;
switch (block_num)
{
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: // case 3
vec1 = 2; yin1 = y; xin1 = x;
vec2 = 0; yin2 = y; xin2 = x;
vec3 = 1; yin3 = y; xin3 = x;
break;
}
p1 = MV[comp][vec1][yin1][xin1];
p2 = MV[comp][vec2][yin2][xin2];
p3 = MV[comp][vec3][yin3][xin3];
// return p1 + p2 + p3 - mmax (p1, mmax (p2, p3)) - mmin (p1, mmin (p2, p3));
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;
// left and right edges
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;
}
// top and bottom edges
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;
}
// corners
{
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)
{
storeframe_rgb (frame_ref,coded_picture_width, width, height);
}
void storeframe_rgb (unsigned char *src[], int width_off,int width, int height)
{
int offset_x,offset_y;
int hor_size = horizontal_size;
int r,g,b;
int y,u,v;
FILE *outfile;
const char *mode="wb";
if ((outfile = fopen (outputname, mode)) == NULL)
{
printf ("\n%d Frames are decoded!", picnum);
exit(0);
}
#ifdef RGB
for(offset_y=0;offset_y<height;offset_y++)
{
for(offset_x=0;offset_x<width;offset_x++)
{
y=(int)src[0][offset_y*width_off+offset_x];
u=(int)src[1][(offset_y>>1)*(width_off>>1)+(offset_x>>1)]-128;
v=(int)src[2][(offset_y>>1)*(width_off>>1)+(offset_x>>1)]-128;
u=(u>127) ? 127 :((u<-128) ? -128 : u);
v=(v>127) ? 127 :((v<-128) ? -128 : v);
r=(int)(y+1.402*v);
g=(int)(y-0.34414*u-0.71414*v);
b=(int)(y+1.772*u);
r=(r<0) ? 0 : r;
r=(r>255) ? 255 : r;
g=(g<0) ? 0 : g;
g=(g>255) ? 255 : g;
b=(b<0) ? 0 : b;
b=(b>255) ? 255 : b;
fputc(r,outfile);
putc(g,outfile);
putc(b,outfile);
}
}
#endif
fclose(outfile);
outputname[6]++;
if(outputname[6]>57)
{
outputname[6]-=10;
outputname[5]++;
if(outputname[5]>57)
{
outputname[5]-=10;
outputname[4]++;
if(outputname[4]>48)
{
picnum++;
printf("\n the decoded picnum is\n");
printf("%d",picnum);
//finish = clock();
// duration = (double)(finish - start) / 1000;
// printf("\n time to decode these frames is\n ");
// printf( "%f seconds\n", duration );
exit(0);
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -