home *** CD-ROM | disk | FTP | other *** search
- /*
- * FrameSource.h
- *
- * Copyright (C) Alberto Vigata - July 2000 - ultraflask@yahoo.com
- *
- * This file is part of FlasKMPEG, a free MPEG to MPEG/AVI converter
- *
- * FlasKMPEG 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, or (at your option)
- * any later version.
- *
- * FlasKMPEG 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 GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-
- #ifndef FRAMESOURCE_H
- #define FRAMESOURCE_H
-
-
- #define FRAME_INTERLACED 0x01 // Full frame but interlaced
- #define FRAME_PROGRESSIVE 0x02 // Full progressive frame
- #define FRAME_TOPFIELD 0x04 // Just top field present
- #define FRAME_BOTTOMFIELD 0x08 // Just bottom field present
- #define FRAME_ISLASTFRAME 0x10 // Last frame of the stream
-
-
- #define FRAME_MEM_ALIGN 16
-
- #define MAX_BUF 2048*2048*32
-
- #include <windows.h>
- #include "flasktypes.h"
- #include "thread.h"
- #include "FormatDefs.h"
- #include "cpusupport.h"
- #include <list>
- using namespace std;
-
-
-
- // YUV444 Format definition
- // The buffer points to a struct
- // like this one.
- typedef struct
- {
- unsigned char *y;
- unsigned char *a;
- int luma_width;
- int luma_height;
- unsigned char *u;
- unsigned char *v;
- int chroma_width;
- int chroma_height;
- } TYUVImage;
-
-
-
- class CFrame;
- class CFrameBuffer
- {
- public:
- virtual ~CFrameBuffer(){};
- virtual CFrame *GetFreeFrame() =0;
- virtual void AddFreeFrame(CFrame *pFrame) =0;
- };
-
- class CFrame
- {
- public:
- CFrame( CFrameBuffer *pFrameBuffer = NULL)
- {
- m_pFrameBuffer = pFrameBuffer;
- m_nPresTime = 0;
- m_nWidth = m_nHeight = 0;
- m_nFormat = 0;
- m_nDepth = 0;
- m_nPitch = 0;
- m_nRef = 0;
- m_pData = 0;
- m_nDuration = 0;
- m_nFrameFlags = 0;
- m_nAllocatedSize = 0;
- m_bOwnBuffer = false;
- m_pUpsample444 = NULL;
- m_pUpsample422 = NULL;
- m_pOverlayTemp = NULL;
- m_nCPUExtensions = CPUGetSupportedExtensions();
- memset( &m_sBitmapInfo, 0, sizeof( m_sBitmapInfo ) );
-
- m_pClp = new ui8[1024];
- m_pClp += 384;
-
- for (int i=-384; i<640; i++)
- m_pClp[i] = (i<0) ? 0 : ((i>255) ? 255 : i);
- }
-
- ~CFrame(){
- m_pClp -= 384;
- delete []m_pClp;
-
- DeAlloc();
- };
-
-
- CFrame &operator =(CFrame &oFrame)
- {
- if(!oFrame.IsValid())
- return *this;
- // free my buffer.
- DeAlloc();
-
- m_nDuration = oFrame.GetDuration();
- m_nWidth = oFrame.GetWidth();
- m_nHeight = oFrame.GetHeight();
- m_nPresTime = oFrame.GetPresTime();
- m_nFormat = oFrame.GetFormat();
- m_nDepth = oFrame.GetDepth();
- m_nFrameFlags = oFrame.GetFlags();
- m_nPitch = oFrame.GetPitch();
- m_bOwnBuffer = true;
- Alloc(GetRequiredMem());
- memcpy( m_pData, oFrame.GetBuffer(), oFrame.GetBufferSize() );
- return *this;
- }
- void Release()
- {
- CFlAutoLock lockObject(&m_csObject);
- //ASSERT(m_nRef>0);
- if(m_nRef==0)
- return;
-
- m_nRef--;
- if(m_nRef==0)
- if(m_pFrameBuffer)
- m_pFrameBuffer->AddFreeFrame(this);
- }
- void AddRef()
- {
- CFlAutoLock lockObject(&m_csObject);
- m_nRef++;
- }
- void SetPresTime( ui64 nPresTime ) { m_nPresTime = nPresTime; }
-
- void Set( ui32 nWidth, ui32 nHeight, ui32 nFormat, ui32 nFlags=FRAME_PROGRESSIVE )
- {
- // Don't do anything, if the format matches the current
- if( m_nWidth==nWidth && m_nHeight==nHeight && m_nFormat==nFormat)
- return;
-
-
- m_nFormat = nFormat;
- SetDepth();
- SetSize( nWidth, nHeight );
- m_nFrameFlags = nFlags;
-
- // If already enough memory in buffer, don't reallocate
- if( GetRequiredMem() > m_nAllocatedSize )
- {
- DeAlloc();
- Alloc(GetRequiredMem());
- }
- }
-
- // Overlay pOverlay with offsets nX,nY
- void Overlay( ui32 nX, ui32 nY, CFrame *pOverlay );
-
- // void SetBuffer ( ui8 *pData ){ m_pData = pData; }
- void SetFlags ( ui32 nFlags ){ m_nFrameFlags = nFlags; }
- void SetLastFrame(){ m_nFrameFlags |= FRAME_ISLASTFRAME; }
- void SetDuration( ui32 nDuration ){ m_nDuration = nDuration; }
- ui32 GetDuration(){ return m_nDuration; }
- ui8* GetBuffer(){ return m_pData; }
- ui32 GetWidth(){ return m_nWidth; }
- ui32 GetHeight(){ return m_nHeight; }
- ui64 GetPresTime(){ return m_nPresTime; }
- ui32 GetFormat(){ return m_nFormat; }
- ui32 GetDepth(){ return m_nDepth; }
- ui32 GetFlags(){ return m_nFrameFlags; }
- ui32 GetPitch(){ return m_nPitch; }
-
- bool IsInterlaced(){ return (m_nFrameFlags&FRAME_INTERLACED)>0; }
- bool IsProgressive(){ return (m_nFrameFlags&FRAME_PROGRESSIVE)>0; }
- bool IsField(){ return (m_nFrameFlags&FRAME_TOPFIELD) || (m_nFrameFlags&FRAME_BOTTOMFIELD); }
- bool IsFull(){ return (m_nFrameFlags&FRAME_PROGRESSIVE) || (m_nFrameFlags&FRAME_INTERLACED); }
- bool IsLastFrame() { return (m_nFrameFlags&FRAME_ISLASTFRAME)>0; }
-
- void Erase()
- {
- switch(m_nFormat)
- {
- case FRAME_RGB32:
- case FRAME_YV12:
- case FRAME_YUY2:
- case FRAME_YUV422:
- case FRAME_YUV444:
- case FRAME_YUV444A:
- case FRAME_YV12A:
- memset( m_pData, 0, GetBufferSize() ) ;
- break;
- }
- return;
- }
-
- ui8 *aligned_new(ui32 nSize)
- {
- int nAllocatedOffset;
- ui8 *pAligned, *pData;
-
- if(!nSize)
- return NULL;
- // Increase the allocated
- // memory to be able to align
- nSize += 2*FRAME_MEM_ALIGN;
- // Allocate
- pData = new ui8[nSize];
- if(!pData)
- return NULL;
- nAllocatedOffset = ((ui32)pData)%FRAME_MEM_ALIGN;
- pAligned = pData + nAllocatedOffset + FRAME_MEM_ALIGN;
- // Store original pointer
- *((ui8 **)pAligned - 1) = pData;
-
- return pAligned;
- }
- void aligned_delete(ui8 *pAligned)
- {
- ui8 *pData;
- pData = *((ui8 **)pAligned - 1);
-
- delete []pData;
- }
-
- ui32 GetBufferSize()
- {
- return GetRequiredMem();
- }
- BITMAPINFO *GetBmpInfo()
- {
- m_sBitmapInfo.bmiHeader.biWidth = m_nWidth;
- m_sBitmapInfo.bmiHeader.biHeight = m_nHeight;
- m_sBitmapInfo.bmiHeader.biCompression = m_nFormat==FRAME_RGB32 ? BI_RGB : m_nFormat;
- m_sBitmapInfo.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
- m_sBitmapInfo.bmiHeader.biPlanes = 1;
- m_sBitmapInfo.bmiHeader.biBitCount = (WORD)m_nDepth;
- return &m_sBitmapInfo;
- }
- bool GetFromBmp(HBITMAP hBitmap)
- {
- // Getinfo of the bitmap
- BITMAP sBitmap;
- if(!GetObject( hBitmap, sizeof(BITMAP),&sBitmap ))
- return false;
-
- DeAlloc();
- // Set properties for out bitmap
- // and allocate the space for it
- m_nWidth = sBitmap.bmWidth;
- m_nHeight = sBitmap.bmHeight;
- m_nDepth = 32;
- m_nPitch = m_nWidth * 4;
- m_nFormat = FRAME_RGB32;
- Alloc(GetRequiredMem());
- // Get the bitmap data
- HDC hDCScreen = GetDC( NULL );
-
- if(!GetDIBits( hDCScreen, hBitmap, 0, m_nHeight, m_pData, GetBmpInfo(), DIB_RGB_COLORS))
- return false;
-
- return true;
- }
-
- void GetYuvInfo(TYUVImage *pYuv)
- {
- int lumasize, chromasize;
-
- if(!pYuv || !m_pData)
- return;
-
- switch( m_nFormat )
- {
- case FRAME_YV12:
- case FRAME_YV12A:
- pYuv->chroma_width = m_nWidth/2;
- pYuv->chroma_height = m_nHeight/2;
- break;
- case FRAME_YUV422:
- pYuv->chroma_width = m_nWidth/2;
- pYuv->chroma_height = m_nHeight;
- break;
- case FRAME_YUV444:
- case FRAME_YUV444A:
- pYuv->chroma_width = m_nWidth;
- pYuv->chroma_height = m_nHeight;
- break;
- default:
- memset( pYuv, 0, sizeof TYUVImage );
- return;
- }
-
- pYuv->luma_width = m_nWidth;
- pYuv->luma_height = m_nHeight;
-
- lumasize = m_nWidth*m_nHeight;
- chromasize = pYuv->chroma_height * pYuv->chroma_width;
- pYuv->y = (unsigned char*)m_pData;
- pYuv->v = (unsigned char*)m_pData + lumasize;
- pYuv->u = (unsigned char*)m_pData + lumasize + chromasize;
-
- switch( m_nFormat )
- {
- case FRAME_YV12A:
- case FRAME_YUV444A:
- pYuv->a = (unsigned char*)m_pData + lumasize + 2*chromasize;
- break;
- default:
- pYuv->a = NULL;
- break;
- }
- }
-
- bool IsValid(){
- return (m_pData!=NULL) && (m_nWidth!=0) && (m_nHeight!=0);
- }
-
- void SetField( CFrame *pFrame, bool bTopField );
- void SetFrame( CFrame *pFrame );
-
- private:
-
- bool Alloc(ui32 nBuffersize);
- void DeAlloc();
-
- ui32 GetRequiredMem();
-
- // Private methods
- // Set the size and pitch Don't expose this to the user.
- void SetSize( ui32 nWidth, ui32 nHeigth )
- {
- m_nWidth = nWidth;
- m_nHeight = nHeigth;
- // Setting Pitch
- switch( m_nFormat )
- {
- case FRAME_RGB32:
- m_nPitch = m_nWidth * m_nDepth/8;
- break;
- case FRAME_YV12:
- case FRAME_YV12A:
- m_nPitch = m_nWidth;
- case FRAME_YUY2:
- m_nPitch = m_nWidth * 2;
- break;
- case FRAME_YUV444A:
- case FRAME_YUV444:
- m_nPitch = m_nWidth;
- break;
- default:
- m_nPitch = m_nWidth;
- };
- }
-
- void SetDepth()
- {
- // Setting Pitch
- switch( m_nFormat )
- {
- case FRAME_RGB32:
- m_nDepth = 32;
- break;
- case FRAME_YV12:
- m_nDepth = 12;
- case FRAME_YUY2:
- m_nDepth = 16;
- default:
- m_nDepth = 0;
- };
- }
-
- CFrameBuffer *m_pFrameBuffer;
-
- bool m_bOwnBuffer;
- ui64 m_nPresTime;
- ui32 m_nWidth, m_nHeight;
- ui32 m_nPitch;
- ui32 m_nFormat;
- ui32 m_nDepth;
- ui32 m_nRef;
- ui32 m_nDuration; // duration of this frame = frame_delay. In 100 ns units
- ui8 *m_pData;
- //ui8 *m_pAlphaData;
- ui32 m_nFrameFlags;
- ui32 m_nAllocatedSize;
-
- ui32 m_nCPUExtensions;
- // clipping vector
- ui8 *m_pClp;
-
- // Frames used for temporary operations
- CFrame *m_pOverlayTemp;
- CFrame *m_pUpsample422;
- CFrame *m_pUpsample444;
-
- BITMAPINFO m_sBitmapInfo;
- CFlCritSec m_csObject;
- };
-
- class CFrameSource
- {
- public:
- virtual bool GetFrame(CFrame **ppFrame)=0;
- };
-
- // This two routines are general purpose, not CFrame specific
- // Defined in FrameSource.cpp
- void From422to444(unsigned char *src, unsigned char *dst, int width, int height);
- void From420to422(unsigned char *src, unsigned char *dst, int width, int height, int frame_type);
-
- #endif