Example #1
0
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());
}