HRESULT CMediaController::CreateInstance(CMediaController **ppMediaController) { HRESULT hr = S_OK; //Instantiate the class CMediaController *pMediaController = new CMediaController(&hr); if (!pMediaController) { LOG_MSG_IF_FAILED(L"CMediaController creation failed.\n", E_OUTOFMEMORY); return E_OUTOFMEMORY; } //Return the pointer to the caller if (SUCCEEDED (hr)) { *ppMediaController = pMediaController; (*ppMediaController)->AddRef(); TRACE((L"CMediaController created.\n")); } LOG_MSG_IF_FAILED(L"CMediaController creation failed.\n", E_FAIL); SAFE_RELEASE (pMediaController); return hr; }
HRESULT D3DPresentEngine::PresentSwapChain(IDirect3DSwapChain9* pSwapChain, IDirect3DSurface9* pSurface) { HRESULT hr = S_OK; //pSwapChain->GetFrontBufferData(d3d_shared_surface); IDirect3DSurface9 *surface; pSwapChain->GetBackBuffer(0,D3DBACKBUFFER_TYPE_MONO,&surface); if (m_pDevice->StretchRect(surface,NULL,d3d_shared_surface,NULL,D3DTEXF_NONE) != D3D_OK) { printf("ofxWMFVideoPlayer: Error while copying texture to gl context \n"); } SAFE_RELEASE(surface); if (m_hwnd == NULL) { return MF_E_INVALIDREQUEST; } hr = pSwapChain->Present(NULL, &m_rcDestRect, m_hwnd, NULL, 0); LOG_MSG_IF_FAILED(L"D3DPresentEngine::PresentSwapChain, IDirect3DSwapChain9::Present failed.", hr); return hr; }
HRESULT CASFManager::CreateInstance(CASFManager **ppASFManager) { // Note: CASFManager constructor sets the ref count to zero. // Create method calls AddRef. HRESULT hr = S_OK; CASFManager *pASFManager = new (std::nothrow) CASFManager(&hr); if (!pASFManager) { return E_OUTOFMEMORY; } if (SUCCEEDED(hr)) { *ppASFManager = pASFManager; (*ppASFManager)->AddRef(); TRACE((L"CASFManager created.\n")); } LOG_MSG_IF_FAILED(L"CASFManager creation failed.\n", hr); SAFE_RELEASE (pASFManager); return hr; }
HRESULT CASFManager::SelectStream (WORD wStreamNumber, GUID* pguidCurrentMediaType) { HRESULT hr = S_OK; if (wStreamNumber == 0 || !pguidCurrentMediaType) { return E_INVALIDARG; } if (! m_pSplitter || ! m_pContentInfo) { return MF_E_NOT_INITIALIZED; } //Select the stream you want to parse. This sample allows you to select only one stream at a time CHECK_HR(hr = m_pSplitter->SelectStreams(&wStreamNumber, 1)); //Load the appropriate stream decoder CHECK_HR(hr = SetupStreamDecoder(wStreamNumber, pguidCurrentMediaType)); m_CurrentStreamID = wStreamNumber; m_guidCurrentMediaType = *pguidCurrentMediaType; TRACE((L"Stream selected.\n")); done: LOG_MSG_IF_FAILED(L"CASFManager::SelectStreams failed.\n", hr); return hr; }
HRESULT CASFManager::GetSeekPosition (MFTIME* hnsSeekTime, QWORD *pcbDataOffset, MFTIME* phnsApproxSeekTime) { HRESULT hr = S_OK; //if the media type is audio, or doesn't have an indexed data //calculate the offset manually if (( m_guidCurrentMediaType == MFMediaType_Audio) || (!m_pIndexer)) { CHECK_HR(hr = GetSeekPositionManually(*hnsSeekTime, pcbDataOffset)); } //if the type is video, get the position with the indexer if (( m_guidCurrentMediaType == MFMediaType_Video)) { CHECK_HR(hr = GetSeekPositionWithIndexer(*hnsSeekTime, pcbDataOffset, phnsApproxSeekTime)); } TRACE((L"Offset calculated.\n")); done: LOG_MSG_IF_FAILED(L"CASFManager::GetSeekPosition failed.\n", hr); return hr; }
HRESULT D3DPresentEngine::PresentSwapChain(IDirect3DSwapChain9* pSwapChain, IDirect3DSurface9* pSurface) { //----------------------------------------------------------------------------- // Copy latest D3D frame to our OpenGL/D3D shared surface... //pSwapChain->GetFrontBufferData(d3d_shared_surface); IDirect3DSurface9 *surface; pSwapChain->GetBackBuffer(0,D3DBACKBUFFER_TYPE_MONO,&surface); if (m_pDevice->StretchRect(surface,NULL,d3d_shared_surface,NULL,D3DTEXF_NONE) != D3D_OK) { CI_LOG_E("Error while copying texture to gl context"); //printf("ciWMFVideoplayer: Error while copying texture to gl context \n"); } SAFE_RELEASE(surface); //----------------------------------------------------------------------------- // Original code from the WMF EVRpresenter sample code... HRESULT hr = S_OK; if (m_hwnd == NULL) { return MF_E_INVALIDREQUEST; } hr = pSwapChain->Present(NULL, &m_rcDestRect, m_hwnd, NULL, 0); LOG_MSG_IF_FAILED(L"D3DPresentEngine::PresentSwapChain, IDirect3DSwapChain9::Present failed.", hr); return hr; }
HRESULT WebHelper::Init(DispatchCallback *pCallback) { m_pDispatchCB = pCallback; IConnectionPointContainer *pCPContainer = NULL; HWND hwndBrowser = NULL; // Create the InternetExplorer object. HRESULT hr = CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_ALL, IID_IWebBrowser2, (void**)&m_pBrowser); LOG_MSG_IF_FAILED(L"CoCreateInstance(CLSID_InternetExplorer)", hr); // Set up the connection point so that we receive events. if (SUCCEEDED(hr)) { hr = m_pBrowser->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPContainer); LOG_MSG_IF_FAILED(L"QueryInterface for IConnectionPointContainer)", hr); } if (SUCCEEDED(hr)) { hr = pCPContainer->FindConnectionPoint(DIID_DWebBrowserEvents2, &m_pCP); LOG_MSG_IF_FAILED(L"FindConnectionPoint)", hr); } if (SUCCEEDED(hr)) { hr = m_pCP->Advise(this, &m_dwCookie); LOG_MSG_IF_FAILED(L"Advise)", hr); } if (SUCCEEDED(hr)) { hr = m_pBrowser->get_HWND((SHANDLE_PTR*)&hwndBrowser); } // Move the browser window to the front. if (SUCCEEDED(hr)) { SetWindowPos(hwndBrowser, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); } SAFE_RELEASE(pCPContainer); return hr; }
HRESULT CASFManager::CreateASFSplitter (IMFByteStream *pContentByteStream, IMFASFSplitter **ppSplitter) { if (!pContentByteStream || !ppSplitter) { return E_INVALIDARG; } if (!m_pContentInfo) { return MF_E_NOT_INITIALIZED; } HRESULT hr = S_OK; IMFASFSplitter *pSplitter = NULL; IMFPresentationDescriptor* pPD = NULL; UINT64 cbDataOffset = 0, cbDataLength = 0; CHECK_HR(hr = MFCreateASFSplitter(&pSplitter)); CHECK_HR(hr = pSplitter->Initialize(m_pContentInfo)); //Generate the presentation descriptor CHECK_HR(hr = m_pContentInfo->GeneratePresentationDescriptor(&pPD)); //Get the offset to the start of the Data Object CHECK_HR(hr = pPD->GetUINT64(MF_PD_ASF_DATA_START_OFFSET, &cbDataOffset)); //Get the length of the Data Object CHECK_HR(hr = pPD->GetUINT64(MF_PD_ASF_DATA_LENGTH, &cbDataLength)); m_pByteStream = pContentByteStream; m_pByteStream->AddRef(); m_cbDataOffset = cbDataOffset; m_cbDataLength = cbDataLength; // Return the pointer to the caller. *ppSplitter = pSplitter; (*ppSplitter)->AddRef(); TRACE((L"Created Splitter object.\n")); done: LOG_MSG_IF_FAILED(L"CASFManager::CreateASFSplitter failed.\n", hr); SAFE_RELEASE(pSplitter); SAFE_RELEASE(pPD); return hr; }
HRESULT CASFManager::ReadDataIntoBuffer( IMFByteStream *pStream, // Pointer to the byte stream. DWORD cbOffset, // Offset at which to start reading DWORD cbToRead, // Number of bytes to read IMFMediaBuffer **ppBuffer // Receives a pointer to the buffer. ) { HRESULT hr = S_OK; BYTE *pData = NULL; DWORD cbRead = 0; // Actual amount of data read IMFMediaBuffer *pBuffer = NULL; // Create the media buffer. This function allocates the memory. CHECK_HR(hr = MFCreateMemoryBuffer(cbToRead, &pBuffer)); // Access the buffer. CHECK_HR(hr = pBuffer->Lock(&pData, NULL, NULL)); //Set the offset CHECK_HR(hr = pStream->SetCurrentPosition(cbOffset)); // Read the data from the byte stream. CHECK_HR(hr = pStream->Read(pData, cbToRead, &cbRead)); CHECK_HR(hr = pBuffer->Unlock()); pData = NULL; // Update the size of the valid data. CHECK_HR(hr = pBuffer->SetCurrentLength(cbRead)); // Return the pointer to the caller. *ppBuffer = pBuffer; (*ppBuffer)->AddRef(); TRACE((L"Read data from the ASF file into a media buffer.\n")); done: LOG_MSG_IF_FAILED(L"CASFManager::ReadDataIntoBuffer failed.\n", hr); if (pData) { pBuffer->Unlock(); } SAFE_RELEASE(pBuffer); return hr; }
HRESULT CASFManager::CreateASFContentInfo (IMFByteStream *pContentByteStream, IMFASFContentInfo **ppContentInfo) { if (!pContentByteStream || !ppContentInfo) { return E_INVALIDARG; } HRESULT hr = S_OK; QWORD cbHeader = 0; IMFASFContentInfo *pContentInfo = NULL; IMFMediaBuffer *pBuffer = NULL; // Create the ASF content information object. CHECK_HR(hr = MFCreateASFContentInfo(&pContentInfo)); // Read the first 30 bytes to find the total header size. CHECK_HR(hr = ReadDataIntoBuffer( pContentByteStream, 0, MIN_ASF_HEADER_SIZE, &pBuffer)); CHECK_HR(hr = pContentInfo->GetHeaderSize(pBuffer, &cbHeader)); SAFE_RELEASE(pBuffer); //Read the header into a buffer CHECK_HR(hr = ReadDataIntoBuffer( pContentByteStream, 0, (DWORD)cbHeader, &pBuffer)); // Pass the buffer for the header object. CHECK_HR(hr = pContentInfo->ParseHeader(pBuffer, 0)); // Return the pointer to the caller. *ppContentInfo = pContentInfo; (*ppContentInfo)->AddRef(); TRACE((L"Created ContentInfo object.\n")); done: LOG_MSG_IF_FAILED(L"CASFManager::CreateASFContentInfo failed.\n", hr); SAFE_RELEASE(pBuffer); SAFE_RELEASE(pContentInfo); return hr; }
HRESULT D3DPresentEngine::PresentSwapChain(IDirect3DSwapChain9* pSwapChain, IDirect3DSurface9* pSurface) { HRESULT hr = S_OK; if (m_hwnd == NULL) { return MF_E_INVALIDREQUEST; } hr = pSwapChain->Present(NULL, &m_rcDestRect, m_hwnd, NULL, 0); LOG_MSG_IF_FAILED(L"D3DPresentEngine::PresentSwapChain, IDirect3DSwapChain9::Present failed.", hr); return hr; }
HRESULT CASFManager::GetSeekPositionManually(MFTIME hnsSeekTime, QWORD *cbDataOffset) { //Get average packet size UINT32 averagepacketsize = ( m_fileinfo->cbMaxPacketSize+ m_fileinfo->cbMinPacketSize)/2; DWORD dwFlags = 0; double fraction = 0; HRESULT hr = S_OK; //Check if the reverse flag is set, if so, offset is calculated from the end of the presentation CHECK_HR(hr = this->m_pSplitter->GetFlags(&dwFlags)); if (dwFlags & MFASF_SPLITTER_REVERSE) { fraction = ((double) (m_fileinfo->cbPresentationDuration) - (double) (hnsSeekTime))/(double) (m_fileinfo->cbPresentationDuration); } else { fraction = (double)(hnsSeekTime)/(double) (m_fileinfo->cbPresentationDuration); } //calculate the number of packets passed int seeked_packets = (int)( m_fileinfo->cbPackets * fraction); //get the offset *cbDataOffset = (QWORD)averagepacketsize * seeked_packets; if (*cbDataOffset >= 0) { return S_OK; } TRACE((L"Offset calculated through fraction.\n")); done: LOG_MSG_IF_FAILED(L"CASFManager::GetSeekPositionManually failed.\n", hr); return hr; }
HRESULT Scheduler::ScheduleSample(IMFSample *pSample, BOOL bPresentNow) { if (m_pCB == NULL) { return MF_E_NOT_INITIALIZED; } if (m_hSchedulerThread == NULL) { return MF_E_NOT_INITIALIZED; } HRESULT hr = S_OK; DWORD dwExitCode = 0; GetExitCodeThread(m_hSchedulerThread, &dwExitCode); if (dwExitCode != STILL_ACTIVE) { return E_FAIL; } if (bPresentNow || (m_pClock == NULL)) { // Present the sample immediately. m_pCB->PresentSample(pSample, 0); } else { // Queue the sample and ask the scheduler thread to wake up. hr = m_ScheduledSamples.Queue(pSample); if (SUCCEEDED(hr)) { PostThreadMessage(m_dwThreadID, eSchedule, 0, 0); } } LOG_MSG_IF_FAILED(L"Scheduler::ScheduleSample failed", hr); return hr; }
HRESULT CMediaController::CreateBitmapForKeyFrame(BYTE* pPixelData, IMFMediaType* pMediaType) { if(!pPixelData || !pMediaType) { return E_INVALIDARG; } HRESULT hr = S_OK; INT32 stride = 0; //Get the Frame size and stride through Media Type attributes CHECK_HR (hr = MFGetAttributeSize(pMediaType, MF_MT_FRAME_SIZE, &m_Width, &m_Height)); CHECK_HR (pMediaType->GetUINT32(MF_MT_DEFAULT_STRIDE, (UINT32*)&stride)); SAFE_DELETE(m_pBitmap); //Create the bitmap with the given size m_pBitmap = new Bitmap(m_Width, m_Height, (INT32)stride, PixelFormat32bppRGB, pPixelData); if(!m_pBitmap) { hr = E_OUTOFMEMORY; goto done; } else { //Bitmap was created, set the flag m_fHasTestMedia = TRUE; TRACE((L"Bitmap for the key frame created.\n")); } done: LOG_MSG_IF_FAILED(L"Bitmap could not be created.\n", hr); return hr; }
HRESULT CASFManager::OpenASFFile(const WCHAR *sFileName) { HRESULT hr = S_OK; IMFByteStream* pStream = NULL; // Open a byte stream for the file. CHECK_HR(hr = MFCreateFile( MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, sFileName, &pStream )); TRACE((L"Opened ASF File\n")); //Reset the ASF components. Reset(); // Create the Media Foundation ASF objects. CHECK_HR(hr = CreateASFContentInfo(pStream, &m_pContentInfo)); CHECK_HR(hr = CreateASFSplitter(pStream, &m_pSplitter)); CHECK_HR(hr = CreateASFIndexer(pStream, &m_pIndexer)); done: LOG_MSG_IF_FAILED(L"CASFManager::OpenASFFile failed.\n", hr); SAFE_RELEASE(pStream); return hr; }
//----------------------------------------------------------------------------- // PresentSwapChain // // Presents a swap chain that contains a video frame by doing a callback // via the sink. // // pSwapChain: Pointer to the swap chain. // pSurface: Pointer to the swap chain's back buffer surface. //----------------------------------------------------------------------------- HRESULT D3DPresentEngine::PresentSwapChain(IDirect3DSwapChain9* pSwapChain, IDirect3DSurface9* pSurface) { HRESULT hr = S_OK; if (m_hwnd == NULL) { return MF_E_INVALIDREQUEST; } if(!m_pRenderSurface) { D3DSURFACE_DESC desc; // Get the surface description pSurface->GetDesc(&desc); // Create a surface the same size as our sample hr = this->m_pDevice->CreateRenderTarget(desc.Width, desc.Height, desc.Format, desc.MultiSampleType, desc.MultiSampleQuality, true, &m_pRenderSurface, NULL); if(hr != S_OK) goto bottom; } if(m_pRenderSurface) { D3DSURFACE_DESC originalDesc; // Get the surface description of this sample pSurface->GetDesc(&originalDesc); D3DSURFACE_DESC renderDesc; // Get the surface description of the render surface m_pRenderSurface->GetDesc(&renderDesc); // Compare the descriptions to make sure they match if(originalDesc.Width != renderDesc.Width || originalDesc.Height != renderDesc.Height || originalDesc.Format != renderDesc.Format) { // Release the old render surface SAFE_RELEASE(m_pRenderSurface); // Create a new render surface that matches the size of this surface hr = this->m_pDevice->CreateRenderTarget(originalDesc.Width, originalDesc.Height, originalDesc.Format, originalDesc.MultiSampleType, originalDesc.MultiSampleQuality, true, &m_pRenderSurface, NULL); if(hr != S_OK) goto bottom; } } if(m_pRenderSurface) { // Copy the passed surface to our rendered surface hr = D3DXLoadSurfaceFromSurface(m_pRenderSurface, NULL, NULL, pSurface, NULL, NULL, D3DX_FILTER_NONE, 0); } if(hr != S_OK) goto bottom; // Do the callback, passing the rendered surface if(m_pCallback) hr = m_pCallback->PresentSurfaceCB(m_pRenderSurface); LOG_MSG_IF_FAILED(L"D3DPresentEngine::PresentSwapChain failed.", hr); bottom: return hr; }
HRESULT CASFManager::GenerateSamples( MFTIME hnsSeekTime, DWORD dwFlags, SAMPLE_INFO* pSampleInfo, void (*FuncPtrToDisplaySampleInfo)(SAMPLE_INFO*) ) { if (! m_pSplitter) { return MF_E_NOT_INITIALIZED; } HRESULT hr = S_OK; QWORD cbStartOffset = 0; DWORD cbReadLen = 0; MFTIME hnsApproxTime =0; MFTIME hnsTestSampleDuration =0; BOOL bReverse = FALSE; // Flush the splitter to remove any samples that were delivered // to the ASF splitter during a previous call to this method. CHECK_HR(hr = m_pSplitter->Flush()); //set the reverse flag if applicable hr = m_pSplitter->SetFlags(dwFlags); if (FAILED (hr)) { dwFlags = 0; hr = S_OK; } bReverse = ((dwFlags & MFASF_SPLITTER_REVERSE) == MFASF_SPLITTER_REVERSE); // Get the offset from the start of the ASF Data Object to the desired seek time. CHECK_HR(hr = GetSeekPosition(&hnsSeekTime, &cbStartOffset, &hnsApproxTime)); // Get the audio playback duration. (The duration is TEST_AUDIO_DURATION or up to // the end of the file, whichever is shorter.) if (m_guidCurrentMediaType == MFMediaType_Audio) { GetTestDuration(hnsSeekTime, bReverse, &hnsTestSampleDuration); } // Notify the MFT we are about to start. if (m_pDecoder) { if ( m_pDecoder->GetDecoderStatus() != STREAMING) { hr = m_pDecoder->StartDecoding(); } if (FAILED(hr)) { SAFE_RELEASE(m_pDecoder); } } cbReadLen = (DWORD)(m_cbDataLength - cbStartOffset); if (bReverse) { // Reverse playback: Read from the offset back to zero. CHECK_HR(hr = GenerateSamplesLoop( hnsSeekTime, hnsTestSampleDuration, bReverse, (DWORD)(m_cbDataLength + m_cbDataOffset - cbStartOffset), //DWORD cbDataOffset cbReadLen, //DWORD cbDataLen pSampleInfo, FuncPtrToDisplaySampleInfo )); } else { // Forward playback: Read from the offset to the end. CHECK_HR(hr = GenerateSamplesLoop( hnsSeekTime, hnsTestSampleDuration, bReverse, (DWORD)(m_cbDataOffset + cbStartOffset), //DWORD cbDataOffset, cbReadLen, //DWORD cbDataLen pSampleInfo, FuncPtrToDisplaySampleInfo )); } // Note: cbStartOffset is relative to the start of the data object. // GenerateSamplesLoop expects the offset relative to the start of the file. done: LOG_MSG_IF_FAILED(L"CASFManager::GenerateSamples failed.\n", hr); return hr; }
HRESULT CASFManager::GetSeekPositionWithIndexer ( MFTIME hnsSeekTime, QWORD *cbDataOffset, MFTIME* hnsApproxSeekTime) { if (! m_pIndexer) { return MF_E_ASF_NOINDEX; } HRESULT hr = S_OK; PROPVARIANT var; PropVariantInit(&var); var.vt = VT_I8; var.hVal.QuadPart = hnsSeekTime; ASF_INDEX_IDENTIFIER IndexIdentifier; BOOL fIsIndexed = FALSE; DWORD cbIndexDescriptor = 0; DWORD dwFlags = 0; //currently only time index is supported, set to GUID_NULL IndexIdentifier.guidIndexType = GUID_NULL; IndexIdentifier.wStreamNumber = m_CurrentStreamID; //Is the stream indexed? Get the value of cbIndexDescriptor hr = m_pIndexer->GetIndexStatus( &IndexIdentifier, &fIsIndexed, NULL, &cbIndexDescriptor ); if (hr == MF_E_BUFFERTOOSMALL) { hr = S_OK; } CHECK_HR(hr); //check if the reverse flag needs to be set on the indexer CHECK_HR (hr = m_pSplitter->GetFlags(&dwFlags)); if (dwFlags & MFASF_SPLITTER_REVERSE) { CHECK_HR (hr = m_pIndexer->SetFlags(MFASF_INDEXER_READ_FOR_REVERSEPLAYBACK)); } //Get the offset from the indexer if (fIsIndexed) { CHECK_HR(hr = m_pIndexer->GetSeekPositionForValue( &var, &IndexIdentifier, cbDataOffset, hnsApproxSeekTime, 0 )); } else { hr = MF_E_ASF_NOINDEX; } TRACE((L"Offset calculated through the Indexer.\n")); done: LOG_MSG_IF_FAILED(L"CASFManager::GetSeekPositionWithIndexer failed.\n", hr); //release memory PropVariantClear(&var); return hr; }
HRESULT CASFManager::SetupStreamDecoder (WORD wStreamNumber, GUID* pguidCurrentMediaType) { if (! m_pContentInfo) { return MF_E_NOT_INITIALIZED; } if (wStreamNumber == 0) { return E_INVALIDARG; } IMFASFProfile* pProfile = NULL; IMFMediaType* pMediaType = NULL; IMFASFStreamConfig *pStream = NULL; GUID guidMajorType = GUID_NULL; GUID guidSubType = GUID_NULL; GUID guidDecoderCategory = GUID_NULL; BOOL fIsCompressed = TRUE; CLSID *pDecoderCLSIDs = NULL; // Pointer to an array of CLISDs. UINT32 cDecoderCLSIDs = 0; // Size of the array. HRESULT hr = S_OK; //Get the profile object that stores stream information CHECK_HR(hr = m_pContentInfo->GetProfile(&pProfile)); //Get stream configuration object from the profile CHECK_HR(hr = pProfile->GetStreamByNumber(wStreamNumber, &pStream)); //Get the media type CHECK_HR(hr = pStream->GetMediaType(&pMediaType)); //Get the major media type CHECK_HR(hr = pMediaType->GetMajorType(&guidMajorType)); //Get the sub media type CHECK_HR(hr = pMediaType->GetGUID(MF_MT_SUBTYPE, &guidSubType)); //find out if the media type is compressed CHECK_HR(hr = pMediaType->IsCompressedFormat(&fIsCompressed)); if (fIsCompressed) { //get decoder category if (guidMajorType == MFMediaType_Video) { guidDecoderCategory = MFT_CATEGORY_VIDEO_DECODER; } else if (guidMajorType == MFMediaType_Audio) { guidDecoderCategory = MFT_CATEGORY_AUDIO_DECODER; } else { CHECK_HR(hr = MF_E_INVALIDMEDIATYPE); } // Look for a decoder. MFT_REGISTER_TYPE_INFO tinfo; tinfo.guidMajorType = guidMajorType; tinfo.guidSubtype = guidSubType; CHECK_HR(hr = MFTEnum( guidDecoderCategory, 0, // Reserved &tinfo, // Input type to match. (Encoded type.) NULL, // Output type to match. (Don't care.) NULL, // Attributes to match. (None.) &pDecoderCLSIDs, // Receives a pointer to an array of CLSIDs. &cDecoderCLSIDs // Receives the size of the array. )); // MFTEnum can return zero matches. if (cDecoderCLSIDs == 0) { hr = MF_E_TOPO_CODEC_NOT_FOUND; } else { //if the CDecoder instance does not exist, create one. if (!m_pDecoder) { CHECK_HR(hr = CDecoder::CreateInstance(&m_pDecoder)); } //Load the first MFT in the array for the current media type CHECK_HR(hr = m_pDecoder->Initialize(pDecoderCLSIDs[0], pMediaType)); } *pguidCurrentMediaType = guidMajorType; } else { // Not compressed. Don't need a decoder. CHECK_HR(hr = MF_E_INVALIDREQUEST); } TRACE((L"Stream decoder loaded.\n")); done: LOG_MSG_IF_FAILED(L"CASFManager::SetupStreamDecoder failed.\n", hr); SAFE_RELEASE(pProfile); SAFE_RELEASE(pMediaType); SAFE_RELEASE(pStream); CoTaskMemFree(pDecoderCLSIDs); return hr; }
HRESULT CASFManager::EnumerateStreams (WORD** ppwStreamNumbers, GUID** ppguidMajorType, DWORD* pcbTotalStreams) { if (!ppwStreamNumbers || !ppguidMajorType || !pcbTotalStreams) { return E_INVALIDARG; } if (!m_pContentInfo) { return MF_E_NOT_INITIALIZED; } HRESULT hr = S_OK; IMFASFStreamConfig* pStream = NULL; IMFASFProfile* pProfile = NULL; *pcbTotalStreams =0; WORD* pwStreamNumbers; GUID* pguidMajorType; CHECK_HR(hr = m_pContentInfo->GetProfile(&pProfile)); CHECK_HR(hr = pProfile->GetStreamCount(pcbTotalStreams)); if (*pcbTotalStreams == 0) { SAFE_RELEASE(pProfile); return E_FAIL; } //create an array of stream numbers and initialize elements swith 0 pwStreamNumbers = new WORD[*pcbTotalStreams*sizeof(WORD)]; if (!pwStreamNumbers) { hr = E_OUTOFMEMORY; goto done; } ZeroMemory (pwStreamNumbers, *pcbTotalStreams*sizeof(WORD)); //create an array of guids and initialize elements with GUID_NULL. pguidMajorType = new GUID[*pcbTotalStreams*sizeof(GUID)]; if (!pguidMajorType) { hr = E_OUTOFMEMORY; goto done; } ZeroMemory (pguidMajorType, *pcbTotalStreams*sizeof(GUID)); //populate the arrays with stream numbers and guids from the profile object for (unsigned index = 0; index < *pcbTotalStreams; index++) { CHECK_HR(hr = pProfile->GetStream(index, &pwStreamNumbers[index], &pStream)); CHECK_HR(hr = pStream->GetStreamType(&pguidMajorType[index])); SAFE_RELEASE(pStream); } *ppwStreamNumbers = pwStreamNumbers; *ppguidMajorType = pguidMajorType; TRACE((L"Enumerated streams.\n")); done: LOG_MSG_IF_FAILED(L"CASFManager::EnumerateStreams failed.\n", hr); SAFE_RELEASE(pProfile); SAFE_RELEASE(pStream); if (FAILED (hr)) { SAFE_ARRAY_DELETE(pwStreamNumbers); SAFE_ARRAY_DELETE(pguidMajorType); } return hr; }
HRESULT CASFManager::CreateASFIndexer (IMFByteStream *pContentByteStream, IMFASFIndexer **ppIndexer) { if (!pContentByteStream || !ppIndexer) { return E_INVALIDARG; } if (!m_pContentInfo) { return MF_E_NOT_INITIALIZED; } HRESULT hr = S_OK; IMFASFIndexer *pIndexer = NULL; IMFByteStream *pIndexerByteStream = NULL; QWORD qwLength = 0, qwIndexOffset = 0, qwBytestreamLength = 0; DWORD dwByteStreamsNeeded = 0; // Create the indexer. CHECK_HR(hr = MFCreateASFIndexer(&pIndexer)); //Initialize the indexer to work with this ASF library CHECK_HR(hr = pIndexer->Initialize(m_pContentInfo)); //Check if the index exists. //you can only do this after creating the indexer //Get byte stream length CHECK_HR(hr = pContentByteStream->GetLength(&qwLength)); //Get index offset CHECK_HR(hr = pIndexer->GetIndexPosition( m_pContentInfo, &qwIndexOffset )); if ( qwIndexOffset >= qwLength) { //index object does not exist, release the indexer goto done; } else { // initialize the indexer // Create a byte stream that the Indexer will use to read in // and parse the indexers. CHECK_HR(hr = MFCreateASFIndexerByteStream( pContentByteStream, qwIndexOffset, &pIndexerByteStream )); } CHECK_HR(hr = pIndexer->GetIndexByteStreamCount( &dwByteStreamsNeeded )); if (dwByteStreamsNeeded == 1) { CHECK_HR(hr = pIndexer->SetIndexByteStreams( &pIndexerByteStream, dwByteStreamsNeeded )); } // Return the pointer to the caller. *ppIndexer = pIndexer; (*ppIndexer)->AddRef(); TRACE((L"Created Indexer object.\n")); done: LOG_MSG_IF_FAILED(L"CASFManager::CreateASFIndexer failed.\n", hr); SAFE_RELEASE(pIndexer); SAFE_RELEASE(pIndexerByteStream); return hr; }
HRESULT WebHelper::OpenURLWithData(const WCHAR *wszURL, const BYTE *pbPostData, DWORD cbData) { // This string is the header needed for HTTP POST actions. const LPWSTR POST_HEADER_DATA = L"Content-Type: application/x-www-form-urlencoded\r\n"; if (!wszURL) { return E_INVALIDARG; } if (!m_pBrowser) { return E_UNEXPECTED; } HRESULT hr = S_OK; BSTR bstrURL = NULL; VARIANT vtEmpty; VARIANT vtHeader; VARIANT vtPostData; VariantInit(&vtEmpty); VariantInit(&vtHeader); VariantInit(&vtPostData); // Allocate a BSTR for the URL. bstrURL = SysAllocString(wszURL); if (bstrURL == NULL) { hr = E_OUTOFMEMORY; } // Allocate a BSTR for the header. if (SUCCEEDED(hr)) { vtHeader.bstrVal = SysAllocString(POST_HEADER_DATA); if (vtHeader.bstrVal == NULL) { hr = E_OUTOFMEMORY; } else { vtHeader.vt = VT_BSTR; } } if (SUCCEEDED(hr)) { if ( pbPostData ) { // Convert the POST data to a safe array in a variant. The safe array type is VT_UI1. void *pvData = NULL; SAFEARRAY *saPostData = SafeArrayCreateVector(VT_UI1, 0, cbData); if (saPostData == NULL) { hr = E_OUTOFMEMORY; } if (SUCCEEDED(hr)) { hr = SafeArrayAccessData(saPostData, &pvData); } if (SUCCEEDED(hr)) { CopyMemory((BYTE*)pvData, pbPostData, cbData); hr = SafeArrayUnaccessData(saPostData); } if (SUCCEEDED(hr)) { vtPostData.vt = VT_ARRAY | VT_UI1; vtPostData.parray = saPostData; } } } // Make the IE window visible. if (SUCCEEDED(hr)) { hr = m_pBrowser->put_Visible(VARIANT_TRUE); LOG_MSG_IF_FAILED(L"put_Visible)", hr); } // Navigate to the URL. if (SUCCEEDED(hr)) { hr = m_pBrowser->Navigate(bstrURL, &vtEmpty, &vtEmpty, &vtPostData, &vtHeader); LOG_MSG_IF_FAILED(L"Navigate", hr); } SysFreeString(bstrURL); VariantClear(&vtEmpty); VariantClear(&vtHeader); VariantClear(&vtPostData); return hr; }
HRESULT CASFManager::SetFilePropertiesObject(FILE_PROPERTIES_OBJECT* fileinfo) { if (! m_pContentInfo) { return MF_E_NOT_INITIALIZED; } HRESULT hr = S_OK; IMFPresentationDescriptor *pPD = NULL; UINT32 cbBlobSize = 0; CHECK_HR( hr = m_pContentInfo->GeneratePresentationDescriptor(&pPD)); //get File ID hr = pPD->GetGUID(MF_PD_ASF_FILEPROPERTIES_FILE_ID, &fileinfo->guidFileID); // get Creation Time hr = pPD->GetBlob(MF_PD_ASF_FILEPROPERTIES_CREATION_TIME, (BYTE *)&fileinfo->ftCreationTime, sizeof(FILETIME), &cbBlobSize); //get Data Packets Count hr = pPD->GetUINT32(MF_PD_ASF_FILEPROPERTIES_PACKETS, &fileinfo->cbPackets); //get Play Duration hr = pPD->GetUINT64(MF_PD_ASF_FILEPROPERTIES_PLAY_DURATION, &fileinfo->cbPlayDuration); //get presentation duration hr = pPD->GetUINT64(MF_PD_DURATION, &fileinfo->cbPresentationDuration); //get Send Duration hr = pPD->GetUINT64(MF_PD_ASF_FILEPROPERTIES_SEND_DURATION, &fileinfo->cbSendDuration); //get preroll UINT64 msecspreroll = 0, hnspreroll =0; hr = pPD->GetUINT64(MF_PD_ASF_FILEPROPERTIES_PREROLL, &msecspreroll); hnspreroll = msecspreroll*10000; fileinfo->cbPreroll = hnspreroll; //get Flags hr = pPD->GetUINT32(MF_PD_ASF_FILEPROPERTIES_FLAGS, &fileinfo->cbFlags); //get Maximum Data Packet Size hr = pPD->GetUINT32(MF_PD_ASF_FILEPROPERTIES_MAX_PACKET_SIZE, &fileinfo->cbMaxPacketSize); //get Minimum Data Packet Size hr = pPD->GetUINT32(MF_PD_ASF_FILEPROPERTIES_MIN_PACKET_SIZE, &fileinfo->cbMinPacketSize); // get Maximum Bit rate hr = pPD->GetUINT32(MF_PD_ASF_FILEPROPERTIES_MAX_BITRATE, &fileinfo->cbMaxBitRate); this->m_fileinfo = fileinfo; TRACE((L"Read File Properties Object from the ASF Header Object.\n")); done: LOG_MSG_IF_FAILED(L"CASFManager::SetFilePropertiesObject failed.\n", hr); SAFE_RELEASE(pPD); return hr; }