⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tffpict.cpp

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 CPP
📖 第 1 页 / 共 2 页
字号:
   clear(Trect(rectClipx+rectClipdx,rectClipy,rectFulldx-(rectClipx+rectClipdx),rectClipdy),i);
  }
}
void TffPict::copyBorder(const TffPict &src,unsigned int plane)
{
 if (rectFull==rectClip) return;
 for (unsigned int i=0;i<cspInfo.numPlanes;i++)
  if (plane==PLANE_ALL || i==plane)
   {
    //copy(data[i],stride[i],src.data[i],src.stride[i],src.rectFull.dx>>cspInfo.shiftX[i],src.rectFull.dy>>cspInfo.shiftY[i]);
    const int rectFulldx=rectFull.dx>>cspInfo.shiftX[i],rectFulldy=rectFull.dy>>cspInfo.shiftY[i];
    const int rectClipx =rectClip.x >>cspInfo.shiftX[i],rectClipy =rectClip.y >>cspInfo.shiftY[i];
    const int rectClipdx=rectClip.dx>>cspInfo.shiftX[i],rectClipdy=rectClip.dy>>cspInfo.shiftY[i];
    copyRect(src,Trect(0,0,rectFulldx,rectClipy),i);
    copyRect(src,Trect(0,rectClipy+rectClipdy,rectFulldx,rectFulldy-(rectClipy+rectClipdy)),i);
    copyRect(src,Trect(0,rectClipy,rectClipx,rectClipdy),i);
    copyRect(src,Trect(rectClipx+rectClipdx,rectClipy,rectFulldx-(rectClipx+rectClipdx),rectClipdy),i);
   }
}
void TffPict::copyRect(const TffPict &src,const Trect &r,unsigned int plane)
{
 if (r.dx!=0 && r.dy!=0)
  copy(data[plane]+r.y*stride[plane]+cspInfo.Bpp*r.x,stride[plane],
       src.data[plane]+r.y*src.stride[plane]+cspInfo.Bpp*r.x,src.stride[plane],
   cspInfo.Bpp*r.dx,r.dy);
}

void TffPict::setRO(bool Iro)
{
 for (unsigned int i=0;i<cspInfo.numPlanes;i++) ro[i]=Iro;
}

