コード例 #1
0
ファイル: dshowutil.cpp プロジェクト: shilinxu/iprojects
HRESULT SeekNextFrame( IMediaSeeking * pSeeking, double FPS, long Frame )
{
    // try seeking by frames first
    //
    HRESULT hr = pSeeking->SetTimeFormat(&TIME_FORMAT_FRAME);
    REFERENCE_TIME Pos = 0;
    if(!FAILED(hr))
    {
        pSeeking->GetCurrentPosition(&Pos);
        Pos++;
    }
    else
    {
        // couldn't seek by frames, use Frame and FPS to calculate time
        //
        Pos = REFERENCE_TIME(double( Frame * UNITS ) / FPS);

        // add a half-frame to seek to middle of the frame
        //
        Pos += REFERENCE_TIME(double( UNITS ) * 0.5 / FPS);
    }

    hr = pSeeking->SetPositions(&Pos, AM_SEEKING_AbsolutePositioning,
                                NULL, AM_SEEKING_NoPositioning);
    return hr;

}
コード例 #2
0
ファイル: PGSSub.cpp プロジェクト: Blitzker/mpc-hc
void CPGSSubFile::ParseFile(CString fn)
{
    CFile f;
    if (!f.Open(fn, CFile::modeRead | CFile::shareDenyWrite)) {
        return;
    }

    // Header: Sync code | start time | stop time | segment type | segment size
    std::array < BYTE, 2 + 2 * 4 + 1 + 2 > header;
    const int nExtraSize = 1 + 2; // segment type + segment size
    std::vector<BYTE> segBuff;

    while (!m_bStopParsing && f.Read(header.data(), (UINT)header.size()) == header.size()) {
        // Parse the header
        CGolombBuffer headerBuffer(header.data(), (int)header.size());

        if (WORD(headerBuffer.ReadShort()) != PGS_SYNC_CODE) {
            break;
        }

        REFERENCE_TIME rtStart = REFERENCE_TIME(headerBuffer.ReadDword()) * 1000 / 9;
        REFERENCE_TIME rtStop  = REFERENCE_TIME(headerBuffer.ReadDword()) * 1000 / 9;
        headerBuffer.ReadByte(); // segment type
        WORD wLenSegment = (WORD)headerBuffer.ReadShort();

        // Leave some room to add the segment type and size
        int nLenData = nExtraSize + wLenSegment;
        segBuff.resize(nLenData);
        memcpy(segBuff.data(), &header[header.size() - nExtraSize], nExtraSize);

        // Read the segment
        if (wLenSegment && f.Read(&segBuff[nExtraSize], wLenSegment) != wLenSegment) {
            break;
        }

        // Parse the data (even if the segment size is 0 because the header itself is important)
        TRACE_PGSSUB(_T("--------- CPGSSubFile::ParseFile rtStart=%s, rtStop=%s, len=%d ---------\n"),
                     ReftimeToString(rtStart), ReftimeToString(rtStop), nLenData);
        ParseSample(rtStart, rtStop, segBuff.data(), nLenData);
    }
}
コード例 #3
0
ファイル: wasapi.cpp プロジェクト: Noplace/NesEmu
int WASAPI_Initialize(int rate,int channels,int bits) {
  
  //WAVEFORMATEX* closest_fmt = (WAVEFORMATEX*)CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE));
 // WAVEFORMATEX** pclosest_fmt = &closest_fmt;
  fmt.Format.wFormatTag			= WAVE_FORMAT_EXTENSIBLE;
  fmt.Format.nChannels				= channels;
  fmt.Format.nSamplesPerSec	= rate;
  fmt.Format.wBitsPerSample	= (bits+7)&~7;
  fmt.Format.nBlockAlign			= channels * fmt.Format.wBitsPerSample>>3;
  fmt.Format.nAvgBytesPerSec	= fmt.Format.nBlockAlign * fmt.Format.nSamplesPerSec;
  fmt.Format.cbSize					= 22;
  fmt.Samples.wValidBitsPerSample	= bits;
	fmt.dwChannelMask					= channels==2 ? 3 : 4;	//Select left & right (stereo) or center (mono)
	fmt.SubFormat						= KSDATAFORMAT_SUBTYPE_PCM;
  //pwfx = &fmt.Format;
  HRESULT hr;
  hr = CoCreateInstance(CLSID_MMDeviceEnumerator,NULL,CLSCTX_ALL,IID_IMMDeviceEnumerator,(void**)&device_enumurator);
  if (FAILED(hr)) return S_FALSE;
  hr = device_enumurator->GetDefaultAudioEndpoint(eRender,eConsole,&device);
  if (FAILED(hr)) return S_FALSE;
  hr = device->Activate(IID_IAudioClient, CLSCTX_ALL,NULL, (void**)&audio_client);
  if (FAILED(hr)) return S_FALSE;
  hr = audio_client->GetMixFormat(&pwfx);
  //if (FAILED(hr)) return S_FALSE;
  //hr = audio_client->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED,(WAVEFORMATEX*)&fmt,pclosest_fmt);
  //hr = audio_client->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE,(WAVEFORMATEX*)&fmt,NULL);
  //CoTaskMemFree(closest_fmt);
  hr = audio_client->Initialize(AUDCLNT_SHAREMODE_SHARED,0,hnsRequestedDuration,0,pwfx,NULL);
  if (FAILED(hr)) return S_FALSE;
  //hr = pMySource->SetFormat(pwfx);
  //if (FAILED(hr)) return S_FALSE;

  // Get the actual size of the allocated buffer.
  hr = audio_client->GetBufferSize(&bufferFrameCount);
  if (FAILED(hr)) return S_FALSE;

  hr = audio_client->GetService(IID_IAudioRenderClient,(void**)&render_client);
  if (FAILED(hr)) return S_FALSE;

  hnsActualDuration = REFERENCE_TIME((double)REFTIMES_PER_SEC *
                        bufferFrameCount / fmt.Format.nSamplesPerSec);

  written_samples = 0;

  audio_block = new BYTE[bufferFrameCount*pwfx->nBlockAlign];

  return S_OK;
}
コード例 #4
0
HRESULT CBaseReferenceClock::AdviseThread()
{
    DWORD dwWait = INFINITE;

    // The first thing we do is wait until something interesting happens
    // (meaning a first advise or shutdown).  This prevents us calling
    // GetPrivateTime immediately which is goodness as that is a virtual
    // routine and the derived class may not yet be constructed.  (This
    // thread is created in the base class constructor.)

    while ( !m_bAbort )
    {
        // Wait for an interesting event to happen
        DbgLog((LOG_TIMING, 3, TEXT("CBaseRefClock::AdviseThread() Delay: %lu ms"), dwWait ));
        WaitForSingleObject(m_pSchedule->GetEvent(), dwWait);
        if (m_bAbort) break;

        // There are several reasons why we need to work from the internal
        // time, mainly to do with what happens when time goes backwards.
        // Mainly, it stop us looping madly if an event is just about to
        // expire when the clock goes backward (i.e. GetTime stop for a
        // while).
        const REFERENCE_TIME  rtNow = GetPrivateTime();

        DbgLog((LOG_TIMING, 3,
              TEXT("CBaseRefClock::AdviseThread() Woke at = %lu ms"),
              ConvertToMilliseconds(rtNow) ));

        // We must add in a millisecond, since this is the resolution of our
        // WaitForSingleObject timer.  Failure to do so will cause us to loop
        // franticly for (approx) 1 a millisecond.
        m_rtNextAdvise = m_pSchedule->Advise( 10000 + rtNow );
        LONGLONG llWait = m_rtNextAdvise - rtNow;

        ASSERT( llWait > 0 );

        llWait = ConvertToMilliseconds(llWait);
        // DON'T replace this with a max!! (The type's of these things is VERY important)
        dwWait = (llWait > REFERENCE_TIME(UINT_MAX)) ? UINT_MAX : DWORD(llWait);
    };
    return NOERROR;
}
コード例 #5
0
ファイル: SyncClock.cpp プロジェクト: BMOTech/MediaPortal-1
REFERENCE_TIME CSyncClock::GetPrivateTime()
{
  UINT64 qpcNow = GetCurrentTimestamp();

  UINT64 hwClock = 0;
  UINT64 hwQpc = 0;
  INT64 delta = 0;
  INT64 qpcDelta = 0;

  HRESULT hr = S_FALSE;

  //UINT64 start1 = GetCurrentTimestamp();

  if (m_pSettings->m_bHWBasedRefClock)
    hr = m_pAudioRenderer->AudioClock(hwClock, hwQpc, qpcNow);

  //UINT64 end1 = GetCurrentTimestamp();

  if (hr == S_OK)
  {
    if (m_clockSource != HW)
    {
      Log("Using HW clock");
      m_clockSource = HW;
    }
    
    if (m_ullStartQpcHW == 0)
    {
      m_ullStartQpcHW = hwQpc;
      m_ullStartTimeSystem = qpcNow;
    }

    if (m_ullStartTimeHW == 0)
    {
      m_ullStartTimeHW = hwClock;
      m_ullPrevSystemTime = qpcNow;
    }

    qpcDelta = qpcNow - m_ullPrevSystemTime;

    m_llDurationHW = (hwClock - m_ullStartTimeHW);
    m_llDurationSystem = (qpcNow - m_ullStartTimeSystem); 

    if (m_bDiscontinuity)
    {
      m_ullStartTimeHW = m_ullPrevTimeHW = hwClock;
      m_ullStartQpcHW = m_ullPrevQpcHW = hwQpc;
      m_ullStartTimeSystem = qpcNow;
      delta = qpcNow - m_ullPrevSystemTime;

      m_bDiscontinuity = false;
    }
    else
    {
      delta = hwClock - m_ullPrevTimeHW;
	  
      m_ullPrevTimeHW = hwClock;
      m_ullPrevQpcHW = hwQpc;
    }
  }
  else
  {
    if (m_clockSource != SYSTEM)
    {
      Log("Using SYSTEM clock");
      m_clockSource = SYSTEM;
    }

    if (m_ullPrevSystemTime == 0)
    {
      m_ullPrevSystemTime = qpcNow;
      m_ullStartTimeSystem = qpcNow;
    }

    qpcDelta = delta = qpcNow - m_ullPrevSystemTime;
    
    if (m_ullStartTimeSystem == 0)
      m_ullStartTimeSystem = qpcNow;

    if (m_ullPrevSystemTime == 0)
      m_ullPrevSystemTime = qpcNow;
  }

  if (qpcNow < m_ullPrevSystemTime)
    delta += REFERENCE_TIME(ULLONG_MAX) + 1;

  m_ullPrevSystemTime = qpcNow;

  //UINT64 start2 = GetCurrentTimestamp();
  INT64 synchCorrectedDelta = m_SynchCorrection.GetCorrectedTimeDelta(delta, m_ullHWPrivateTime, m_ullPrivateTime);
  //UINT64 end2 = GetCurrentTimestamp();

  //Log("diff %I64d delta: %I64d synchCorrectedDelta: %I64d qpc based delta: %I64d", delta - synchCorrectedDelta, delta, synchCorrectedDelta, qpcDelta);

  m_ullHWPrivateTime = m_ullHWPrivateTime + delta;
  m_ullPrivateTime = m_ullPrivateTime + synchCorrectedDelta;

  //UINT64 qpcEnd = GetCurrentTimestamp();

  /*if (qpcEnd - qpcNow > 2000)
    Log("DUR: %I64d first: %I64d second: %I64d", qpcEnd - qpcNow, end1 - start1, end2 - start2);
  */

  return m_ullPrivateTime;
}
コード例 #6
0
ファイル: HdmvClipInfo.cpp プロジェクト: Tphive/mpc-be
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());
}
コード例 #7
0
ファイル: HdmvClipInfo.cpp プロジェクト: Tphive/mpc-be
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());
}
コード例 #8
0
ファイル: HdmvClipInfo.cpp プロジェクト: Tphive/mpc-be
HRESULT CHdmvClipInfo::ReadCpiInfo(CAtlArray<SyncPoint>* sps)
{
	sps->RemoveAll();

	CAtlArray<ClpiEpMapEntry> ClpiEpMapList;

	LARGE_INTEGER Pos = {0, 0};
	Pos.QuadPart = Cpi_start_addrress;
	SetFilePointerEx(m_hFile, Pos, NULL, FILE_BEGIN);

	DWORD len = ReadDword();
	if (len == 0) {
		return E_FAIL;
	}

	BYTE* buf = NULL;

	ReadByte();
	BYTE Type = ReadByte() & 0xF;
	DWORD ep_map_pos = Cpi_start_addrress + 4 + 2;
	ReadByte();
	BYTE num_stream_pid = ReadByte();

	DWORD size = num_stream_pid * 12;
	buf = DNew BYTE[size];
	ReadBuffer(buf, size);
	CGolombBuffer gb(buf, size);
	for (int i = 0; i < num_stream_pid; i++) {
		ClpiEpMapEntry em;

		em.pid						= gb.ReadShort();
		gb.BitRead(10);
		em.ep_stream_type			= gb.BitRead(4);
		em.num_ep_coarse			= gb.ReadShort();
		em.num_ep_fine				= gb.BitRead(18);
		em.ep_map_stream_start_addr	= gb.ReadDword() + ep_map_pos;

		em.coarse					= DNew ClpiEpCoarse[em.num_ep_coarse];
		em.fine						= DNew ClpiEpFine[em.num_ep_fine];

		ClpiEpMapList.Add(em);
	}
	delete[] buf;

	for (int i = 0; i < num_stream_pid; i++) {
		ClpiEpMapEntry* em = &ClpiEpMapList[i];

		Pos.QuadPart = em->ep_map_stream_start_addr;
		SetFilePointerEx(m_hFile, Pos, NULL, FILE_BEGIN);
		DWORD fine_start = ReadDword();

		size = em->num_ep_coarse * 8;
		buf = DNew BYTE[size];
		ReadBuffer(buf, size);
		gb.Reset(buf, size);

		for (int j = 0; j < em->num_ep_coarse; j++) {
			em->coarse[j].ref_ep_fine_id	= gb.BitRead(18);
			em->coarse[j].pts_ep			= gb.BitRead(14);
			em->coarse[j].spn_ep			= gb.ReadDword();
		}
		delete[] buf;

		Pos.QuadPart = em->ep_map_stream_start_addr+fine_start;
		SetFilePointerEx(m_hFile, Pos, NULL, FILE_BEGIN);

		size = em->num_ep_fine * 4;
		buf = DNew BYTE[size];
		ReadBuffer(buf, size);
		gb.Reset(buf, size);

		for (int j = 0; j < em->num_ep_fine; j++) {
			em->fine[j].is_angle_change_point	= gb.BitRead(1);
			em->fine[j].i_end_position_offset	= gb.BitRead(3);
			em->fine[j].pts_ep					= gb.BitRead(11);
			em->fine[j].spn_ep					= gb.BitRead(17);
		}
		delete[] buf;
	}

	if (ClpiEpMapList.GetCount() > 0) {
		const ClpiEpMapEntry* entry = &ClpiEpMapList[0];
		for (int i = 0; i < entry->num_ep_coarse; i++) {
			int start, end;

			const ClpiEpCoarse* coarse = &entry->coarse[i];
			start = coarse->ref_ep_fine_id;
			if (i < entry->num_ep_coarse - 1) {
				end = entry->coarse[i+1].ref_ep_fine_id;
			} else {
				end = entry->num_ep_fine;
			}

			for (int j = start; j < end; j++) {
				ClpiEpFine* fine = &entry->fine[j];
				uint64 pts = ((uint64)(coarse->pts_ep & ~0x01) << 18) +
							 ((uint64)fine->pts_ep << 8);
				uint32 spn = (coarse->spn_ep & ~0x1FFFF) + fine->spn_ep;

				SyncPoint sp = {REFERENCE_TIME(20000.0f*pts/90), (__int64)spn * 192};
				sps->Add(sp);
			}
		}
	}

	for (size_t ii = 0; ii < ClpiEpMapList.GetCount(); ii++) {
		delete[] ClpiEpMapList[ii].coarse;
		delete[] ClpiEpMapList[ii].fine;
	}

	ClpiEpMapList.RemoveAll();

	return S_OK;
}