HRESULT CLAVSplitterTrayIcon::ProcessMenuCommand(HMENU hMenu, int cmd) { CheckPointer(m_pFilter, E_FAIL); DbgLog((LOG_TRACE, 10, L"Menu Command %d", cmd)); if (cmd >= STREAM_CMD_OFFSET && cmd < m_NumStreams + STREAM_CMD_OFFSET) { IAMStreamSelect *pStreamSelect = nullptr; if (SUCCEEDED(m_pFilter->QueryInterface(&pStreamSelect))) { pStreamSelect->Enable(cmd - STREAM_CMD_OFFSET, AMSTREAMSELECTENABLE_ENABLE); SafeRelease(&pStreamSelect); } } else if (cmd > CHAPTER_CMD_OFFSET && cmd <= m_NumChapters + CHAPTER_CMD_OFFSET) { IAMExtendedSeeking *pExSeeking = nullptr; if (SUCCEEDED(m_pFilter->QueryInterface(IID_IAMExtendedSeeking, (void **)&pExSeeking))) { double markerTime; if (FAILED(pExSeeking->GetMarkerTime(cmd - CHAPTER_CMD_OFFSET, &markerTime))) goto failchapterseek; REFERENCE_TIME rtMarkerTime = (REFERENCE_TIME)(markerTime * 10000000.0); // Try to get the graph to seek on, its much safer than directly trying to seek on LAV FILTER_INFO info; if (FAILED(m_pFilter->QueryFilterInfo(&info)) || !info.pGraph) goto failchapterseek; IMediaSeeking *pSeeking = nullptr; if (SUCCEEDED(info.pGraph->QueryInterface(&pSeeking))) { pSeeking->SetPositions(&rtMarkerTime, AM_SEEKING_AbsolutePositioning, nullptr, AM_SEEKING_NoPositioning); SafeRelease(&pSeeking); } SafeRelease(&info.pGraph); failchapterseek: SafeRelease(&pExSeeking); } } else if (cmd == STREAM_CMD_OFFSET - 1) { OpenPropPage(); } else { return E_UNEXPECTED; } return S_OK; }
bool MiniPlayer::prepare(LPCTSTR filename) { if(fail()) return false; HRESULT hr = _mediaCtrl->Stop(); IBaseFilter *pFileSrc = NULL; hr = _filterGraph->FindFilterByName(L"Media File", &pFileSrc); if(hr == S_OK) { hr = _filterGraph->RemoveFilter(pFileSrc); IF_REL(pFileSrc); } hr = _filterGraph->AddSourceFilter(filename, L"Media File", &pFileSrc); IF_CHK(hr, _T("Unable to add Source Filter for file: %s"), filename); IPin *pFileOutputPin = NULL; hr = findPin(pFileSrc, PINDIR_OUTPUT, &pFileOutputPin); IF_CHK(hr, "Unable to find output pin of File Source Filter."); hr = _filterGraph->Connect(pFileOutputPin, _splitterInputPin); IF_CHK(hr, "Unable to connect File Source Output Pin & Splitter Input Pin"); IPin *pSplitterVideoOutputPin = NULL; IPin *pSplitterAudioOutputPin = NULL; IPin *pVideoDecoderOutputPin = NULL; IPin *pAudioDecoderOutputPin = NULL; //listAllPins(_splitter); hr = findPin(_splitter, PINDIR_OUTPUT, MEDIATYPE_Video, &pSplitterVideoOutputPin); if(hr == S_OK) { hr = _filterGraph->Connect(pSplitterVideoOutputPin, _videoDecoderInputPin); } hr = findPin(_splitter, PINDIR_OUTPUT, MEDIATYPE_Audio, &pSplitterAudioOutputPin); if(hr == S_OK) { hr = _filterGraph->Connect(pSplitterAudioOutputPin, _audioDecoderInputPin); } //listAllPins(_videoDecoder); hr = findPin(_videoDecoder, PINDIR_OUTPUT, &pVideoDecoderOutputPin); if(hr == S_OK) { hr = _filterGraph->Render(pVideoDecoderOutputPin); } //listAllPins(_audioDecoder); hr = findPin(_audioDecoder, PINDIR_OUTPUT, &pAudioDecoderOutputPin); if(hr == S_OK) { hr = _filterGraph->Render(pAudioDecoderOutputPin); } IID IID_ITrackInfo; IIDFromString(L"{03E98D51-DDE7-43aa-B70C-42EF84A3A23D}", &IID_ITrackInfo); ITrackInfo *pTrackInfo; hr = _splitter->QueryInterface(IID_ITrackInfo, (void **)&pTrackInfo); IAMStreamSelect *pAudioSel; hr = _splitter->QueryInterface(IID_IAMStreamSelect, (void **)&pAudioSel); hr = pAudioSel->Enable(2, AMSTREAMSELECTENABLE_ENABLE); ctrace("Track Info:\n"); ctrace(" Track Count: %d\n", pTrackInfo->GetTrackCount()); for(UINT i = 0; i < pTrackInfo->GetTrackCount(); i++) { TrackElement elem; TrackExtendedInfoVideo videoInfo; TrackExtendedInfoAudio audioInfo; pTrackInfo->GetTrackInfo(i, &elem); ctrace("\t [%d] ", i); switch(elem.Type) { case TypeVideo: pTrackInfo->GetTrackExtendedInfo(i, &videoInfo); ctrace("Video %dx%d", videoInfo.PixelWidth, videoInfo.PixelHeight); break; case TypeAudio: pTrackInfo->GetTrackExtendedInfo(i, &audioInfo); ctrace("Audio %d Channels", audioInfo.Channels); break; case TypeSubtitle: ctrace("Subtitle "); break; } ctrace("\n"); } _fail = false; return true; Cleanup: return (_fail = true); }
HMENU CLAVSplitterTrayIcon::GetPopupMenu() { CheckPointer(m_pFilter, nullptr); CPopupMenu menu; IAMStreamSelect *pStreamSelect = nullptr; if (SUCCEEDED(m_pFilter->QueryInterface(&pStreamSelect))) { DWORD dwStreams = 0; if (FAILED(pStreamSelect->Count(&dwStreams))) dwStreams = 0; DWORD dwLastGroup = DWORD_MAX; for (DWORD i = 0; i < dwStreams; i++) { DWORD dwFlags = 0, dwGroup = 0; LPWSTR pszName = nullptr; if (FAILED(pStreamSelect->Info(i, nullptr, &dwFlags, nullptr, &dwGroup, &pszName, nullptr, nullptr))) continue; if (dwGroup != dwLastGroup) { switch (dwGroup) { case 0: menu.AddItem(dwGroup, L"Video", FALSE, FALSE); break; case 1: menu.AddItem(dwGroup, L"Audio", FALSE, FALSE); break; case 2: menu.AddItem(dwGroup, L"Subtitles", FALSE, FALSE); break; case 18: menu.AddItem(dwGroup, L"Editions", FALSE, FALSE); break; default: menu.AddSeparator(); break; } dwLastGroup = dwGroup; } menu.AddItem(STREAM_CMD_OFFSET + i, pszName, dwFlags & AMSTREAMSELECTINFO_ENABLED); CoTaskMemFree(pszName); } if (dwStreams) menu.AddSeparator(); m_NumStreams = dwStreams; SafeRelease(&pStreamSelect); } // Chapters IAMExtendedSeeking *pExSeeking = nullptr; if (SUCCEEDED(m_pFilter->QueryInterface(IID_IAMExtendedSeeking, (void **)&pExSeeking))) { long count = 0, current = 0; if (FAILED(pExSeeking->get_MarkerCount(&count))) count = 0; if (FAILED(pExSeeking->get_CurrentMarker(¤t))) current = 0; CPopupMenu chapters; for (long i = 1; i <= count; i++) { double markerTime; if (FAILED(pExSeeking->GetMarkerTime(i, &markerTime))) continue; BSTR bstrName = nullptr; if (FAILED(pExSeeking->GetMarkerName(i, &bstrName))) continue; // Create compound chapter name int total_seconds = (int)(markerTime + 0.5); int seconds = total_seconds % 60; int minutes = total_seconds / 60 % 60; int hours = total_seconds / 3600; WCHAR chapterName[512]; _snwprintf_s(chapterName, _TRUNCATE, L"%s\t[%02d:%02d:%02d]", bstrName, hours, minutes, seconds); // Sanitize any tab chars in the chapter name (replace by space) // More then one tab in the string messes with the popup menu rendering WCHAR *nextMatch, *tabMatch = wcsstr(chapterName, L"\t"); while (nextMatch = wcsstr(tabMatch+1, L"\t")) { *tabMatch = L' '; tabMatch = nextMatch; } chapters.AddItem(CHAPTER_CMD_OFFSET + i, chapterName, i == current); SysFreeString(bstrName); } if (count) { menu.AddSubmenu(chapters.Finish(), L"Chapters"); menu.AddSeparator(); } m_NumChapters = count; SafeRelease(&pExSeeking); } menu.AddItem(STREAM_CMD_OFFSET - 1, L"Properties"); HMENU hMenu = menu.Finish(); return hMenu; }