avi_PushSourceBitmapSet.cpp

Go to the documentation of this file.
00001 //------------------------------------------------------------------------------
00002 // File: PushSourceBitmapSet.cpp
00003 //------------------------------------------------------------------------------
00004 #pragma warning( disable : 4311 4312 4133)
00005 
00006 #include <streams.h>
00007 #include <stdio.h>
00008 
00009 #include "avi_PushSource.h"
00010 #include "avi_PushGuids.h"
00011 
00012 
00013 extern "C" BYTE *GetNextBitmapFromTemporaryFile(long frame);
00014 
00015 extern int gFirstF;
00016 extern int gLastF;  
00017 extern int gCurrentF;  
00018 
00019 extern void Msg(TCHAR *szFormat, ...);
00020 
00021 const AMOVIESETUP_MEDIATYPE sudOpPinTypes =
00022 {
00023     &MEDIATYPE_Video,       // Major type
00024     &MEDIASUBTYPE_NULL      // Minor type
00025 };
00026 
00027 CPushPinBitmapSet::CPushPinBitmapSet(int nFrames, HRESULT *phr, CSource *pFilter)
00028       : CSourceStream(NAME("Push Source BitmapSet"), phr, pFilter, L"Out"),
00029         m_bZeroMemory(0),
00030         m_iFrameNumber(0),
00031         m_rtFrameLength(FPS_25), 
00032         m_bFilesLoaded(FALSE)
00033 {
00034    // Load the first bitmap this will be used to set the parameters
00035    m_FirstF=gFirstF;
00036    m_LastF=gLastF;  
00037    //char ttt[256]; sprintf(ttt,"First frame %ld Last Frame %ld",m_FirstF,m_LastF);
00038    //MessageBox(NULL,ttt,"New reading Object",MB_OK);
00039    ZeroMemory(&m_cbBitmapInfo, sizeof(DWORD));
00040    ZeroMemory(&m_pBmi,    sizeof(BITMAPINFO *));
00041    ZeroMemory(&m_pFile,   sizeof(BYTE *));
00042    ZeroMemory(&m_pImage,  sizeof(BYTE *));
00043 
00044    m_pFile=GetNextBitmapFromTemporaryFile(m_FirstF+m_iFrameNumber);  // should return BITMAP
00045    m_cbBitmapInfo = (long)sizeof(BITMAPINFOHEADER);
00046    m_pBmi = (BITMAPINFO*)(m_pFile);
00047    m_pImage = m_pFile + m_cbBitmapInfo;
00048    m_bFilesLoaded=TRUE;
00049 }
00050 
00051 CPushPinBitmapSet::~CPushPinBitmapSet(){   
00052 //MessageBox(NULL,"Push source PIN deleted",NULL,MB_OK);
00053 }
00054 
00055 void CPushPinBitmapSet::LoadNextBitmap(void){
00056    m_bFilesLoaded=FALSE;
00057    m_pFile=GetNextBitmapFromTemporaryFile(m_FirstF+m_iFrameNumber); 
00058    m_cbBitmapInfo = (long)sizeof(BITMAPINFOHEADER);
00059    m_pBmi = (BITMAPINFO*)(m_pFile);
00060    m_pImage = m_pFile + m_cbBitmapInfo;
00061    m_bFilesLoaded=TRUE;
00062    //Msg("Loaded %s",FileList[m_iFrameNumber]);
00063 }
00064 
00065 
00066 HRESULT CPushPinBitmapSet::GetMediaType(CMediaType *pMediaType){
00067     //MessageBox(NULL,"GetMediaType1",NULL,MB_OK);
00068     CAutoLock cAutoLock(m_pFilter->pStateLock());
00069     CheckPointer(pMediaType, E_POINTER);
00070     // If the bitmap files were not loaded, just fail here.
00071     if (!m_bFilesLoaded)return E_FAIL;
00072     // Allocate enough room for the VIDEOINFOHEADER and the color tables
00073     VIDEOINFOHEADER *pvi = 
00074         (VIDEOINFOHEADER*)pMediaType->AllocFormatBuffer(SIZE_PREHEADER + 
00075                                                         m_cbBitmapInfo);
00076     if (pvi == 0) 
00077         return(E_OUTOFMEMORY);
00078     // Initialize the video info header
00079     ZeroMemory(pvi, pMediaType->cbFormat);   
00080     pvi->AvgTimePerFrame = m_rtFrameLength;
00081     // Copy the header info from the current bitmap
00082     memcpy(&(pvi->bmiHeader), m_pBmi, m_cbBitmapInfo);
00083     // Set image size for use in FillBuffer
00084     pvi->bmiHeader.biSizeImage  = GetBitmapSize(&pvi->bmiHeader);
00085     // Clear source and target rectangles
00086     SetRectEmpty(&(pvi->rcSource)); // we want the whole image area rendered
00087     SetRectEmpty(&(pvi->rcTarget)); // no particular destination rectangle
00088     pMediaType->SetType(&MEDIATYPE_Video);
00089     pMediaType->SetFormatType(&FORMAT_VideoInfo);
00090     pMediaType->SetTemporalCompression(FALSE);
00091     // Work out the GUID for the subtype from the header info.
00092     const GUID SubTypeGUID = GetBitmapSubtype(&pvi->bmiHeader);
00093     pMediaType->SetSubtype(&SubTypeGUID);
00094     pMediaType->SetSampleSize(pvi->bmiHeader.biSizeImage);
00095     return S_OK;
00096 }
00097 
00098 
00099 HRESULT CPushPinBitmapSet::DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pRequest){
00100     HRESULT hr;
00101     CAutoLock cAutoLock(m_pFilter->pStateLock());
00102     // If the bitmap files were not loaded, just fail here.
00103     if (!m_bFilesLoaded) return E_FAIL;
00104     CheckPointer(pAlloc, E_POINTER);
00105     CheckPointer(pRequest, E_POINTER);
00106     VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER*) m_mt.Format();
00107     // Ensure a minimum number of buffers
00108     if (pRequest->cBuffers == 0)    {
00109         pRequest->cBuffers = 2;
00110     }
00111     pRequest->cbBuffer = pvi->bmiHeader.biSizeImage;
00112     ALLOCATOR_PROPERTIES Actual;
00113     hr = pAlloc->SetProperties(pRequest, &Actual);
00114     if (FAILED(hr)) { return hr;   }
00115     // Is this allocator unsuitable?
00116     if (Actual.cbBuffer < pRequest->cbBuffer) { return E_FAIL;    }
00117     return S_OK;
00118 }
00119 
00120 // This is where we insert the DIB bits into the video stream.
00121 // FillBuffer is called once for every sample in the stream.
00122 HRESULT CPushPinBitmapSet::FillBuffer(IMediaSample *pSample){
00123     BYTE *pData;
00124     long cbData;
00125     if(m_iFrameNumber + m_FirstF >= m_LastF)return E_FAIL;  // this terminates the writing
00126     if(m_iFrameNumber > 0){ // Now we need to load the bitmap
00127       LoadNextBitmap();
00128       gCurrentF=m_iFrameNumber+m_FirstF;
00129     }
00130     if(!m_bFilesLoaded)return E_FAIL;
00131     CheckPointer(pSample, E_POINTER);
00132     CAutoLock cAutoLockShared(&m_cSharedState);
00133     // Access the sample's data buffer
00134     pSample->GetPointer(&pData);
00135     cbData = pSample->GetSize();
00136     // Check that we're still using video
00137     ASSERT(m_mt.formattype == FORMAT_VideoInfo);
00138     VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER*)m_mt.pbFormat;
00139     // Copy the DIB bits over into our filter's output buffer.
00140     // Since sample size may be larger than the image size, bound the copy size.
00141     // Remember that the new data has the same format that we specified in GetMediaType.
00142     memcpy(pData, m_pImage, min(pVih->bmiHeader.biSizeImage, (DWORD) cbData));
00143     // Set the timestamps that will govern playback frame rate.
00144     // If this file is getting written out as an AVI,
00145     // then you'll also need to configure the AVI Mux filter to 
00146     // set the Average Time Per Frame for the AVI Header.
00147     // The current time is the sample's start
00148     REFERENCE_TIME rtStart = m_iFrameNumber * m_rtFrameLength;
00149     REFERENCE_TIME rtStop  = rtStart + m_rtFrameLength;
00150     pSample->SetTime(&rtStart, &rtStop);
00151     m_iFrameNumber++;
00152     // Set TRUE on every sample for uncompressed frames
00153     pSample->SetSyncPoint(TRUE);
00154     // Increment the current buffer so that the next FillBuffer() call 
00155     // will use the bits from the next bitmap in the set.
00156     return S_OK;
00157 }
00158 
00159 // Filter's class
00160 CPushSourceBitmapSet::CPushSourceBitmapSet(int Nframes, IUnknown *pUnk, HRESULT *phr)
00161            : CSource(NAME("PushSourceBitmapSet"), pUnk, 
00162            __uuidof(CLSID_PushSourceBitmapSet)){
00163     m_pPin = new CPushPinBitmapSet(Nframes, phr, this);
00164     if (phr)    {
00165         if (m_pPin == NULL)
00166             *phr = E_OUTOFMEMORY;
00167         else
00168             *phr = S_OK;
00169     }  
00170 }
00171 
00172 CPushSourceBitmapSet::~CPushSourceBitmapSet(){
00173 //MessageBox(NULL,"Push source to be deleted",NULL,MB_OK);
00174     delete m_pPin;
00175 //MessageBox(NULL,"Push source deleted",NULL,MB_OK);
00176 }

Generated on Sun Apr 27 14:20:13 2014 for OpenFX by  doxygen 1.5.6