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

📄 softidct.cpp

📁 鼎鼎有名的手机mpeg4播放器smart movie-智能影院 解码内核
💻 CPP
📖 第 1 页 / 共 2 页
字号:
   IncPtr(true, true);
                              //V
   CopyBlock8x8(ref_ptr, curr_block_ptr, current_pitch, current_pitch);
}

//----------------------------

static void FillEdge(byte *ptr, int sx, int sy, int EdgeX, int EdgeY){
   int n;
   byte *p;
   int InnerWidth = sx - EdgeX*2;
   int InnerHeight = sy - EdgeY*2;
      
                              //left and right
   p = ptr + EdgeX + EdgeY * sx;
   for(n=0;n<InnerHeight;++n) {
      MemSet(p-EdgeX, p[0], EdgeX);
      MemSet(p+InnerWidth,p[InnerWidth-1], EdgeX);
      p += sx;
   }
                              //top
   p = ptr;
   for (n=0;n<EdgeY;++n) {
      MemCpy(p, ptr+EdgeY * sx, sx);
      p += sx;
   }
                              //bottom
   p = ptr + (sy-EdgeY)*sx;
   for (n=0;n<EdgeY;++n) {
      MemCpy(p, ptr+(sy-EdgeY-1)*sx, sx);
      p += sx;
   }
}

//----------------------------

void C_softidct::FillEdgeYUV(byte *ptr){

                              //Y
   FillEdge(ptr, buffer_sx, buffer_sy, EDGE, EDGE);
                              //U
   ptr += Y_buffer_size;
   FillEdge(ptr, buffer_sx>>UVX2, buffer_sy>>UVY2, EDGE>>UVX2, EDGE>>UVY2);
                              //V
   ptr += Y_buffer_size >> (UVX2+UVY2);
   FillEdge(ptr, buffer_sx>>UVX2, buffer_sy>>UVY2, EDGE>>UVX2, EDGE>>UVY2);
}

//----------------------------

bool C_softidct::SetBufferCount(int n){

   if(n<=bufer_count)
      return true;

   int i;
   if(n>MAXBUF){
      return false;
   }

   for(i=n; i<bufer_count; ++i){
      delete[] buffers[i].allocated;
      buffers[i].allocated = NULL;
   }
   if(bufer_count > n)
      bufer_count = n;

   for(i=bufer_count; i<n; ++i){
      int Align = 32;
      buffers[i].allocated = new byte[buffer_size + Align];
      if(!buffers[i].allocated)
         break;
      /*
      if(i>=2 && AvailMemory()<64*1024){
         delete[] buffers[i].allocated;
         buffer_size = NULL;
         max_buffer_count = bufer_count;
         break;
      }
      */
      buffers[i].ptr = (byte*)(((dword)buffers[i].allocated + Align-1) & ~(Align-1));
      buffers[i].has_border = false;
      buffers[i].frame_index = -1;
      bufer_count = i+1;
#ifdef _DEBUG
      if(i==2)                //fill B-frame buffer to green, for easier detection of problems
         MemSet(buffers[i].ptr, 0x0, buffer_size);
#endif
   }

   if(rendered_buffer_index >= bufer_count)
      rendered_buffer_index = -1;

   return (bufer_count == n);
}

//----------------------------

void C_softidct::FrameStart(int frame_index, int DstNo, int BackNo, int FwdNo, int ShowNo){

   rendered_buffer_index = ShowNo;

   last_frame_index = buffers[DstNo].frame_index;// = -1;
   buffers[DstNo].frame_index = frame_index;

   curr_frame_buffer_ptr = buffers[DstNo].ptr;
   ptr_backward_buffer = NULL;
   ptr_forward_buffer = NULL;
   ptr_b_max = NULL;
   ptr_f_max = NULL;

   if(BackNo>=0){
      ptr_backward_buffer = buffers[BackNo].ptr;
      if(!buffers[BackNo].has_border){
         buffers[BackNo].has_border = true;
         FillEdgeYUV(ptr_backward_buffer);
      }
      ptr_b_max = ptr_backward_buffer + buffer_size -8-8*UV_buffer_pitch;
   }
   if(FwdNo>=0){
      ptr_forward_buffer = buffers[FwdNo].ptr;
      if(!buffers[FwdNo].has_border){
         buffers[FwdNo].has_border = true;
         FillEdgeYUV(ptr_forward_buffer);
      }
      ptr_f_max = ptr_forward_buffer + buffer_size -8-8*UV_buffer_pitch;
   }
                              //invalidate border for dst
   buffers[DstNo].has_border = false;
} 

