HRESULT CHdmvClipInfo::ReadInfo(LPCTSTR strFile) { m_bIsHdmv = false; m_hFile = CreateFile(strFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY | FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (m_hFile != INVALID_HANDLE_VALUE) { BYTE Buff[100]; ReadBuffer(Buff, 4); if (memcmp(Buff, "HDMV", 4)) { return CloseFile(VFW_E_INVALID_FILE_FORMAT); } ReadBuffer(Buff, 4); if ((memcmp(Buff, "0200", 4) != 0) && (memcmp(Buff, "0100", 4) != 0)) { return CloseFile(VFW_E_INVALID_FILE_FORMAT); } SequenceInfo_start_address = ReadDword(); ProgramInfo_start_address = ReadDword(); ReadProgramInfo(); m_bIsHdmv = true; return CloseFile(S_OK); } return AmHresultFromWin32(GetLastError()); }
//----------------------------------------------------------------------------- // Construction // CBaseEDLReader::CBaseEDLReader(const CString Filename, HRESULT* phr) : m_hFile(NULL) , m_pFile(NULL) , m_cbFile(0) { HRESULT hr = S_OK; m_hFile = CreateFile(Filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (INVALID_HANDLE_VALUE != m_hFile) { m_cbFile = SetFilePointer(m_hFile, 0, NULL, FILE_END); if (INVALID_SET_FILE_POINTER != m_cbFile) { if (INVALID_SET_FILE_POINTER != SetFilePointer(m_hFile, 0, NULL, FILE_BEGIN)) { try { m_pFile = new char [m_cbFile]; if (m_pFile) { DWORD dwNumberOfBytesRead; if (0 == ReadFile(m_hFile, m_pFile, m_cbFile, &dwNumberOfBytesRead, NULL)) { hr = AmHresultFromWin32(GetLastError()); } } } catch (std::bad_alloc) { hr = E_OUTOFMEMORY; } } } else { hr = E_FAIL; } } else { hr = AmHresultFromWin32(GetLastError()); } if (FAILED(hr) && phr) { *phr = hr; } }
STDAPI RegisterFilters( BOOL bRegister ) { HRESULT hr = NOERROR; WCHAR achFileName[MAX_PATH]; char achTemp[MAX_PATH]; ASSERT(g_hInst != 0); if( 0 == GetModuleFileNameA(g_hInst, achTemp, sizeof(achTemp))) return AmHresultFromWin32(GetLastError()); MultiByteToWideChar(CP_ACP, 0L, achTemp, lstrlenA(achTemp) + 1, achFileName, NUMELMS(achFileName)); hr = CoInitialize(0); if(bRegister) { hr = AMovieSetupRegisterServer(CLSID_OgamaCaptureDesktop, L"OgamaCapture", achFileName, L"Both", L"InprocServer32"); } if( SUCCEEDED(hr) ) { IFilterMapper2 *fm = 0; hr = CreateComObject( CLSID_FilterMapper2, IID_IFilterMapper2, fm ); if( SUCCEEDED(hr) ) { if(bRegister) { IMoniker *pMoniker = 0; REGFILTER2 rf2; rf2.dwVersion = 1; rf2.dwMerit = MERIT_DO_NOT_USE; rf2.cPins = 1; rf2.rgPins = &sudOutputPinDesktop; // this is the name that actually shows up in VLC et al. weird hr = fm->RegisterFilter(CLSID_OgamaCaptureDesktop, L"OgamaCapture", &pMoniker, &CLSID_VideoInputDeviceCategory, NULL, &rf2); } else { hr = fm->UnregisterFilter(&CLSID_VideoInputDeviceCategory, 0, CLSID_OgamaCaptureDesktop); } } // release interface // if(fm) fm->Release(); } if( SUCCEEDED(hr) && !bRegister ) hr = AMovieSetupUnregisterServer( CLSID_OgamaCaptureDesktop ); CoFreeUnusedLibraries(); CoUninitialize(); return hr; }
HRESULT CHdmvClipInfo::ReadChapters(CString strPlaylistFile, CAtlList<CHdmvClipInfo::PlaylistItem>& PlaylistItems, CAtlList<PlaylistChapter>& Chapters) { CPath Path(strPlaylistFile); // Get BDMV folder Path.RemoveFileSpec(); Path.RemoveFileSpec(); m_hFile = CreateFile(strPlaylistFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY | FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (m_hFile != INVALID_HANDLE_VALUE) { REFERENCE_TIME* rtOffset = DEBUG_NEW REFERENCE_TIME[PlaylistItems.GetCount()]; REFERENCE_TIME rtSum = 0; int nIndex = 0; BYTE Buff[100]; bool bDuplicate = false; POSITION pos = PlaylistItems.GetHeadPosition(); while (pos) { CHdmvClipInfo::PlaylistItem& PI = PlaylistItems.GetNext(pos); rtOffset[nIndex] = rtSum - PI.m_rtIn; rtSum = rtSum + PI.Duration(); nIndex++; } ReadBuffer(Buff, 4); if (memcmp(Buff, "MPLS", 4)) { SAFE_DELETE_ARRAY(rtOffset); return CloseFile(VFW_E_INVALID_FILE_FORMAT); } ReadBuffer(Buff, 4); if ((memcmp(Buff, "0200", 4) != 0) && (memcmp(Buff, "0100", 4) != 0)) { SAFE_DELETE_ARRAY(rtOffset); return CloseFile(VFW_E_INVALID_FILE_FORMAT); } LARGE_INTEGER Pos; unsigned short nMarkCount; ReadDword(); // PlayList_start_address Pos.QuadPart = ReadDword(); // PlayListMark_start_address // PlayListMark() SetFilePointerEx(m_hFile, Pos, NULL, FILE_BEGIN); ReadDword(); // length nMarkCount = ReadShort(); // number_of_PlayList_marks for (size_t i = 0; i < nMarkCount; i++) { PlaylistChapter Chapter; ReadByte(); // reserved_for_future_use Chapter.m_nMarkType = (PlaylistMarkType)ReadByte(); // mark_type Chapter.m_nPlayItemId = ReadShort(); // ref_to_PlayItem_id Chapter.m_rtTimestamp = 20000i64 * ReadDword() / 90 + rtOffset[Chapter.m_nPlayItemId]; // mark_time_stamp Chapter.m_nEntryPID = ReadShort(); // entry_ES_PID Chapter.m_rtDuration = 20000i64 * ReadDword() / 90; // duration Chapters.AddTail(Chapter); //TRACE(_T("Chapter %d : %s\n"), i, ReftimeToString(Chapter.m_rtTimestamp)); } CloseFile(S_OK); SAFE_DELETE_ARRAY(rtOffset); return bDuplicate ? S_FALSE : S_OK; } return AmHresultFromWin32(GetLastError()); }
HRESULT CHdmvClipInfo::ReadPlaylist(CString strPlaylistFile, REFERENCE_TIME& rtDuration, CAtlList<PlaylistItem>& Playlist) { CPath Path(strPlaylistFile); rtDuration = 0; // Get BDMV folder Path.RemoveFileSpec(); Path.RemoveFileSpec(); m_hFile = CreateFile(strPlaylistFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY | FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (m_hFile != INVALID_HANDLE_VALUE) { BYTE Buff[100]; bool bDuplicate = false; ReadBuffer(Buff, 4); if (memcmp(Buff, "MPLS", 4)) { return CloseFile(VFW_E_INVALID_FILE_FORMAT); } ReadBuffer(Buff, 4); if ((memcmp(Buff, "0200", 4) != 0) && (memcmp(Buff, "0100", 4) != 0)) { return CloseFile(VFW_E_INVALID_FILE_FORMAT); } LARGE_INTEGER Pos; DWORD dwTemp; unsigned short nPlaylistItems; Pos.QuadPart = ReadDword(); // PlayList_start_address ReadDword(); // PlayListMark_start_address // PlayList() SetFilePointerEx(m_hFile, Pos, NULL, FILE_BEGIN); ReadDword(); // length ReadShort(); // reserved_for_future_use nPlaylistItems = ReadShort(); // number_of_PlayItems ReadShort(); // number_of_SubPaths Pos.QuadPart += 10; for (size_t i = 0; i < nPlaylistItems; i++) { PlaylistItem Item; SetFilePointerEx(m_hFile, Pos, NULL, FILE_BEGIN); Pos.QuadPart += ReadShort() + 2; ReadBuffer(Buff, 5); Item.m_strFileName.Format(_T("%s\\STREAM\\%c%c%c%c%c.M2TS"), Path, Buff[0], Buff[1], Buff[2], Buff[3], Buff[4]); ReadBuffer(Buff, 4); if (memcmp(Buff, "M2TS", 4)) { return CloseFile(VFW_E_INVALID_FILE_FORMAT); } ReadBuffer(Buff, 3); dwTemp = ReadDword(); Item.m_rtIn = 20000i64 * dwTemp / 90; // Carefull : 32->33 bits! dwTemp = ReadDword(); Item.m_rtOut = 20000i64 * dwTemp / 90; // Carefull : 32->33 bits! rtDuration += (Item.m_rtOut - Item.m_rtIn); if (Playlist.Find(Item) != NULL) { bDuplicate = true; } Playlist.AddTail(Item); //TRACE(_T("File : %s, Duration : %s, Total duration : %s\n"), strTemp, ReftimeToString (rtOut - rtIn), ReftimeToString (rtDuration)); } CloseFile(S_OK); return bDuplicate ? S_FALSE : S_OK; } return AmHresultFromWin32(GetLastError()); }
STDAPI AMovieDllRegisterServer( void ) { HRESULT hr = NOERROR; // get file name (where g_hInst is the // instance handle of the filter dll) // WCHAR achFileName[MAX_PATH]; { // WIN95 doesn't support GetModuleFileNameW // char achTemp[MAX_PATH]; if( 0 == GetModuleFileNameA( g_hInst , achTemp , sizeof(achTemp) ) ) { // we've failed! DWORD dwerr = GetLastError(); return AmHresultFromWin32(dwerr); } MultiByteToWideChar( CP_ACP , 0L , achTemp , lstrlenA(achTemp) + 1 , achFileName , NUMELMS(achFileName) ); } // scan through array of CFactoryTemplates // registering servers and filters. // for( int i = 0; i < g_cTemplates; i++ ) { // get i'th template // const CFactoryTemplate *pT = &g_Templates[i]; // register CLSID and InprocServer32 // hr = AMovieSetupRegisterServer( *(pT->m_ClsID) , (LPCWSTR)pT->m_Name , achFileName ); // instantiate all servers and get hold of // IAMovieSetup, if implemented, and call // IAMovieSetup.Register() method // if( SUCCEEDED(hr) && (NULL != pT->m_lpfnNew) ) { // instantiate object // PAMOVIESETUP psetup; hr = CoCreateInstance( *(pT->m_ClsID) , 0 , CLSCTX_INPROC_SERVER , IID_IAMovieSetup , reinterpret_cast<void**>(&psetup) ); if( SUCCEEDED(hr) ) { hr = psetup->Unregister(); if( SUCCEEDED(hr) ) hr = psetup->Register(); psetup->Release(); } else { if( (E_NOINTERFACE == hr ) || (VFW_E_NEED_OWNER == hr ) ) hr = NOERROR; } } // check final error for this pass // and break loop if we failed // if( FAILED(hr) ) break; } // end-for return hr; }
STDAPI AMovieDllRegisterServer2( BOOL bRegister ) { HRESULT hr = NOERROR; DbgLog((LOG_TRACE, 2, TEXT("AMovieDllRegisterServer2()"))); // get file name (where g_hInst is the // instance handle of the filter dll) // WCHAR achFileName[MAX_PATH]; // WIN95 doesn't support GetModuleFileNameW // { char achTemp[MAX_PATH]; DbgLog((LOG_TRACE, 2, TEXT("- get module file name"))); // g_hInst handle is set in our dll entry point. Make sure // DllEntryPoint in dllentry.cpp is called ASSERT(g_hInst != 0); if( 0 == GetModuleFileNameA( g_hInst , achTemp , sizeof(achTemp) ) ) { // we've failed! DWORD dwerr = GetLastError(); return AmHresultFromWin32(dwerr); } MultiByteToWideChar( CP_ACP , 0L , achTemp , lstrlenA(achTemp) + 1 , achFileName , NUMELMS(achFileName) ); } // // first registering, register all OLE servers // if( bRegister ) { DbgLog((LOG_TRACE, 2, TEXT("- register OLE Servers"))); hr = RegisterAllServers( achFileName, TRUE ); } // // next, register/unregister all filters // if( SUCCEEDED(hr) ) { // init is ref counted so call just in case // we're being called cold. // DbgLog((LOG_TRACE, 2, TEXT("- CoInitialize"))); hr = CoInitialize( (LPVOID)NULL ); ASSERT( SUCCEEDED(hr) ); // get hold of IFilterMapper2 // DbgLog((LOG_TRACE, 2, TEXT("- obtain IFilterMapper2"))); IFilterMapper2 *pIFM2 = 0; IFilterMapper *pIFM = 0; hr = CoCreateInstance( CLSID_FilterMapper2 , NULL , CLSCTX_INPROC_SERVER , IID_IFilterMapper2 , (void **)&pIFM2 ); if(FAILED(hr)) { DbgLog((LOG_TRACE, 2, TEXT("- trying IFilterMapper instead"))); hr = CoCreateInstance( CLSID_FilterMapper, NULL, CLSCTX_INPROC_SERVER, IID_IFilterMapper, (void **)&pIFM); } if( SUCCEEDED(hr) ) { // scan through array of CFactoryTemplates // registering servers and filters. // DbgLog((LOG_TRACE, 2, TEXT("- register Filters"))); for( int i = 0; i < g_cTemplates; i++ ) { // get i'th template // const CFactoryTemplate *pT = &g_Templates[i]; if( NULL != pT->m_pAMovieSetup_Filter ) { DbgLog((LOG_TRACE, 2, TEXT("- - register %ls"), (LPCWSTR)pT->m_Name )); if(pIFM2) { hr = AMovieSetupRegisterFilter2( pT->m_pAMovieSetup_Filter, pIFM2, bRegister ); } else { hr = AMovieSetupRegisterFilter( pT->m_pAMovieSetup_Filter, pIFM, bRegister ); } } // check final error for this pass // and break loop if we failed // if( FAILED(hr) ) break; } // release interface // if(pIFM2) pIFM2->Release(); else pIFM->Release(); } // and clear up // CoFreeUnusedLibraries(); CoUninitialize(); } // // if unregistering, unregister all OLE servers // if( SUCCEEDED(hr) && !bRegister ) { DbgLog((LOG_TRACE, 2, TEXT("- register OLE Servers"))); hr = RegisterAllServers( achFileName, FALSE ); } DbgLog((LOG_TRACE, 2, TEXT("- return %0x"), hr)); return hr; }
STDAPI AMovieSetupRegisterServer( CLSID clsServer , LPCWSTR szDescription , LPCWSTR szFileName , LPCWSTR szThreadingModel = L"Both" , LPCWSTR szServerType = L"InprocServer32" ) { // temp buffer // TCHAR achTemp[MAX_PATH]; // convert CLSID uuid to string and write // out subkey as string - CLSID\{} // OLECHAR szCLSID[CHARS_IN_GUID]; HRESULT hr = StringFromGUID2( clsServer , szCLSID , CHARS_IN_GUID ); ASSERT( SUCCEEDED(hr) ); // create key // HKEY hkey; wsprintf( achTemp, TEXT("CLSID\\%ls"), szCLSID ); LONG lreturn = RegCreateKey( HKEY_CLASSES_ROOT , (LPCTSTR)achTemp , &hkey ); if( ERROR_SUCCESS != lreturn ) { return AmHresultFromWin32(lreturn); } // set description string // wsprintf( achTemp, TEXT("%ls"), szDescription ); lreturn = RegSetValue( hkey , (LPCTSTR)NULL , REG_SZ , achTemp , sizeof(achTemp) ); if( ERROR_SUCCESS != lreturn ) { RegCloseKey( hkey ); return AmHresultFromWin32(lreturn); } // create CLSID\\{"CLSID"}\\"ServerType" key, // using key to CLSID\\{"CLSID"} passed back by // last call to RegCreateKey(). // HKEY hsubkey; wsprintf( achTemp, TEXT("%ls"), szServerType ); lreturn = RegCreateKey( hkey , achTemp , &hsubkey ); if( ERROR_SUCCESS != lreturn ) { RegCloseKey( hkey ); return AmHresultFromWin32(lreturn); } // set Server string // wsprintf( achTemp, TEXT("%ls"), szFileName ); lreturn = RegSetValue( hsubkey , (LPCTSTR)NULL , REG_SZ , (LPCTSTR)achTemp , sizeof(TCHAR) * (lstrlen(achTemp)+1) ); if( ERROR_SUCCESS != lreturn ) { RegCloseKey( hkey ); RegCloseKey( hsubkey ); return AmHresultFromWin32(lreturn); } wsprintf( achTemp, TEXT("%ls"), szThreadingModel ); lreturn = RegSetValueEx( hsubkey , TEXT("ThreadingModel") , 0L , REG_SZ , (CONST BYTE *)achTemp , sizeof(TCHAR) * (lstrlen(achTemp)+1) ); // close hkeys // RegCloseKey( hkey ); RegCloseKey( hsubkey ); // and return // return HRESULT_FROM_WIN32(lreturn); }
// // COutputQueue Constructor : // // Determines if a thread is to be created and creates resources // // pInputPin - the downstream input pin we're queueing samples to // // phr - changed to a failure code if this function fails // (otherwise unchanges) // // bAuto - Ask pInputPin if it can block in Receive by calling // its ReceiveCanBlock method and create a thread if // it can block, otherwise not. // // bQueue - if bAuto == FALSE then we create a thread if and only // if bQueue == TRUE // // lBatchSize - work in batches of lBatchSize // // bBatchEact - Use exact batch sizes so don't send until the // batch is full or SendAnyway() is called // // lListSize - If we create a thread make the list of samples queued // to the thread have this size cache // // dwPriority - If we create a thread set its priority to this // COutputQueue::COutputQueue( IPin *pInputPin, // Pin to send stuff to __inout HRESULT *phr, // 'Return code' BOOL bAuto, // Ask pin if queue or not BOOL bQueue, // Send through queue LONG lBatchSize, // Batch BOOL bBatchExact, // Batch exactly to BatchSize LONG lListSize, DWORD dwPriority, bool bFlushingOpt // flushing optimization ) : m_lBatchSize(lBatchSize), m_bBatchExact(bBatchExact && (lBatchSize > 1)), m_hThread(NULL), m_hSem(NULL), m_List(NULL), m_pPin(pInputPin), m_ppSamples(NULL), m_lWaiting(0), m_evFlushComplete(FALSE, phr), m_pInputPin(NULL), m_bSendAnyway(FALSE), m_nBatched(0), m_bFlushing(FALSE), m_bFlushed(TRUE), m_bFlushingOpt(bFlushingOpt), m_bTerminate(FALSE), m_hEventPop(NULL), m_hr(S_OK) { ASSERT(m_lBatchSize > 0); if (FAILED(*phr)) { return; } // Check the input pin is OK and cache its IMemInputPin interface *phr = pInputPin->QueryInterface(IID_IMemInputPin, (void **)&m_pInputPin); if (FAILED(*phr)) { return; } // See if we should ask the downstream pin if (bAuto) { HRESULT hr = m_pInputPin->ReceiveCanBlock(); if (SUCCEEDED(hr)) { bQueue = hr == S_OK; } } // Create our sample batch m_ppSamples = new PMEDIASAMPLE[m_lBatchSize]; if (m_ppSamples == NULL) { *phr = E_OUTOFMEMORY; return; } // If we're queueing allocate resources if (bQueue) { DbgLog((LOG_TRACE, 2, TEXT("Creating thread for output pin"))); m_hSem = CreateSemaphore(NULL, 0, 0x7FFFFFFF, NULL); if (m_hSem == NULL) { DWORD dwError = GetLastError(); *phr = AmHresultFromWin32(dwError); return; } m_List = new CSampleList(NAME("Sample Queue List"), lListSize, FALSE // No lock ); if (m_List == NULL) { *phr = E_OUTOFMEMORY; return; } DWORD dwThreadId; m_hThread = CreateThread(NULL, 0, InitialThreadProc, (LPVOID)this, 0, &dwThreadId); if (m_hThread == NULL) { DWORD dwError = GetLastError(); *phr = AmHresultFromWin32(dwError); return; } SetThreadPriority(m_hThread, dwPriority); } else { DbgLog((LOG_TRACE, 2, TEXT("Calling input pin directly - no thread"))); } }
STDMETHODIMP CBaseDispatch::GetTypeInfo( REFIID riid, UINT itinfo, LCID lcid, ITypeInfo ** pptinfo) { CheckPointer(pptinfo,E_POINTER); ValidateReadWritePtr(pptinfo,sizeof(ITypeInfo *)); HRESULT hr; *pptinfo = NULL; // we only support one type element if (0 != itinfo) { return TYPE_E_ELEMENTNOTFOUND; } if (NULL == pptinfo) { return E_POINTER; } // always look for neutral if (NULL == m_pti) { LPLOADTYPELIB lpfnLoadTypeLib; LPLOADREGTYPELIB lpfnLoadRegTypeLib; ITypeLib *ptlib; HINSTANCE hInst; static const char szTypeLib[] = "LoadTypeLib"; static const char szRegTypeLib[] = "LoadRegTypeLib"; static const WCHAR szControl[] = L"control.tlb"; // // Try to get the Ole32Aut.dll module handle. // hInst = LoadOLEAut32(); if (hInst == NULL) { DWORD dwError = GetLastError(); return AmHresultFromWin32(dwError); } lpfnLoadRegTypeLib = (LPLOADREGTYPELIB)GetProcAddress(hInst, szRegTypeLib); if (lpfnLoadRegTypeLib == NULL) { DWORD dwError = GetLastError(); return AmHresultFromWin32(dwError); } hr = (*lpfnLoadRegTypeLib)(LIBID_QuartzTypeLib, 1, 0, // version 1.0 lcid, &ptlib); if (FAILED(hr)) { // attempt to load directly - this will fill the // registry in if it finds it lpfnLoadTypeLib = (LPLOADTYPELIB)GetProcAddress(hInst, szTypeLib); if (lpfnLoadTypeLib == NULL) { DWORD dwError = GetLastError(); return AmHresultFromWin32(dwError); } hr = (*lpfnLoadTypeLib)(szControl, &ptlib); if (FAILED(hr)) { return hr; } } hr = ptlib->GetTypeInfoOfGuid( riid, &m_pti); ptlib->Release(); if (FAILED(hr)) { return hr; } } *pptinfo = m_pti; m_pti->AddRef(); return S_OK; }
HRESULT CHdmvClipInfo::ReadChapters(CString strPlaylistFile, CPlaylist& PlaylistItems, CPlaylistChapter& Chapters) { BYTE Buff[4]; CPath Path(strPlaylistFile); // Get BDMV folder Path.RemoveFileSpec(); Path.RemoveFileSpec(); m_hFile = CreateFile(strPlaylistFile, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY|FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (m_hFile != INVALID_HANDLE_VALUE) { REFERENCE_TIME* rtOffset = DNew REFERENCE_TIME[PlaylistItems.GetCount()]; REFERENCE_TIME rtSum = 0; USHORT nIndex = 0; POSITION pos = PlaylistItems.GetHeadPosition(); while (pos) { CHdmvClipInfo::PlaylistItem* PI = PlaylistItems.GetNext(pos); rtOffset[nIndex] = rtSum - PI->m_rtIn; rtSum = rtSum + PI->Duration(); nIndex++; } ReadBuffer(Buff, 4); if (memcmp(Buff, "MPLS", 4)) { SAFE_DELETE_ARRAY(rtOffset); return CloseFile(VFW_E_INVALID_FILE_FORMAT); } ReadBuffer(Buff, 4); if ((memcmp(Buff, "0200", 4)!=0) && (memcmp(Buff, "0100", 4)!=0)) { SAFE_DELETE_ARRAY(rtOffset); return CloseFile(VFW_E_INVALID_FILE_FORMAT); } LARGE_INTEGER Pos = {0, 0}; USHORT nMarkCount; ReadDword(); // PlayList_start_address Pos.QuadPart = ReadDword(); // PlayListMark_start_address // PlayListMark() SetFilePointerEx(m_hFile, Pos, NULL, FILE_BEGIN); ReadDword(); // length nMarkCount = ReadShort(); // number_of_PlayList_marks for (size_t i = 0; i < nMarkCount; i++) { PlaylistChapter Chapter; ReadByte(); // reserved_for_future_use Chapter.m_nMarkType = (PlaylistMarkType)ReadByte(); // mark_type Chapter.m_nPlayItemId = ReadShort(); // ref_to_PlayItem_id Chapter.m_rtTimestamp = REFERENCE_TIME(20000.0f*ReadDword()/90) + rtOffset[Chapter.m_nPlayItemId]; // mark_time_stamp Chapter.m_nEntryPID = ReadShort(); // entry_ES_PID Chapter.m_rtDuration = REFERENCE_TIME(20000.0f*ReadDword()/90); // duration if (Chapter.m_rtTimestamp < 0 || Chapter.m_rtTimestamp > rtSum) { continue; } Chapters.AddTail (Chapter); } CloseFile(S_OK); SAFE_DELETE_ARRAY(rtOffset); return S_OK; } return AmHresultFromWin32(GetLastError()); }
HRESULT CHdmvClipInfo::ReadPlaylist(CString strPlaylistFile, REFERENCE_TIME& rtDuration, CPlaylist& Playlist, BOOL bFullInfoRead) { BYTE Buff[5]; CPath Path (strPlaylistFile); bool bDuplicate = false; rtDuration = 0; // Get BDMV folder Path.RemoveFileSpec(); Path.RemoveFileSpec(); m_hFile = CreateFile(strPlaylistFile, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY|FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (m_hFile != INVALID_HANDLE_VALUE) { DbgLog((LOG_TRACE, 3, _T("CHdmvClipInfo::ReadPlaylist() : %s"), strPlaylistFile)); ReadBuffer(Buff, 4); if (memcmp(Buff, "MPLS", 4)) { return CloseFile(VFW_E_INVALID_FILE_FORMAT); } ReadBuffer(Buff, 4); if ((memcmp(Buff, "0200", 4)) && (memcmp(Buff, "0100", 4))) { return CloseFile(VFW_E_INVALID_FILE_FORMAT); } LARGE_INTEGER Pos = {0, 0}; DWORD dwTemp; USHORT nPlaylistItems; Pos.QuadPart = ReadDword(); // PlayList_start_address ReadDword(); // PlayListMark_start_address // PlayList() SetFilePointerEx(m_hFile, Pos, NULL, FILE_BEGIN); ReadDword(); // length ReadShort(); // reserved_for_future_use nPlaylistItems = ReadShort(); // number_of_PlayItems ReadShort(); // number_of_SubPaths Pos.QuadPart += 10; __int64 TotalSize = 0; for (size_t i = 0; i < nPlaylistItems; i++) { CAutoPtr<PlaylistItem> Item(DNew PlaylistItem); SetFilePointerEx(m_hFile, Pos, NULL, FILE_BEGIN); Pos.QuadPart += ReadShort() + 2; ReadBuffer(Buff, 5); Item->m_strFileName.Format(_T("%s\\STREAM\\%c%c%c%c%c.M2TS"), CString(Path), Buff[0], Buff[1], Buff[2], Buff[3], Buff[4]); ReadBuffer(Buff, 4); if (memcmp(Buff, "M2TS", 4)) { return CloseFile(VFW_E_INVALID_FILE_FORMAT); } if (!::PathFileExists(Item->m_strFileName)) { DbgLog((LOG_TRACE, 3, _T(" ==> %s is missing, skip it"), Item->m_strFileName)); continue; } ReadBuffer(Buff, 3); dwTemp = ReadDword(); Item->m_rtIn = REFERENCE_TIME(20000.0f*dwTemp/90); dwTemp = ReadDword(); Item->m_rtOut = REFERENCE_TIME(20000.0f*dwTemp/90); Item->m_rtStartTime = rtDuration; rtDuration += (Item->m_rtOut - Item->m_rtIn); if (bFullInfoRead) { LARGE_INTEGER size = {0, 0}; HANDLE hFile = CreateFile(Item->m_strFileName, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY|FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (hFile != INVALID_HANDLE_VALUE) { GetFileSizeEx(hFile, &size); CloseHandle(hFile); } Item->m_SizeIn = TotalSize; TotalSize += size.QuadPart; Item->m_SizeOut = TotalSize; } POSITION pos = Playlist.GetHeadPosition(); while (pos) { PlaylistItem* pItem = Playlist.GetNext(pos); if (*pItem == *Item) { bDuplicate = true; break; } } DbgLog((LOG_TRACE, 3, _T(" ==> %s, Duration : %s [%15I64d], Total duration : %s, Size : %I64d"), Item->m_strFileName, ReftimeToString(Item->Duration()), Item->Duration(), ReftimeToString(rtDuration), Item->Size())); Playlist.AddTail(Item); } CloseFile(S_OK); if (bFullInfoRead) { POSITION pos = Playlist.GetHeadPosition(); while (pos) { PlaylistItem* pItem = Playlist.GetNext(pos); CString fname = pItem->m_strFileName; fname.Replace(L"\\STREAM\\", L"\\CLIPINF\\"); fname.Replace(L".M2TS", L".CLPI"); ReadInfo(fname, &pItem->m_sps); } } return Playlist.IsEmpty() ? E_FAIL : bDuplicate ? S_FALSE : S_OK; } return AmHresultFromWin32(GetLastError()); }