📄 recon.cc
字号:
/* File: recon.hh */#include "all.hh"// #define HAVE_3Dnow#ifdef HAVE_MMX#ifndef HAVE_3Dnow static long long ADD_1 = 0x0101010101010101LL; static long long MASK_AND = 0x7f7f7f7f7f7f7f7fLL;#endif#endif#ifdef HAVE_MMX#ifndef HAVE_3Dnowextern "C" void recva(unsigned char *s, unsigned char *d, int lx, int lx2, int h);extern "C" void recvac(unsigned char *s, unsigned char *d, int lx, int lx2, int h);extern "C" void rech(unsigned char *s, unsigned char *d, int lx2, int h);extern "C" void rechc(unsigned char *s, unsigned char *d, int lx2, int h);#else inline void recva(unsigned char *s, unsigned char *d, int lx, int lx2, int h); inline void recvac(unsigned char *s, unsigned char *d, int lx, int lx2, int h); inline void rech(unsigned char *s, unsigned char *d, int lx2, int h); inline void rechc(unsigned char *s, unsigned char *d, int lx2, int h);#endif#else inline void recva(unsigned char *s, unsigned char *d, int lx, int lx2, int h); inline void recvac(unsigned char *s, unsigned char *d, int lx, int lx2, int h); inline void rech(unsigned char *s, unsigned char *d, int lx2, int h); inline void rechc(unsigned char *s, unsigned char *d, int lx2, int h);#endifinline void rec(unsigned char *s, unsigned char *d, int lx2, int h);inline void recc(unsigned char *s, unsigned char *d, int lx2, int h);inline void reca(unsigned char *s, unsigned char *d, int lx2, int h);inline void recac(unsigned char *s, unsigned char *d, int lx2, int h);inline void recv(unsigned char *s, unsigned char *d, int lx, int lx2, int h);inline void recvc(unsigned char *s, unsigned char *d, int lx, int lx2, int h);inline void recha(unsigned char *s, unsigned char *d, int lx2, int h);inline void rechac(unsigned char *s, unsigned char *d, int lx2, int h);inline void rec4(unsigned char *s, unsigned char *d, int lx, int lx2, int h);inline void rec4c(unsigned char *s, unsigned char *d, int lx, int lx2, int h);inline void rec4a(unsigned char *s, unsigned char *d, int lx, int lx2, int h);inline void rec4ac(unsigned char *s, unsigned char *d, int lx, int lx2, int h);void recon_comp(unsigned char *src, unsigned char *dst, int lx, int lx2, int w, int h, int x, int y, int dx, int dy, int addflag);void recon(unsigned char *src[], int sfield, unsigned char *dst[], int dfield, int lx,int lx2, int w, int h, int x, int y, int dx, int dy, int addflag){ /* unsigned char *src[]; * prediction source buffer * int sfield; * prediction source field number (0 or 1) * unsigned char *dst[]; * prediction destination buffer * int dfield; * prediction destination field number (0 or 1)* int lx,lx2; * horizontal offsets * int w,h; * prediction block/sub-block width, height * int x,y; * pixel co-ordinates of top-left sample in current MB * int dx,dy; * horizontal, vertical motion vector * int addflag; * add prediction error to prediction ? * */ /* Y */ recon_comp((src[0]+(sfield?lx2>>1:0)), dst[0]+(dfield?lx2>>1:0), lx,lx2,w,h,x,y,dx,dy,addflag); if (chroma_format!=CHROMA444){ lx>>=1; dx/=2;lx2>>=1; w = 0; x>>=1; } if (chroma_format==CHROMA420){ h>>=1; dy/=2;y>>=1; } /* Cb */ recon_comp((src[1]+(sfield?lx2>>1:0)), dst[1]+(dfield?lx2>>1:0), lx,lx2,w,h,x,y,dx,dy,addflag); /* Cr */ recon_comp((src[2]+(sfield?lx2>>1:0)), dst[2]+(dfield?lx2>>1:0), lx,lx2,w,h,x,y,dx,dy,addflag);}//#define WIDTH 16#define WIDTH 1void LayerData::reconstruct(int bx, int by, int mb_type, int motion_type, int PMV[2][2][2], int mv_field_sel[2][2], int dmvector[2], int stwtype){ int currentfield; unsigned char **predframe; int DMV[2][2]; int stwtop, stwbot; stwtop = stwtype%3; /* 0:temporal, 1:(spat+temp)/2, 2:spatial */ stwbot = stwtype/3; if ((mb_type & MB_FORWARD) || (pict_type==P_TYPE)){ if (pict_struct==FRAME_PICTURE){ if ((motion_type==MC_FRAME) || !(mb_type & MB_FORWARD)){ /* frame-based prediction */ { if (stwtop<2) recon(oldrefframe,0,newframe,0, coded_picture_width,coded_picture_width<<1,WIDTH,8,bx,by, PMV[0][0][0],PMV[0][0][1],stwtop); if (stwbot<2) recon(oldrefframe,1,newframe,1, coded_picture_width,coded_picture_width<<1,WIDTH,8,bx,by, PMV[0][0][0],PMV[0][0][1],stwbot); } } else if (motion_type==MC_FIELD) /* field-based prediction */ { /* top field prediction */ if (stwtop<2) recon(oldrefframe,mv_field_sel[0][0],newframe,0, coded_picture_width<<1,coded_picture_width<<1,WIDTH,8,bx,by>>1, PMV[0][0][0],PMV[0][0][1]>>1,stwtop); /* bottom field prediction */ if (stwbot<2) recon(oldrefframe,mv_field_sel[1][0],newframe,1, coded_picture_width<<1,coded_picture_width<<1,WIDTH,8,bx,by>>1, PMV[1][0][0],PMV[1][0][1]>>1,stwbot); } else if (motion_type==MC_DMV){ /* dual prime prediction */ /* calculate derived motion vectors */ ld->calc_DMV(DMV,dmvector,PMV[0][0][0],PMV[0][0][1]>>1); if (stwtop<2){ /* predict top field from top field */ recon(oldrefframe,0,newframe,0, coded_picture_width<<1,coded_picture_width<<1,WIDTH,8,bx,by>>1, PMV[0][0][0],PMV[0][0][1]>>1,0); /* predict and add to top field from bottom field */ recon(oldrefframe,1,newframe,0, coded_picture_width<<1,coded_picture_width<<1,WIDTH,8,bx,by>>1, DMV[0][0],DMV[0][1],1); } if (stwbot<2) { /* predict bottom field from bottom field */ recon(oldrefframe,1,newframe,1, coded_picture_width<<1,coded_picture_width<<1,WIDTH,8,bx,by>>1, PMV[0][0][0],PMV[0][0][1]>>1,0); /* predict and add to bottom field from top field */ recon(oldrefframe,0,newframe,1, coded_picture_width<<1,coded_picture_width<<1,WIDTH,8,bx,by>>1, DMV[1][0],DMV[1][1],1); } } else /* invalid motion_type */ if (!quiet) printf("invalid motion_type\n"); } else /* TOP_FIELD or BOTTOM_FIELD */ { /* field picture */ currentfield = (pict_struct==BOTTOM_FIELD); /* determine which frame to use for prediction */ if ((pict_type==P_TYPE) && secondfield && (currentfield!=mv_field_sel[0][0])) predframe = refframe; /* same frame */ else predframe = oldrefframe; /* previous frame */ if ((motion_type==MC_FIELD) || !(mb_type & MB_FORWARD)) { /* field-based prediction */ if (stwtop<2) recon(predframe,mv_field_sel[0][0],newframe,0, coded_picture_width<<1,coded_picture_width<<1,WIDTH,16,bx,by, PMV[0][0][0],PMV[0][0][1],stwtop); } else if (motion_type==MC_16X8) { if (stwtop<2) { recon(predframe,mv_field_sel[0][0],newframe,0, coded_picture_width<<1,coded_picture_width<<1,WIDTH,8,bx,by, PMV[0][0][0],PMV[0][0][1],stwtop); /* determine which frame to use for lower half prediction */ if ((pict_type==P_TYPE) && secondfield && (currentfield!=mv_field_sel[1][0])) predframe = refframe; /* same frame */ else predframe = oldrefframe; /* previous frame */ recon(predframe,mv_field_sel[1][0],newframe,0, coded_picture_width<<1,coded_picture_width<<1,WIDTH,8,bx,by+8, PMV[1][0][0],PMV[1][0][1],stwtop); } } else if (motion_type==MC_DMV) /* dual prime prediction */ { if (secondfield) predframe = refframe; /* same frame */ else predframe = oldrefframe; /* previous frame */ /* calculate derived motion vectors */ calc_DMV(DMV,dmvector,PMV[0][0][0],PMV[0][0][1]); /* predict from field of same parity */ recon(oldrefframe,currentfield,newframe,0, coded_picture_width<<1,coded_picture_width<<1,WIDTH,16,bx,by, PMV[0][0][0],PMV[0][0][1],0); /* predict from field of opposite parity */ recon(predframe,!currentfield,newframe,0, coded_picture_width<<1,coded_picture_width<<1,WIDTH,16,bx,by, DMV[0][0],DMV[0][1],1); } else /* invalid motion_type */ printf("invalid motion_type\n"); } stwtop = stwbot = 1; } if (mb_type & MB_BACKWARD) { if (pict_struct==FRAME_PICTURE) { if (motion_type==MC_FRAME) { /* frame-based prediction */ if (stwtop<2) recon(refframe,0,newframe,0, coded_picture_width,coded_picture_width<<1,WIDTH,8,bx,by, PMV[0][1][0],PMV[0][1][1],stwtop); if (stwbot<2) recon(refframe,1,newframe,1, coded_picture_width,coded_picture_width<<1,WIDTH,8,bx,by, PMV[0][1][0],PMV[0][1][1],stwbot); } else { /* field-based prediction */ /* top field prediction */ if (stwtop<2){ recon(refframe,mv_field_sel[0][1],newframe,0, (coded_picture_width<<1), (coded_picture_width<<1),WIDTH,8,bx, (by>>1), PMV[0][1][0], (PMV[0][1][1]>>1), stwtop); } /* bottom field prediction */ if (stwbot<2){ recon(refframe, mv_field_sel[1][1], newframe, 1, (coded_picture_width<<1), (coded_picture_width<<1), WIDTH, 8, bx, (by>>1), PMV[1][1][0], (PMV[1][1][1]>>1), stwbot); } } } else { /* TOP_FIELD or BOTTOM_FIELD */ /* field picture */ if (motion_type==MC_FIELD){ /* field-based prediction */ recon(refframe,mv_field_sel[0][1],newframe,0, coded_picture_width<<1,coded_picture_width<<1,WIDTH,16,bx,by, PMV[0][1][0],PMV[0][1][1],stwtop); } else if (motion_type==MC_16X8) { recon(refframe,mv_field_sel[0][1],newframe,0, coded_picture_width<<1,coded_picture_width<<1,WIDTH,8,bx,by, PMV[0][1][0],PMV[0][1][1],stwtop); recon(refframe,mv_field_sel[1][1],newframe,0, coded_picture_width<<1,coded_picture_width<<1,WIDTH,8,bx,by+8, PMV[1][1][0],PMV[1][1][1],stwtop); } else /* invalid motion_type */ printf("invalid motion_type\n"); } } /* mb_type & MB_BACKWARD */}inline void rec(unsigned char *s, unsigned char *d, int lx2, int h){#ifdef HAVE_MMX __asm__ __volatile__( ".align 8\n" "1:\t" "movq ( %1 ), %%mm0\n" /* 8 s */ "movq 8( %1 ), %%mm2\n" /* 16 s */ "movq %%mm0, ( %2 )\n" "addl %3, %1\n" "movq %%mm2, 8( %2 )\n" "decl %0\n" "leal (%2, %3), %2\n" "jnz 1b" : : "c" (h), "r" (s), "r" (d), "r" (lx2) ); #else for (int j=0; j<h; j++, s+=lx2, d+=lx2){ d[0] = s[0];d[1] = s[1];d[2] = s[2];d[3] = s[3]; d[4] = s[4];d[5] = s[5];d[6] = s[6];d[7] = s[7]; d[8] = s[8];d[9] = s[9];d[10] = s[10];d[11] = s[11]; d[12] = s[12];d[13] = s[13];d[14] = s[14];d[15] = s[15]; }#endif}inline void recc(unsigned char *s, unsigned char *d, int lx2, int h){#ifdef HAVE_MMX __asm__ __volatile__( ".align 8\n" "1:\t" "movq ( %1 ), %%mm0\n" "addl %3, %1\n" "movq %%mm0, ( %2 )\n" "decl %0\n" "leal (%2, %3), %2\n" "jnz 1b" : : "c" (h), "r" (s), "r" (d), "r" (lx2) ); #else for (int j=0; j<h; j++, s+=lx2, d+=lx2){ d[0] = s[0];d[1] = s[1];d[2] = s[2];d[3] = s[3]; d[4] = s[4];d[5] = s[5];d[6] = s[6];d[7] = s[7]; }#endif}inline void reca(unsigned char *s,unsigned char *d, int lx2, int h){#ifdef HAVE_MMX #ifdef HAVE_3Dnow __asm__ ( ".align 8\n" "1:" "movq (%1), %%mm0\n" /* 8 s */ "movq (%2), %%mm2\n" /* 8 d */ "movq 8(%1), %%mm1\n" /* 8 s */ "movq 8(%2), %%mm3\n" /* 8 d */ "pavgusb %%mm2, %%mm0\n" "addl %3, %1\n" "pavgusb %%mm3, %%mm1\n" "movq %%mm0, (%2)\n" "movq %%mm1, 8(%2)\n" "addl %3, %2\n" "loop 1b\n" : : "c" (h), "r" (s), "r" (d), "r" (lx2) ); #else __asm__ ( "movq MASK_AND, %%mm5\n" "movq ADD_1, %%mm6\n" "1:\t" "movq (%1),%%mm0\n" "movq (%2),%%mm1\n" "movq 8(%1),%%mm2\n" "movq 8(%2),%%mm3\n" "psrlw $1,%%mm0\n" "psrlw $1,%%mm1\n" "psrlw $1,%%mm2\n" "psrlw $1,%%mm3\n" "pand %%mm5,%%mm0\n" "pand %%mm5,%%mm1\n" "pand %%mm5,%%mm2\n" "pand %%mm5,%%mm3\n" "paddusb %%mm1,%%mm0\n" "paddusb %%mm3,%%mm2\n" "paddusb %%mm6,%%mm0\n" "paddusb %%mm6,%%mm2\n" "movq %%mm0,(%2)\n" "addl %3,%1\n" "movq %%mm2, 8(%2)\n" "decl %0\n" "leal (%2, %3), %2\n" "jnz 1b\n" : : "c" (h), "r" (s), "r" (d), "r" (lx2) ); #endif#else for (int j=0; j<h; j++, s+=lx2, d+=lx2){ d[0] = (unsigned int)(d[0] + s[0] + 1)>>1; d[1] = (unsigned int)(d[1] + s[1] + 1)>>1; d[2] = (unsigned int)(d[2] + s[2] + 1)>>1; d[3] = (unsigned int)(d[3] + s[3] + 1)>>1; d[4] = (unsigned int)(d[4] + s[4] + 1)>>1; d[5] = (unsigned int)(d[5] + s[5] + 1)>>1; d[6] = (unsigned int)(d[6] + s[6] + 1)>>1; d[7] = (unsigned int)(d[7] + s[7] + 1)>>1; d[8] = (unsigned int)(d[8] + s[8] + 1)>>1; d[9] = (unsigned int)(d[9] + s[9] + 1)>>1; d[10] = (unsigned int)(d[10] + s[10] + 1)>>1; d[11] = (unsigned int)(d[11] + s[11] + 1)>>1; d[12] = (unsigned int)(d[12] + s[12] + 1)>>1; d[13] = (unsigned int)(d[13] + s[13] + 1)>>1; d[14] = (unsigned int)(d[14] + s[14] + 1)>>1; d[15] = (unsigned int)(d[15] + s[15] + 1)>>1; }#endif}inline void recac(unsigned char *s, unsigned char *d, int lx2, int h){#ifdef HAVE_MMX #ifdef HAVE_3Dnow
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -