www.pudn.com > coremp4-1.0.zip > softidct.h


/***************************************************************************** 
 * 
 * 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 
 * 
 ****************************************************************************/ 
 
#ifndef __IDCT_H 
#define __IDCT_H 
 
#include "Rules.h" 
 
//---------------------------- 
// scan orders (not every data format requires) 
enum{ 
   IDCTSCAN_ZIGZAG, 
   IDCTSCAN_ALT_HORI, 
   IDCTSCAN_ALT_VERT, 
}; 
 
//--------------------------------------------------------------- 
// block format 
// 
// input is a idct_block_t[8][8] matrix 
// which is directly passed to 8x8 idct 
// attention: input matrix is overwritten(trashed) after the call 
// 
// length/scantype is hint how much data is in the matrix 
// block[scan[length..63]] souhld be zero 
// pass length=64 if you can't provide this information 
typedef short idct_block_t; 
 
//---------------------------- 
 
class C_softidct{ 
protected: 
   enum{ MAXBUF = 3 }; 
 
   typedef void (*t_CopyBlock)(const byte *src, byte *dst, int src_pitch, int dst_pitch); 
   typedef void (*t_AddBlock)(const byte*,byte*,int); 
   typedef void (*t_IDCT_Const8x8)(int v, byte *dst, int DstStride, const byte *Src); 
 
   typedef void (*t_IDCT_Block)(short *Block, byte *Dest, int DestStride, const byte *Src); 
 
 
   t_CopyBlock all_copy_block[2][4]; //[8x8/16x16][Rounding][x][y] 
   t_AddBlock add_block[4];            //[x][y] 
   t_CopyBlock CopyBlock8x8, CopyBlock16x16; 
   t_IDCT_Block IDCT_Block4x8, IDCT_Block8x8; 
   t_IDCT_Const8x8 IDCT_Const8x8; 
#ifdef ARM 
   class C_dyn_code *dyn_code; 
#endif 
 
   byte *temp_buffer_16;     //aligned 8x8 or 16x16 temp buffer 
 
   int buffer_sx;    //16 aligned and edge added 
   int buffer_sy;    // '' 
   int Y_buffer_size; 
   int buffer_size; 
   int UV_buffer_pitch; 
   t_CopyBlock *CopyBlock;      //current 4 pointers to CopyBlock functions, set by rounding type 
                              //size of video image 
   int image_sx, image_sy; 
 
   int rendered_buffer_index; 
   int last_frame_index; 
   int bufer_count; 
 
   struct S_buffer{ 
      byte *allocated; 
      byte *ptr;              //aligned to 32-byte boundary 
      int frame_index; 
      bool has_border; 
   } buffers[MAXBUF]; 
 
                              //pointer to beginning of buffer associated with current frame 
   byte *curr_frame_buffer_ptr; 
                              //pointer to current 16x16 block 
   byte *curr_block_ptr; 
                              //pitch of current block pointer 
   int current_pitch; 
 
                              //backward/forward buffer pointers 
   byte *ptr_backward_buffer, *ptr_b_max, *curr_back_buf_ptr; 
   byte *ptr_forward_buffer, *ptr_f_max, *curr_forward_buf_ptr; 
 
   dword pass_offset[6];      //Y/UV pointer increment after each pass (highest bit set means transition from Y to UV - set on 4th step) 
   dword *pass_ptr; 
 
   const int *mv_back, *mv_forward; 
 
   byte _temp_buffer[16*16+16]; 
 
   void FillEdgeYUV(byte *buf); 
   void IncPtr(bool inc_back, bool inc_forward); 
public: 
   C_softidct(dword sx, dword sy); 
   ~C_softidct(); 
 
   void Init(); 
 
   void Drop(); 
 
//---------------------------- 
// Set rounding mode for CopyBlock function. This is typically set once per frame. 
// ('rounding' param could be put to FrameStart function) 
   inline void SetRounding(bool rounding){ 
      CopyBlock = all_copy_block[rounding]; 
   } 
 
//---------------------------- 
// Start decoding a frame. 
   void FrameStart(int frame_index, int Dst, int Back, int Fwd, int Show); 
 
//---------------------------- 
   // copy a macroblock from the backward or forward buffer 
   void Copy16x16(int x, int y, int Forward); 
 
//---------------------------- 
// Start processing a macroblock. 
   void BeginBlock(int x, int y); 
 
//---------------------------- 
// Motion compensation data (these has to be valid during Inter8x8 are called) 
   void SetMotionCompensationData(const int b[6], const int f[6]){ 
      mv_back = b; 
      mv_forward = f; 
   } 
 
//---------------------------- 
   // passing idct data  
   void Intra8x8(idct_block_t* Block, int Length, int ScanType){ 
      if(ScanType!=IDCTSCAN_ALT_HORI && Length < 15) 
         IDCT_Block4x8(Block, curr_block_ptr, current_pitch, NULL); 
      else 
         IDCT_Block8x8(Block, curr_block_ptr, current_pitch, NULL); 
      IncPtr(false, false); 
   } 
 
//---------------------------- 
   // passing idct data (always has to be called even if there is no data) 
   // data is optional (length=0) 
   void Inter8x8(idct_block_t *data, int length); 
 
//---------------------------- 
 
   bool SetBufferCount(int c); 
   inline int GetBufferCount() const{ return bufer_count; } 
 
   inline dword GetBufferPitch() const{ return buffer_sx; } 
 
   bool GetBuffer(const byte *&Y, const byte *&U, const byte *&V) const; 
 
//---------------------------- 
// -1 if content is lost 
   inline int GetPreviousDstFrameIndex() const{ return last_frame_index; } 
 
//---------------------------- 
    
}; 
//---------------------------- 
 
#endif