home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2004 March / PCWELT_3_2004.ISO / pcwsoft / flaskmpeg_078_39_src.z.exe / flaskmpeg / FrameSource.h < prev    next >
Encoding:
C/C++ Source or Header  |  2002-10-28  |  10.7 KB  |  427 lines

  1. /* 
  2.  *  FrameSource.h
  3.  *
  4.  *    Copyright (C) Alberto Vigata - July 2000 - ultraflask@yahoo.com
  5.  *
  6.  *  This file is part of FlasKMPEG, a free MPEG to MPEG/AVI converter
  7.  *    
  8.  *  FlasKMPEG is free software; you can redistribute it and/or modify
  9.  *  it under the terms of the GNU General Public License as published by
  10.  *  the Free Software Foundation; either version 2, or (at your option)
  11.  *  any later version.
  12.  *   
  13.  *  FlasKMPEG is distributed in the hope that it will be useful,
  14.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  *  GNU General Public License for more details.
  17.  *   
  18.  *  You should have received a copy of the GNU General Public License
  19.  *  along with GNU Make; see the file COPYING.  If not, write to
  20.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  21.  *
  22.  */
  23.  
  24.  
  25. #ifndef FRAMESOURCE_H
  26. #define FRAMESOURCE_H
  27.  
  28.  
  29. #define FRAME_INTERLACED  0x01  // Full frame but interlaced
  30. #define FRAME_PROGRESSIVE 0x02  // Full progressive frame
  31. #define FRAME_TOPFIELD    0x04  // Just top field present
  32. #define FRAME_BOTTOMFIELD 0x08  // Just bottom field present
  33. #define FRAME_ISLASTFRAME 0x10  // Last frame of the stream
  34.  
  35.  
  36. #define FRAME_MEM_ALIGN   16
  37.  
  38. #define MAX_BUF 2048*2048*32
  39.  
  40. #include <windows.h>
  41. #include "flasktypes.h"
  42. #include "thread.h"
  43. #include "FormatDefs.h"
  44. #include "cpusupport.h"
  45. #include <list>
  46. using namespace std;
  47.  
  48.  
  49.         
  50. // YUV444 Format definition
  51. //   The buffer points to a struct
  52. //   like this one.
  53. typedef struct
  54. {
  55.   unsigned char *y;
  56.   unsigned char *a;
  57.   int              luma_width;
  58.   int              luma_height;
  59.   unsigned char *u;
  60.   unsigned char *v;
  61.   int          chroma_width;
  62.   int          chroma_height;
  63. } TYUVImage;
  64.  
  65.  
  66.  
  67. class CFrame;
  68. class CFrameBuffer
  69. {
  70. public:
  71.     virtual ~CFrameBuffer(){};
  72.     virtual CFrame *GetFreeFrame() =0;
  73.     virtual void AddFreeFrame(CFrame *pFrame) =0;
  74. };
  75.  
  76. class CFrame
  77. {
  78. public:
  79.   CFrame( CFrameBuffer *pFrameBuffer = NULL)
  80.   {
  81.     m_pFrameBuffer = pFrameBuffer;
  82.     m_nPresTime     = 0;
  83.     m_nWidth = m_nHeight = 0;
  84.     m_nFormat = 0;
  85.     m_nDepth = 0;
  86.     m_nPitch = 0;
  87.     m_nRef = 0;
  88.     m_pData = 0;
  89.     m_nDuration = 0;
  90.     m_nFrameFlags = 0;
  91.     m_nAllocatedSize = 0;
  92.     m_bOwnBuffer = false;
  93.     m_pUpsample444 = NULL;
  94.     m_pUpsample422 = NULL;
  95.     m_pOverlayTemp = NULL;
  96.     m_nCPUExtensions = CPUGetSupportedExtensions();
  97.     memset( &m_sBitmapInfo, 0, sizeof( m_sBitmapInfo ) );
  98.  
  99.     m_pClp = new ui8[1024];
  100.     m_pClp += 384;
  101.  
  102.     for (int i=-384; i<640; i++)
  103.       m_pClp[i] = (i<0) ? 0 : ((i>255) ? 255 : i);
  104.    }
  105.  
  106.   ~CFrame(){
  107.     m_pClp -= 384;
  108.     delete []m_pClp;
  109.     
  110.     DeAlloc();
  111.   };
  112.   
  113.  
  114.   CFrame &operator =(CFrame &oFrame)
  115.   {
  116.     if(!oFrame.IsValid())
  117.       return *this;
  118.     // free my buffer.
  119.     DeAlloc();
  120.  
  121.     m_nDuration = oFrame.GetDuration();
  122.     m_nWidth = oFrame.GetWidth();
  123.     m_nHeight = oFrame.GetHeight();
  124.     m_nPresTime = oFrame.GetPresTime();
  125.     m_nFormat = oFrame.GetFormat();
  126.     m_nDepth = oFrame.GetDepth();
  127.     m_nFrameFlags = oFrame.GetFlags();
  128.     m_nPitch = oFrame.GetPitch();
  129.     m_bOwnBuffer = true;
  130.     Alloc(GetRequiredMem());
  131.     memcpy( m_pData, oFrame.GetBuffer(), oFrame.GetBufferSize() );
  132.     return *this;
  133.   }
  134.   void Release()
  135.   {
  136.     CFlAutoLock lockObject(&m_csObject);
  137.     //ASSERT(m_nRef>0);
  138.     if(m_nRef==0)
  139.       return;
  140.  
  141.     m_nRef--;
  142.     if(m_nRef==0)
  143.       if(m_pFrameBuffer)
  144.         m_pFrameBuffer->AddFreeFrame(this);
  145.   }
  146.   void AddRef()
  147.   {
  148.     CFlAutoLock lockObject(&m_csObject);
  149.     m_nRef++;
  150.   }
  151.   void SetPresTime( ui64 nPresTime ) { m_nPresTime = nPresTime; }
  152.  
  153.   void Set( ui32 nWidth, ui32 nHeight, ui32 nFormat, ui32 nFlags=FRAME_PROGRESSIVE )
  154.   {
  155.     // Don't do anything, if the format matches the current
  156.     if( m_nWidth==nWidth && m_nHeight==nHeight && m_nFormat==nFormat)
  157.         return;
  158.  
  159.  
  160.     m_nFormat = nFormat;
  161.     SetDepth();
  162.     SetSize( nWidth, nHeight );
  163.     m_nFrameFlags = nFlags;
  164.     
  165.     // If already enough memory in buffer, don't reallocate
  166.     if( GetRequiredMem() > m_nAllocatedSize )
  167.     {
  168.       DeAlloc();
  169.       Alloc(GetRequiredMem());
  170.     }
  171.   }
  172.  
  173.   // Overlay pOverlay with offsets nX,nY
  174.   void Overlay( ui32 nX, ui32 nY, CFrame *pOverlay );
  175.  
  176.   // void SetBuffer ( ui8 *pData ){ m_pData = pData; }
  177.   void SetFlags ( ui32 nFlags ){ m_nFrameFlags = nFlags; }
  178.   void SetLastFrame(){ m_nFrameFlags |= FRAME_ISLASTFRAME; }
  179.   void SetDuration( ui32 nDuration ){ m_nDuration = nDuration; }
  180.   ui32 GetDuration(){ return m_nDuration; }
  181.   ui8* GetBuffer(){ return m_pData; }
  182.   ui32 GetWidth(){ return m_nWidth; }
  183.   ui32 GetHeight(){ return m_nHeight; }
  184.   ui64 GetPresTime(){ return m_nPresTime; }
  185.   ui32 GetFormat(){ return m_nFormat; }
  186.   ui32 GetDepth(){ return m_nDepth; }
  187.   ui32 GetFlags(){ return m_nFrameFlags; }
  188.   ui32 GetPitch(){ return m_nPitch; }
  189.  
  190.   bool IsInterlaced(){ return (m_nFrameFlags&FRAME_INTERLACED)>0; }  
  191.   bool IsProgressive(){ return (m_nFrameFlags&FRAME_PROGRESSIVE)>0; }
  192.   bool IsField(){ return (m_nFrameFlags&FRAME_TOPFIELD) || (m_nFrameFlags&FRAME_BOTTOMFIELD); }
  193.   bool IsFull(){ return (m_nFrameFlags&FRAME_PROGRESSIVE) || (m_nFrameFlags&FRAME_INTERLACED); }
  194.   bool IsLastFrame() { return (m_nFrameFlags&FRAME_ISLASTFRAME)>0; }
  195.   
  196.   void Erase()
  197.   {
  198.     switch(m_nFormat)
  199.     {
  200.       case FRAME_RGB32:
  201.       case FRAME_YV12:
  202.       case FRAME_YUY2:
  203.       case FRAME_YUV422:
  204.       case FRAME_YUV444:
  205.       case FRAME_YUV444A:
  206.       case FRAME_YV12A:
  207.         memset( m_pData, 0, GetBufferSize() ) ;
  208.         break;
  209.     }
  210.     return;
  211.   }
  212.  
  213.   ui8 *aligned_new(ui32 nSize)
  214.   {
  215.     int nAllocatedOffset;
  216.     ui8 *pAligned, *pData;
  217.  
  218.     if(!nSize)
  219.       return NULL;
  220.     // Increase the allocated
  221.     // memory to be able to align
  222.     nSize += 2*FRAME_MEM_ALIGN;
  223.     // Allocate
  224.     pData = new ui8[nSize];
  225.     if(!pData)
  226.       return NULL;
  227.     nAllocatedOffset = ((ui32)pData)%FRAME_MEM_ALIGN;
  228.     pAligned = pData + nAllocatedOffset + FRAME_MEM_ALIGN;
  229.     // Store original pointer
  230.     *((ui8 **)pAligned - 1) = pData;
  231.  
  232.     return pAligned;
  233.   }
  234.   void aligned_delete(ui8 *pAligned)
  235.   {
  236.     ui8 *pData;
  237.     pData = *((ui8 **)pAligned - 1);
  238.  
  239.     delete []pData;
  240.   }
  241.  
  242.   ui32 GetBufferSize()
  243.   {
  244.     return GetRequiredMem();
  245.   }
  246.   BITMAPINFO *GetBmpInfo()
  247.   {
  248.     m_sBitmapInfo.bmiHeader.biWidth  = m_nWidth;
  249.     m_sBitmapInfo.bmiHeader.biHeight = m_nHeight;
  250.     m_sBitmapInfo.bmiHeader.biCompression = m_nFormat==FRAME_RGB32 ? BI_RGB : m_nFormat;
  251.     m_sBitmapInfo.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
  252.     m_sBitmapInfo.bmiHeader.biPlanes = 1;
  253.     m_sBitmapInfo.bmiHeader.biBitCount = (WORD)m_nDepth;
  254.     return &m_sBitmapInfo;
  255.   }
  256.   bool GetFromBmp(HBITMAP hBitmap)
  257.   {
  258.     // Getinfo of the bitmap
  259.     BITMAP sBitmap;
  260.     if(!GetObject( hBitmap, sizeof(BITMAP),&sBitmap ))
  261.       return false;
  262.  
  263.     DeAlloc();
  264.     // Set properties for out bitmap
  265.     // and allocate the space for it
  266.     m_nWidth  = sBitmap.bmWidth;
  267.     m_nHeight = sBitmap.bmHeight;
  268.     m_nDepth  = 32;
  269.     m_nPitch  = m_nWidth * 4;
  270.     m_nFormat = FRAME_RGB32;
  271.     Alloc(GetRequiredMem());
  272.     // Get the bitmap data
  273.     HDC hDCScreen = GetDC( NULL );
  274.  
  275.     if(!GetDIBits( hDCScreen, hBitmap, 0, m_nHeight, m_pData, GetBmpInfo(), DIB_RGB_COLORS))
  276.       return false;
  277.   
  278.       return true;
  279.   }
  280.  
  281.   void GetYuvInfo(TYUVImage *pYuv)
  282.   {
  283.     int lumasize, chromasize;
  284.  
  285.     if(!pYuv || !m_pData)
  286.       return;
  287.  
  288.     switch( m_nFormat )
  289.     {
  290.       case FRAME_YV12:
  291.       case FRAME_YV12A:
  292.         pYuv->chroma_width = m_nWidth/2;
  293.         pYuv->chroma_height = m_nHeight/2;
  294.         break;
  295.       case FRAME_YUV422:
  296.         pYuv->chroma_width = m_nWidth/2;
  297.         pYuv->chroma_height = m_nHeight;
  298.         break;
  299.       case FRAME_YUV444:
  300.       case FRAME_YUV444A:
  301.         pYuv->chroma_width = m_nWidth;
  302.         pYuv->chroma_height = m_nHeight;
  303.         break;
  304.       default:
  305.         memset( pYuv, 0, sizeof TYUVImage );
  306.         return;
  307.     }
  308.  
  309.     pYuv->luma_width  = m_nWidth;
  310.     pYuv->luma_height = m_nHeight;
  311.  
  312.     lumasize = m_nWidth*m_nHeight;
  313.     chromasize = pYuv->chroma_height * pYuv->chroma_width;
  314.     pYuv->y = (unsigned char*)m_pData;
  315.     pYuv->v = (unsigned char*)m_pData + lumasize;
  316.     pYuv->u = (unsigned char*)m_pData + lumasize + chromasize;
  317.     
  318.     switch( m_nFormat )
  319.     {
  320.       case FRAME_YV12A:
  321.       case FRAME_YUV444A:
  322.         pYuv->a = (unsigned char*)m_pData + lumasize + 2*chromasize;
  323.         break;
  324.       default:
  325.         pYuv->a = NULL;
  326.         break;
  327.     }
  328.   }
  329.  
  330.   bool IsValid(){
  331.     return (m_pData!=NULL) && (m_nWidth!=0) && (m_nHeight!=0);
  332.   }
  333.   
  334.   void SetField( CFrame *pFrame, bool bTopField );  
  335.   void SetFrame( CFrame *pFrame );
  336.  
  337. private:
  338.  
  339.   bool Alloc(ui32 nBuffersize);
  340.   void DeAlloc();
  341.  
  342.   ui32 GetRequiredMem();
  343.  
  344.   // Private methods
  345.   // Set the size and pitch Don't expose this to the user.
  346.   void SetSize( ui32 nWidth, ui32 nHeigth )
  347.   {
  348.     m_nWidth = nWidth;
  349.     m_nHeight = nHeigth;
  350.     // Setting Pitch
  351.     switch( m_nFormat )
  352.     {
  353.     case FRAME_RGB32:
  354.       m_nPitch = m_nWidth * m_nDepth/8;
  355.       break;
  356.     case FRAME_YV12:
  357.     case FRAME_YV12A:
  358.       m_nPitch = m_nWidth;
  359.     case FRAME_YUY2:
  360.       m_nPitch = m_nWidth * 2;
  361.       break;
  362.     case FRAME_YUV444A:
  363.     case FRAME_YUV444:
  364.       m_nPitch = m_nWidth;
  365.       break;
  366.     default:
  367.       m_nPitch = m_nWidth;
  368.     };
  369.   }
  370.  
  371.   void SetDepth()
  372.   {
  373.     // Setting Pitch
  374.     switch( m_nFormat )
  375.     {
  376.     case FRAME_RGB32:
  377.       m_nDepth = 32;
  378.       break;
  379.     case FRAME_YV12:
  380.       m_nDepth = 12;
  381.     case FRAME_YUY2:
  382.       m_nDepth = 16;
  383.     default:
  384.       m_nDepth = 0;
  385.     };    
  386.   }
  387.  
  388.   CFrameBuffer *m_pFrameBuffer;
  389.   
  390.   bool   m_bOwnBuffer;
  391.   ui64   m_nPresTime;
  392.   ui32   m_nWidth, m_nHeight;
  393.   ui32   m_nPitch;
  394.   ui32   m_nFormat;
  395.   ui32   m_nDepth;
  396.   ui32   m_nRef;
  397.   ui32   m_nDuration;    // duration of this frame = frame_delay. In 100 ns units
  398.   ui8   *m_pData;
  399.   //ui8   *m_pAlphaData;
  400.   ui32   m_nFrameFlags;
  401.   ui32   m_nAllocatedSize;
  402.  
  403.   ui32   m_nCPUExtensions;
  404.   // clipping vector
  405.   ui8 *m_pClp;
  406.  
  407.   // Frames used for temporary operations
  408.   CFrame  *m_pOverlayTemp;
  409.   CFrame  *m_pUpsample422;
  410.   CFrame  *m_pUpsample444;
  411.  
  412.   BITMAPINFO m_sBitmapInfo;
  413.   CFlCritSec m_csObject;
  414. };
  415.  
  416. class CFrameSource
  417. {
  418. public:
  419.   virtual bool GetFrame(CFrame **ppFrame)=0;
  420. };
  421.  
  422. // This two routines are general purpose, not CFrame specific
  423. // Defined in FrameSource.cpp
  424. void From422to444(unsigned char *src, unsigned char *dst, int width, int height);
  425. void From420to422(unsigned char *src, unsigned char *dst, int width, int height, int frame_type);
  426.  
  427. #endif