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

📄 softidct.cpp

📁 鼎鼎有名的手机mpeg4播放器smart movie-智能影院 解码内核
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
 *
 * This program is free software ; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 * The Core Pocket Media Player
 * Copyright (c) 2004-2005 Gabor Kovacs
 *
 ****************************************************************************/

#include "Rules.h"
#include "Util.h"
#include "SoftIdct.h"
#ifdef ARM
#include "DynamicArmCode.h"
#endif


#define USE_WMMX              //use Wireless MMX, if available by platform and is supported by hardware

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

#define MV_X(v) ((v<<16)>>17)
#define MV_Y(v) (v>>17)
#define MV_SUB(v) (v&1)+((v>>15)&2)

#define UVX2 1
#define UVY2 1

#define EDGE 32

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

void IDCT_Const8x8(int v, byte * Dst,int DstStride, const byte *Src);

                              //ARM-optimized functions:
#ifndef _ARM
void CopyBlock(const byte * Src, byte * Dst, int SrcPitch, int DstPitch);
void CopyBlockHor(const byte * Src, byte * Dst, int SrcPitch, int DstPitch); 
void CopyBlockVer(const byte * Src, byte * Dst, int SrcPitch, int DstPitch);
void CopyBlockHorVer(const byte * Src, byte * Dst, int SrcPitch, int DstPitch);
void CopyBlockHorRound(const byte * Src, byte * Dst, int SrcPitch, int DstPitch);
void CopyBlockVerRound(const byte * Src, byte * Dst, int SrcPitch, int DstPitch);
void CopyBlockHorVerRound(const byte * Src, byte * Dst, int SrcPitch, int DstPitch);

void IDCT_Block4x8(short *Block, byte *Dest, int DestStride, const byte *Src);
void IDCT_Block8x8(short *Block, byte *Dest, int DestStride, const byte *Src);

// AddBlock DstPitch=8
void AddBlock(const byte * Src, byte * Dst, int SrcPitch);
void AddBlockHor(const byte * Src, byte * Dst, int SrcPitch); 
void AddBlockVer(const byte * Src, byte * Dst, int SrcPitch);
void AddBlockHorVer(const byte * Src, byte * Dst, int SrcPitch);

// Src must be aligned
void CopyBlock8x8(const byte * Src, byte * Dst, int SrcPitch,int DstPitch);
void CopyBlock16x16(const byte * Src, byte * Dst, int SrcPitch,int DstPitch);

#endif

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

void C_softidct::Drop(){
   for(int i=0; i<bufer_count; ++i)
      buffers[i].frame_index = -1;
   last_frame_index = -1;
}

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

void C_softidct::IncPtr(bool inc_back, bool inc_forward){
   int v = *pass_ptr++;
   if(v & 0x80000000){
                           //transition from Y to UV
      current_pitch >>= 1;
      v &= 0x7fffffff;
   }
   curr_block_ptr += v;
   if(inc_back)
      curr_back_buf_ptr += v;
   if(inc_forward)
      curr_forward_buf_ptr += v;
}

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

bool C_softidct::GetBuffer(const byte *&Y, const byte *&U, const byte *&V) const{

   if(rendered_buffer_index < 0)
      return false;

   Y = buffers[rendered_buffer_index].ptr + EDGE + EDGE*buffer_sx;
   U = buffers[rendered_buffer_index].ptr + Y_buffer_size + (EDGE >> UVX2) + (EDGE >> UVY2)*(buffer_sx >> UVX2);
   V = U + (Y_buffer_size >> (UVX2+UVY2));
   return true;
}

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

