__int64 CBaseSplitterFilter::SeekBD(REFERENCE_TIME rt) { if (m_Items.GetCount()) { POSITION pos = m_Items.GetHeadPosition(); while (pos) { CHdmvClipInfo::PlaylistItem* Item = m_Items.GetNext(pos); if (rt >= Item->m_rtStartTime && rt <= (Item->m_rtStartTime + Item->Duration())) { REFERENCE_TIME _rt = rt - Item->m_rtStartTime + Item->m_rtIn; for (size_t idx = 0; idx < Item->m_sps.GetCount() - 1; idx++) { if (_rt < Item->m_sps[idx].rt) { if (idx > 0) { idx--; } return Item->m_sps[idx].fp + Item->m_SizeIn; } } } } } return -1; }
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()); }