void TffPict::histogram(unsigned int histogram[256],int full,int half) const
{
 memset(histogram,0,256*sizeof(unsigned int));
 if (csp_isYUVplanar(csp))
  {
   Trect r=getRect(full,half);
   stride_t diff[4];calcDiff(cspInfo,r,stride,diff);
   for (const unsigned char *src=data[0]+diff[0],*srcEnd=src+r.dy*stride[0];src!=srcEnd;src+=stride[0])
    for (unsigned int x=0;x<r.dx;x++)
     histogram[src[x]]++;
  }
 else if ((csp&FF_CSPS_MASK)&FF_CSPS_MASK_YUV_PACKED)
  {
   Trect r=getRect(full,half);
   stride_t diff[4];calcDiff(cspInfo,r,stride,diff);
   int lumaoffset=cspInfo.packedLumaOffset;
   for (const unsigned char *src=data[0]+diff[0],*srcEnd=src+r.dy*stride[0];src!=srcEnd;src+=stride[0])
    for (unsigned int x=0;x<r.dx;x+=2)
     histogram[src[2*x+lumaoffset]]++;
  }
}
void TffPict::calcDiff(const TcspInfo &cspInfo,const Trect &rectClip,const stride_t stride[4],stride_t diff[4])
{
 for (unsigned int i=0;i<cspInfo.numPlanes;i++)
  diff[i]=cspInfo.Bpp*(rectClip.x>>cspInfo.shiftX[i])+(rectClip.y>>cspInfo.shiftY[i])*stride[i];
}
void TffPict::calcDiff(void)
{
 calcDiff(cspInfo,rectClip,stride,diff);
}
void TffPict::copyFrom(const TffPict &p,Tbuffer &buf,const Trect *rectCopy)
{
 if (!rectCopy)
  {
   rectFull=p.rectFull;
   rectClip=p.rectClip;
  }
 else
  rectFull=rectClip=*rectCopy;
 convertCSP(p.csp&FF_CSPS_MASK,buf);
 if (!rectCopy)
  for (unsigned int i=0;i<cspInfo.numPlanes;i++)
   copy(data[i],stride[i],p.data[i],p.stride[i],cspInfo.Bpp*(rectFull.dx>>cspInfo.shiftX[i]),rectFull.dy>>cspInfo.shiftY[i]);
 else
  for (unsigned int i=0;i<cspInfo.numPlanes;i++)
   copy(data[i],stride[i],p.data[i]+p.stride[i]*(rectCopy->y>>p.cspInfo.shiftY[i])+(rectCopy->x>>p.cspInfo.shiftX[i]),p.stride[i],cspInfo.Bpp*(rectFull.dx>>cspInfo.shiftX[i]),rectFull.dy>>cspInfo.shiftY[i]);
}
void TffPict::setCSP(int Icsp)
{
 cspInfo=*csp_getInfo(csp=Icsp);
}
void TffPict::convertCSP(int Icsp,Tbuffer &buf,Tconvert *convert,int edge)
{
 if (csp&FF_CSP_FLAGS_YUV_ADJ)
  {
   csp_yuv_adj_to_plane(csp,&cspInfo,rectFull.dy,data,stride);
   calcDiff();
  }
 if (csp&FF_CSP_FLAGS_YUV_ORDER) csp_yuv_order(csp,data,stride);
 int csp0=csp;
 const unsigned char *data0[4]={data[0],data[1],data[2],data[3]};
 stride_t stride0[4]={stride[0],stride[1],stride[2],stride[3]};
 Tpalette palette0=palette;
 convertCSP(Icsp,buf,edge);
 convert->convert(csp0|((fieldtype&FIELD_TYPE::MASK_INT)?FF_CSP_FLAGS_INTERLACED:0),data0,stride0,csp,data,stride,&palette0);
}
void TffPict::convertCSP(int Icsp,Tbuffer &buf,int edge)
{
 cspInfo=*csp_getInfo(csp=Icsp);
 if (csp_isYUVplanar(csp))
  {
   if (csp&FF_CSP_FLAGS_YUV_ADJ)
    {
     stride[0]=rectFull.dx>>cspInfo.shiftX[0];
     stride[1]=(stride[0]>>cspInfo.shiftX[1])+edge;//((rectFull.dx>>shiftX[1])/16+2)*16;
     stride[2]=(stride[0]>>cspInfo.shiftX[2])+edge;//((rectFull.dx>>shiftX[2])/16+2)*16;
     stride[3]=(stride[0]>>cspInfo.shiftX[3])+edge;//((rectFull.dx>>shiftX[3])/16+2)*16;
     stride[0]+=edge;
    }
   else
    {
     stride[0]=(((rectFull.dx>>cspInfo.shiftX[0])+edge)/16+2)*16;
     stride[1]=(((rectFull.dx>>cspInfo.shiftX[1])+edge)/16+2)*16;
     stride[2]=(((rectFull.dx>>cspInfo.shiftX[2])+edge)/16+2)*16;
     stride[3]=(((rectFull.dx>>cspInfo.shiftX[3])+edge)/16+2)*16;
    }
   size_t size=0;
   for (unsigned int i=0;i<cspInfo.numPlanes;i++)
    size+=stride[i]*((ODD2EVEN(rectFull.dy)>>cspInfo.shiftY[i])+edge); // rectFull.dy should be added by 1 when rectFull.dy is odd number.
   buf.allocZ(size,128);
   data[0]=buf;
   data[1]=data[0]+stride[0]*((ODD2EVEN(rectFull.dy)>>cspInfo.shiftY[0])+edge);
   data[2]=data[1]+stride[1]*((ODD2EVEN(rectFull.dy)>>cspInfo.shiftY[1])+edge);
   data[3]=data[2]+stride[2]*((ODD2EVEN(rectFull.dy)>>cspInfo.shiftY[2])+edge);
  }
 else
  {
   stride[0]=rectFull.dx*cspInfo.Bpp;
   size_t bufsize0=stride[0]*rectFull.dy;
   buf.alloc(bufsize0);
   data[0]=buf;
  }
 calcDiff();
}
void TffPict::alloc(unsigned int dx,unsigned int dy,int Icsp,Tbuffer &buf,int edge)
{
 rectFull=rectClip=Trect(0,0,dx,dy);
 convertCSP(Icsp,buf,edge);
}

// copied from AviSynth
/*****************************
 * Assembler bitblit by Steady
 *****************************/

void TffPict::asm_BitBlt_MMX(BYTE* dstp, stride_t dst_pitch, const BYTE* srcp, stride_t src_pitch, int row_size, int height) {
  if (height==0 || row_size==0) return;
  const unsigned char *esi=srcp+(height-1)*src_pitch;unsigned char *edi=dstp+(height-1)*dst_pitch;
  int row_size15=row_size-15;
  for (;height;height--,esi-=src_pitch,edi-=dst_pitch)
   {
    int ebx;
    for (ebx=0;ebx<row_size15;ebx+=16)
     {
      __m64 mm0=*(__m64*)(esi+ebx);
      __m64 mm1=*(__m64*)(esi+ebx+8);
      *(__m64*)(edi+ebx)=mm0;
      *(__m64*)(edi+ebx+8)=mm1;
     }
    for (;ebx<row_size;ebx++)
     edi[ebx]=esi[ebx];
   }
 _mm_empty();
}