//----------------------------

C_softidct::C_softidct(dword sx, dword sy):
   bufer_count(0),
   buffer_size(0),
#ifdef ARM
   dyn_code(NULL),
#endif
   image_sx(sx),
   image_sy(sy),
   rendered_buffer_index(-1),
   last_frame_index(-1)
{
   MemSet(buffers, 0, sizeof(buffers));

   IDCT_Const8x8 = ::IDCT_Const8x8;
#ifdef ARM
#ifdef USE_WMMX
   dword cpu_caps = C_dyn_code::GetCpuCaps();
   bool use_wmmx = (cpu_caps & C_dyn_code::CPU_WIRELESS_MMX);
#else
   bool use_wmmx = false;
#endif
   dyn_code = C_dyn_code::Create();
   void BuildMotionCompensationFunctions(C_dyn_code&, bool use_wmmx);
   BuildMotionCompensationFunctions(*dyn_code, use_wmmx);

   void BuildIDCTFunctions(C_dyn_code&, bool use_wmmx);
   BuildIDCTFunctions(*dyn_code, use_wmmx);

   dyn_code->CodeBuild();
   //if(((dword*)dyn_code->Code(0))[-1]!=0xe289409d) Fatal("!", 0);


   int i;
   for(i=0; i<4; i++)
      add_block[i] = (t_AddBlock)dyn_code->Code(i);

   all_copy_block[0][0] = all_copy_block[1][0] = (t_CopyBlock)dyn_code->Code(4);
   for(i=0; i<3; i++){
      all_copy_block[0][1+i] = (t_CopyBlock)dyn_code->Code(5+i*2);
      all_copy_block[1][1+i] = (t_CopyBlock)dyn_code->Code(6+i*2);
   }
   CopyBlock8x8 = (t_CopyBlock)dyn_code->Code(11);
   CopyBlock16x16 = (t_CopyBlock)dyn_code->Code(12);

   IDCT_Block4x8 = (t_IDCT_Block)dyn_code->Code(13);
   IDCT_Block8x8 = (t_IDCT_Block)dyn_code->Code(14);

   if(use_wmmx)
      IDCT_Const8x8 = (t_IDCT_Const8x8)dyn_code->Code(15);
#else
   add_block[0] = AddBlock;
   add_block[1] = AddBlockHor;
   add_block[2] = AddBlockVer;
   add_block[3] = AddBlockHorVer;
   all_copy_block[0][0] = ::CopyBlock;
   all_copy_block[1][0] = ::CopyBlock;

   all_copy_block[0][1] = ::CopyBlockHor;
   all_copy_block[1][1] = ::CopyBlockHorRound;

   all_copy_block[0][2] = ::CopyBlockVer;
   all_copy_block[1][2] = ::CopyBlockVerRound;

   all_copy_block[0][3] = ::CopyBlockHorVer;
   all_copy_block[1][3] = ::CopyBlockHorVerRound;

   CopyBlock8x8 = ::CopyBlock8x8;
   CopyBlock16x16 = ::CopyBlock16x16;
   IDCT_Block4x8 = ::IDCT_Block4x8;
   IDCT_Block8x8 = ::IDCT_Block8x8;
#endif

   temp_buffer_16 = (byte*)(((dword)_temp_buffer + 15) & ~15);

                           //compute sizes of buffers
   const int AlignX = (8 << UVX2) - 1;
   const int AlignY = (8 << UVY2) - 1;

   buffer_sx = ((image_sx+AlignX)&~AlignX)+2*EDGE;
   buffer_sy = ((image_sy+AlignY)&~AlignY)+2*EDGE;

   Y_buffer_size = buffer_sy * buffer_sx;
   buffer_size = Y_buffer_size + 2*(Y_buffer_size >> (UVX2+UVY2));
   UV_buffer_pitch = buffer_sx >> UVX2;

   pass_offset[0] = 8;              //Y[0;0] -> Y[0;1]
   pass_offset[1] = 8*buffer_sx-8;  //Y[0;1] -> Y[1;0]
   pass_offset[2] = 8;              //Y[1;0] -> Y[1;1]
   pass_offset[4] = Y_buffer_size >> 2;    //U->V
   pass_offset[5] = 0;

   SetRounding(false);
}

//----------------------------

C_softidct::~C_softidct(){
   for(int i=0; i<bufer_count; ++i)
      delete[] buffers[i].allocated;
#ifdef ARM
   delete dyn_code;
#endif
}

//----------------------------

⌨️ 快捷键说明

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