void C_softidct::Inter8x8(short* Block, int Length){

   if(!ptr_forward_buffer){
      int MV = *mv_back++;
      byte *ptr = curr_back_buf_ptr + MV_X(MV) + current_pitch * MV_Y(MV);

      if(Length){
                                 //mcomp and idct (using tmp buffer)
         if(ptr >= ptr_backward_buffer && ptr < ptr_b_max)
            CopyBlock[MV_SUB(MV)](ptr, temp_buffer_16, current_pitch, 8);

         if(Length == 1){
            int v = (Block[0]+4) >> 3;
            if(v)
               IDCT_Const8x8(v, curr_block_ptr, current_pitch, temp_buffer_16);
            else
               CopyBlock8x8(temp_buffer_16, curr_block_ptr, 8, current_pitch);
         }else
         if(Length < 15 || (Length<26 && ((dword*)Block)[2]==0 && ((dword*)Block)[6]==0)){
            IDCT_Block4x8(Block, curr_block_ptr, current_pitch, temp_buffer_16);
         }else{
            IDCT_Block8x8(Block, curr_block_ptr, current_pitch, temp_buffer_16);
         }
      } else {
                                 //only back mcomp
         if(ptr >= ptr_backward_buffer && ptr < ptr_b_max)
            CopyBlock[MV_SUB(MV)](ptr, curr_block_ptr, current_pitch, current_pitch);
      }
      IncPtr(true, false);
   }else{
      if(Length){
                                 //mcomp and idct (using tmp buffer)
         if(mv_back){
            int MV = *mv_back++;
            byte *ptr = curr_back_buf_ptr + MV_X(MV) + current_pitch * MV_Y(MV);
            if(ptr >= ptr_backward_buffer && ptr < ptr_b_max)
               CopyBlock[MV_SUB(MV)](ptr, temp_buffer_16, current_pitch, 8);

            if(mv_forward){
               MV = *mv_forward++;
               ptr = curr_forward_buf_ptr + MV_X(MV) + current_pitch * MV_Y(MV);
               if(ptr >= ptr_forward_buffer && ptr < ptr_f_max)
                  add_block[MV_SUB(MV)](ptr, temp_buffer_16, current_pitch);
            }
         }else
         if(mv_forward){
            int MV = *mv_forward++;
            byte *ptr = curr_forward_buf_ptr + MV_X(MV) + current_pitch * MV_Y(MV);
            if(ptr >= ptr_forward_buffer && ptr < ptr_f_max)
               CopyBlock[MV_SUB(MV)](ptr,temp_buffer_16, current_pitch, 8);
         }

         if(Length == 1){
            int v = (Block[0]+4) >> 3;
            if(v)
               IDCT_Const8x8(v, curr_block_ptr, current_pitch, temp_buffer_16);
            else
               CopyBlock8x8(temp_buffer_16, curr_block_ptr, 8, current_pitch);
         }else
         if(Length < 15){
            IDCT_Block4x8(Block, curr_block_ptr, current_pitch, temp_buffer_16);
         }else{
            IDCT_Block8x8(Block, curr_block_ptr, current_pitch, temp_buffer_16);
         }
      }else{
                                 //interpolate back and foward (using tmp buffer)
         if(mv_back && mv_forward){
            int MV = *mv_back++;
            byte *ptr = curr_back_buf_ptr + MV_X(MV) + current_pitch * MV_Y(MV);
            if(ptr >= ptr_backward_buffer && ptr < ptr_b_max)
               CopyBlock[MV_SUB(MV)](ptr, temp_buffer_16, current_pitch, 8);

            MV = *mv_forward++;
            ptr = curr_forward_buf_ptr + MV_X(MV) + current_pitch * MV_Y(MV);
            if(ptr >= ptr_forward_buffer && ptr < ptr_f_max){
               add_block[MV_SUB(MV)](ptr, temp_buffer_16, current_pitch);
                                 //copy temp_buffer_16 to Dst
               all_copy_block[0][0](temp_buffer_16, curr_block_ptr, 8, current_pitch);
            }
         }else
         if(mv_back){
            int MV = *mv_back++;
            byte *ptr = curr_back_buf_ptr + MV_X(MV) + current_pitch * MV_Y(MV);
            if(ptr >= ptr_backward_buffer && ptr < ptr_b_max)
               CopyBlock[MV_SUB(MV)](ptr, curr_block_ptr, current_pitch, current_pitch);
         }else
         if(mv_forward){
            int MV = *mv_forward++;
            byte *ptr = curr_forward_buf_ptr + MV_X(MV) + current_pitch * MV_Y(MV);
            if(ptr >= ptr_forward_buffer && ptr < ptr_f_max)
               CopyBlock[MV_SUB(MV)](ptr, curr_block_ptr, current_pitch, current_pitch);
         }
      }
      IncPtr(true, true);
   }
}

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

void C_softidct::BeginBlock(int x, int y){
   x = x*16 + EDGE;
   y = (y*16 + EDGE) * buffer_sx;
   current_pitch = buffer_sx;
   curr_block_ptr = curr_frame_buffer_ptr + x + y;
   curr_back_buf_ptr = ptr_backward_buffer + x + y;
   curr_forward_buf_ptr = ptr_forward_buffer + x + y;
   pass_ptr = pass_offset;
                              //Y[1;1] -> U
   pass_offset[3] = (-y-x-8*buffer_sx-8 + Y_buffer_size + (x>>1) + (y>>2)) | 0x80000000;
}

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

void C_softidct::Copy16x16(int x, int y, int Forward){

   BeginBlock(x, y);

   byte *&ref_ptr = Forward ? curr_forward_buf_ptr : curr_back_buf_ptr;
   CopyBlock16x16(ref_ptr, curr_block_ptr, current_pitch, current_pitch);
   {
                              //like 4x IncPtr
      dword v = (pass_offset[0]+pass_offset[1]+pass_offset[2]+pass_offset[3]) & 0x7fffffff;
      current_pitch >>= 1;
      curr_block_ptr += v;
      curr_back_buf_ptr += v;
      curr_forward_buf_ptr += v;
      pass_ptr = pass_offset+4;
   }
                              //U
   CopyBlock8x8(ref_ptr, curr_block_ptr, current_pitch, current_pitch);

⌨️ 快捷键说明

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