void TffPict::asm_BitBlt_C(BYTE* dstp, stride_t dst_pitch, const BYTE* srcp, stride_t src_pitch, int row_size, int height)
{
  if (dst_pitch == src_pitch && src_pitch == row_size) {
    memcpy(dstp, srcp, src_pitch * height);
  } else {
    for (int y=height; y>0; --y) {
      memcpy(dstp, srcp, row_size);
      dstp += dst_pitch;
      srcp += src_pitch;
    }
  }
}

void TffPict::clear(int Bpp,unsigned int black,unsigned char *dst,stride_t stride,unsigned int row_size,unsigned int height)
{
 switch (Bpp)
  {
   case 1:
    for (unsigned int y=0;y<height;y++)
     memset(dst+y*stride,black,row_size);
    return;
   case 2:
    black|=black<<16;
    for (unsigned int y=0;y<height;y++)
     for (uint32_t *p=(uint32_t*)(dst+y*stride),*pEnd=(uint32_t*)((uint8_t*)p+(row_size&~3));p!=pEnd;p++)
      *p=black;
    return;
   case 3:
    for (unsigned int y=0;y<height;y++)
     for (uint8_t *p=dst+y*stride,*pEnd=p+row_size;p!=pEnd;p+=3)
      {
       p[0]=((uint8_t*)&black)[0];
       p[1]=((uint8_t*)&black)[1];
       p[2]=((uint8_t*)&black)[2];
      }
    return;
   case 4:
    for (unsigned int y=0;y<height;y++)
     memsetd((uint32_t*)(dst+y*stride),black,row_size);
    return;
  }
}

void TffPict::draw_edges(uint8_t *buf, stride_t wrap, int width, int height, int w)
{
    uint8_t *ptr, *last_line;
    int i;

    last_line = buf + (height - 1) * wrap;
    for(i=0;i<w;i++) {
        /* top and bottom */
        memcpy(buf - (i + 1) * wrap, buf, width);
        memcpy(last_line + (i + 1) * wrap, last_line, width);
    }
    /* left and right */
    ptr = buf;
    for(i=0;i<height;i++) {
        memset(ptr - w, ptr[0], w);
        memset(ptr + width, ptr[width-1], w);
        ptr += wrap;
    }
    /* corners */
    for(i=0;i<w;i++) {
        memset(buf - (i + 1) * wrap - w, buf[0], w); /* top left */
        memset(buf - (i + 1) * wrap + width, buf[width-1], w); /* top right */
        memset(last_line + (i + 1) * wrap - w, last_line[0], w); /* top left */
        memset(last_line + (i + 1) * wrap + width, last_line[width-1], w); /* top right */
    }
}

void TffPict::createEdge(unsigned int Iedge,Tbuffer &buf)
{
 if (edge>=Iedge) return;
 edge=Iedge;
 Trect rectFull0=rectFull,rectClip0=rectClip;
 stride_t stride0[4];memcpy(stride0,stride,sizeof(stride));
 unsigned char *data0[4];memcpy(data0,data,sizeof(data));
 alloc(rectFull.dx,rectFull.dy,csp,buf,2*edge);
 rectFull=rectEdge=Trect(0,0,rectFull.dx+edge*2,rectFull.dy+edge*2);
 rectClip=Trect(edge,edge,rectFull0.dx,rectFull0.dy);
 calcDiff();
 for (unsigned int i=0;i<cspInfo.numPlanes;i++)
  {
   edgeData[i]=data[i];
   unsigned int dx=rectFull0.dx>>cspInfo.shiftX[i],dy=rectFull0.dy>>cspInfo.shiftY[i];
   copy(data[i]+=diff[i],stride[i],data0[i],stride0[i],dx*cspInfo.Bpp,dy);
   draw_edges(data[i],stride[i],dx,dy,edge);
  }
 rectFull=rectFull0;rectClip=rectClip0;
 calcDiff();
}

void TffPict::md5sum(uint8_t sum[16]) const
{
 memset(sum,0,16);
 Tmd5 md5;
 for (unsigned int i=0;i<cspInfo.numPlanes;i++)
  for (unsigned int y=0;y<rectFull.dy>>cspInfo.shiftY[i];y++)
   md5.sum(data[i]+y*stride[i],rectFull.dx>>cspInfo.shiftX[i]);
 md5.done(sum);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -