Changeset 441


Ignore:
Timestamp:
May 18, 2015, 10:11:11 AM (8 years ago)
Author:
roman
Message:

Added filtering in media sample trace UI; fixed thread safety problem; fixed file mapping initialization issue; removed media sample leak feature (to extend file mapping lifetime) and replaced with file mapping ownership transfer to UI process; added menu item to jump right to filter graph

Location:
trunk/DirectShowSpy
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/DirectShowSpy/FilterGraphList.h

    r432 r441  
    249249                        return ((CListPropertyPage*) nParameter)->SortGraphListViewItems(nItemParameter1, nItemParameter2);
    250250                }
    251                 VOID Refresh()
    252                 {
    253                         CRoMapT<CStringW, CItem> ItemMap;
    254                         #pragma region Enumerate
     251                static VOID EnumerateItems(IRunningObjectTable* pRunningObjectTable, CRoMapT<CStringW, CItem>& ItemMap, const LONG* pnProcessIdentifier = NULL)
     252                {
     253                        _A(pRunningObjectTable);
     254                        _A(ItemMap.IsEmpty());
    255255                        _ATLTRY
    256256                        {
    257                                 LONG nProcessIdentifier;
    258                                 const BOOL bProcessIdentifierAvailable = m_PropertySheet.m_Options.TryGetLongValue(_T("FilterGraphListPropertySheet.ProcessIdentifier"), nProcessIdentifier);
    259                                 if(!m_pRunningObjectTable)
    260                                         __C(GetRunningObjectTable(0, &m_pRunningObjectTable));
    261257                                CComPtr<IEnumMoniker> pEnumMoniker;
    262                                 __C(m_pRunningObjectTable->EnumRunning(&pEnumMoniker));
     258                                __C(pRunningObjectTable->EnumRunning(&pEnumMoniker));
    263259                                CComPtr<IMalloc> pMalloc;
    264260                                __C(CoGetMalloc(1, &pMalloc));
     
    288284                                                        Item.m_sTime = CString(MatchContext.GetMatchString(3));
    289285                                                        Item.m_sTime.Replace(_T("-"), _T(":"));
    290                                                         if(bProcessIdentifierAvailable && Item.m_nProcessIdentifier != (DWORD) nProcessIdentifier)
     286                                                        if(pnProcessIdentifier && Item.m_nProcessIdentifier != (DWORD) *pnProcessIdentifier)
    291287                                                                continue; // Skip
    292288                                                        _W(ItemMap.SetAt(sDisplayName, Item) >= 0);
     
    303299                                _Z_EXCEPTION();
    304300                        }
    305                         #pragma endregion
     301                }
     302                VOID Refresh()
     303                {
     304                        if(!m_pRunningObjectTable)
     305                                __C(GetRunningObjectTable(0, &m_pRunningObjectTable));
     306                        LONG nProcessIdentifier;
     307                        const BOOL bProcessIdentifierAvailable = m_PropertySheet.m_Options.TryGetLongValue(_T("FilterGraphListPropertySheet.ProcessIdentifier"), nProcessIdentifier);
     308                        CRoMapT<CStringW, CItem> ItemMap;
     309                        EnumerateItems(m_pRunningObjectTable, ItemMap, bProcessIdentifierAvailable ? &nProcessIdentifier : NULL);
    306310                        CWindowRedraw GraphListViewRedraw(m_GraphListView);
    307311                        BOOL bSortNeeded = FALSE;
  • trunk/DirectShowSpy/FilterGraphSpy.h

    r440 r441  
    230230// CSpyT
    231231
    232 LPCTSTR g_pszAddRemoveHookName = _T("Add/Remove Hooks");
    233 LPCTSTR g_pszConnectHookName = _T("Connect Hooks");
    234 LPCTSTR g_pszStateControlHookName = _T("State Control Hooks");
     232extern LPCTSTR g_pszAddRemoveHookName;
     233extern LPCTSTR g_pszConnectHookName;
     234extern LPCTSTR g_pszStateControlHookName;
     235
     236__declspec(selectany) LPCTSTR g_pszAddRemoveHookName = _T("Add/Remove Hooks");
     237__declspec(selectany) LPCTSTR g_pszConnectHookName = _T("Connect Hooks");
     238__declspec(selectany) LPCTSTR g_pszStateControlHookName = _T("State Control Hooks");
    235239
    236240template <typename T, const CLSID* t_pFilterGraphClassIdentifier>
  • trunk/DirectShowSpy/Helper.cpp

    r440 r441  
    232232                FilterGraph.CoCreateInstance();
    233233                const CComPtr<IBaseFilter> pSourceBaseFilter = FilterGraph.AddSourceFilter(
    234                         //_T("E:\\Media\\Robotica_1080.wmv")
    235                         _T("E:\\Media\\Windows Phone - Design for Developers.mp4")
     234                        _T("E:\\Media\\Robotica_1080.wmv")
     235                        //_T("E:\\Media\\Windows Phone - Design for Developers.mp4")
    236236                        );
    237237                CComPtr<IPin> pOutputPin = _FilterGraphHelper::GetFilterPin(pSourceBaseFilter, PINDIR_OUTPUT);
    238                 if(TRUE)
     238                if(FALSE)
    239239                {
    240240                        class __declspec(uuid("{025BE2E4-1787-4DA4-A585-C5B2B9EEB57C}")) Demultiplexer;
  • trunk/DirectShowSpy/MediaSampleTrace.h

    r440 r441  
    2020#include "Common.h"
    2121#include "FilterGraphHelper.h"
     22#include "FilterGraphList.h"
    2223
    2324////////////////////////////////////////////////////////////
     
    186187
    187188        ////////////////////////////////////////////////////////
     189        // CHandleMap
     190
     191        class CHandleMap :
     192                protected CRoMapT<CString, HANDLE>
     193        {
     194        protected:
     195                mutable CRoCriticalSection m_DataCriticalSection;
     196
     197        public:
     198        // CHandleMap
     199                CHandleMap()
     200                {
     201                }
     202                ~CHandleMap()
     203                {
     204                        RemoveAll();
     205                }
     206                VOID Add(const CString& sName, HANDLE hValue)
     207                {
     208                        CRoCriticalSectionLock DataLock(m_DataCriticalSection);
     209                        if(Lookup(sName))
     210                                return;
     211                        CHandle PrivateValue;
     212                        if(!DuplicateHandle(GetCurrentProcess(), hValue, GetCurrentProcess(), &PrivateValue.m_h, 0, FALSE, DUPLICATE_SAME_ACCESS))
     213                                return;
     214                        _W(SetAt(sName, PrivateValue.Detach()));
     215                }
     216                VOID RemoveAll()
     217                {
     218                        CRoCriticalSectionLock DataLock(m_DataCriticalSection);
     219                        for(auto&& hValue: GetValues())
     220                                reinterpret_cast<CHandle&>(hValue).Close();
     221                        __super::RemoveAll();
     222                }
     223        };
     224
     225        ////////////////////////////////////////////////////////
    188226        // CPages
    189227
     
    222260                        return AtlFormatString(_T("DirectShowSpy.MediaSamplePage.%08X.%08X"), nProcessIdentifier, nPageIdentifier);
    223261                }
     262                static VOID InitializeFileMapping(CAtlFileMapping<HEADER>& FileMapping)
     263                {
     264                        HEADER* pHeader = FileMapping;
     265                        pHeader->nCapacity = (UINT32) GetFileMappingCapacity();
     266                        pHeader->nFlags = HEADERFLAGS_NONE;
     267                        pHeader->nVersion = 0;
     268                        pHeader->nItemCount = 0;
     269                }
    224270                BOOL Initialize(BOOL bCreate = FALSE)
    225271                {
     
    244290                                //CMutexLock MutexLock(m_Mutex);
    245291                                __C(m_FileMapping.MapSharedMem(GetFileMappingCapacity(), GetFileMappingName()));
     292                                HEADER* pHeader = m_FileMapping;
     293                                if(!pHeader->nCapacity)
     294                                        InitializeFileMapping(m_FileMapping);
    246295                        }
    247296                        return TRUE;
    248297                }
    249                 VOID GetData(CData& Data)
     298                VOID GetData(CData& Data, CHandleMap* pHandleMap = NULL)
    250299                {
    251300                        _A(m_Mutex && m_FileMapping);
     301                        if(pHandleMap)
     302                        {
     303                                pHandleMap->Add(GetMutexName(), m_Mutex);
     304                                pHandleMap->Add(GetFileMappingName(), m_FileMapping.GetHandle());
     305                        }
    252306                        Data.Initialize();
    253307                        CMutexLock MutexLock(m_Mutex);
     
    262316                                {
    263317                                        CMutex PageMutex;
    264                                         __E(PageMutex.Open(MUTEX_ALL_ACCESS, FALSE, GetPageMutexName(pItem->nProcessIdentifier, pItem->nPageIdentifier)));
     318                                        const CString sMutexName = GetPageMutexName(pItem->nProcessIdentifier, pItem->nPageIdentifier);
     319                                        __E(PageMutex.Open(MUTEX_ALL_ACCESS, FALSE, sMutexName));
    265320                                        CAtlFileMapping<PAGEHEADER> PageFileMapping;
    266                                         __C(PageFileMapping.OpenMapping(GetPageFileMappingName(pItem->nProcessIdentifier, pItem->nPageIdentifier), GetPageFileMappingCapacity()));
     321                                        const CString sFileMappingName = GetPageFileMappingName(pItem->nProcessIdentifier, pItem->nPageIdentifier);
     322                                        __C(PageFileMapping.OpenMapping(sFileMappingName, GetPageFileMappingCapacity()));
     323                                        if(pHandleMap)
     324                                        {
     325                                                pHandleMap->Add(sMutexName, PageMutex);
     326                                                pHandleMap->Add(sFileMappingName, PageFileMapping.GetHandle());
     327                                        }
    267328                                        PAGEHEADER* pPageHeader = PageFileMapping;
    268329                                        CMutexLock MutexLock(PageMutex);
     
    310371                        HEADER* pHeader = m_FileMapping;
    311372                        if(!pHeader->nCapacity)
    312                         {
    313                                 _A(!bOpen);
    314                                 pHeader->nCapacity = (UINT32) GetFileMappingCapacity();
    315                                 pHeader->nFlags = HEADERFLAGS_NONE;
    316                                 pHeader->nVersion = 0;
    317                                 pHeader->nItemCount = 0;
    318                         } else
    319                                 _A(bOpen);
     373                                InitializeFileMapping(m_FileMapping);
    320374                        #if defined(_DEBUG)
    321375                                _Z4(atlTraceGeneral, 4, _T("File mapping size %d, item size %d, item capacity %d\n"), GetFileMappingCapacity(), sizeof (ITEM), (GetFileMappingCapacity() - sizeof (HEADER)) / sizeof (ITEM));
     
    416470        public:
    417471        // CPage
     472                BOOL IsEmpty() const
     473                {
     474                        return m_ItemList.IsEmpty();
     475                }
    418476                VOID Register(CPages& Pages, UINT64 nFilterIdentifier, const CStringW& sFilterName, LPCWSTR pszStreamName, const PAGEITEM& PageItem, LPCWSTR pszComment)
    419477                {
     
    480538{
    481539public:
    482         //enum { IDR = IDR_MediaSampleTrace };
     540        //enum { IDR = IDR_MEDIASAMPLETRACE };
    483541
    484542DECLARE_NO_REGISTRY() //DECLARE_REGISTRY_RESOURCEID(IDR)
     
    493551
    494552private:
    495         //mutable CRoCriticalSection m_DataCriticalSection;
     553        mutable CRoCriticalSection m_DataCriticalSection;
    496554        UINT_PTR m_nFilterGraphIdentifier;
    497555        CStringW m_sFilterGraphName;
     
    508566        {
    509567                _Z4_THIS();
     568                #pragma region Transfer Ownership
     569                if(!m_Page.IsEmpty())
     570                {
     571                        CEvent RequestEvent, ResponseEvent;
     572                        if(RequestEvent.Open(EVENT_ALL_ACCESS, FALSE, CString(CPages::GetFileMappingName()) + _T(".TransferRequest")))
     573                        {
     574                                ResponseEvent.Open(EVENT_ALL_ACCESS, FALSE, CString(CPages::GetFileMappingName()) + _T(".TransferResponse"));
     575                                if(RequestEvent.Set())
     576                                {
     577                                        // NOTE: The event creator (UI) has some time to grap mapping handles and store a private copy
     578                                        static const ULONG g_nTimeoutTime = 500; // 500 ms
     579                                        if(ResponseEvent)
     580                                        {
     581                                                const DWORD nWaitResult = WaitForSingleObject(ResponseEvent, g_nTimeoutTime);
     582                                                _Z5_WAITRESULT(nWaitResult);
     583                                        } else
     584                                                Sleep(g_nTimeoutTime);
     585                                }
     586                        }
     587                }
     588                #pragma endregion
    510589        }
    511590        VOID Initialize(ISpy* pSpy)
     
    516595                const CComQIPtr<IFilterGraph2> pFilterGraph2 = pSpy;
    517596                _A(pFilterGraph2);
    518                 //CRoCriticalSectionLock DataLock(m_DataCriticalSection);
     597                CRoCriticalSectionLock DataLock(m_DataCriticalSection);
    519598                m_nFilterGraphIdentifier = (UINT_PTR) (IFilterGraph2*) pFilterGraph2;
    520599                m_sFilterGraphName = CStringW(sName);
    521600                m_Pages.Initialize((UINT64) m_nFilterGraphIdentifier, m_sFilterGraphName);
    522                 // NOTE: We might prefer to let the pages leak away to outlive the filter graph itself...
    523                 AddRef();
    524601        }
    525602        static CStringW GetFilterName(IUnknown* pBaseFilterUnknown)
     
    543620                        PageItem.Data.NewSegment.nStopTime = nStopTime;
    544621                        PageItem.Data.NewSegment.fRate = fRate;
     622                        CRoCriticalSectionLock DataLock(m_DataCriticalSection);
    545623                        m_Page.Register(m_Pages, (UINT_PTR) pBaseFilterUnknown, GetFilterName(pBaseFilterUnknown), pszStreamName, PageItem, pszComment);
    546624                }
     
    560638                        PageItem.nFlags = PAGEITEMFLAG_MEDIASAMPLE;
    561639                        PageItem.Data.MediaSample.Properties = *((const AM_SAMPLE2_PROPERTIES*) pnSamplePropertiesData);
     640                        CRoCriticalSectionLock DataLock(m_DataCriticalSection);
    562641                        m_Page.Register(m_Pages, (UINT_PTR) pBaseFilterUnknown, GetFilterName(pBaseFilterUnknown), pszStreamName, PageItem, pszComment);
    563642                }
     
    575654                        PAGEITEM PageItem;
    576655                        PageItem.nFlags = PAGEITEMFLAG_ENDOFSTREAM;
     656                        CRoCriticalSectionLock DataLock(m_DataCriticalSection);
    577657                        m_Page.Register(m_Pages, (UINT_PTR) pBaseFilterUnknown, GetFilterName(pBaseFilterUnknown), pszStreamName, PageItem, pszComment);
    578658                }
     
    590670                        PAGEITEM PageItem;
    591671                        PageItem.nFlags = PAGEITEMFLAG_COMMENT;
     672                        CRoCriticalSectionLock DataLock(m_DataCriticalSection);
    592673                        m_Page.Register(m_Pages, (UINT_PTR) pBaseFilterUnknown, GetFilterName(pBaseFilterUnknown), pszStreamName, PageItem, pszComment);
    593674                }
     
    626707                public CDialogResize<CMediaSamplePropertyPage>
    627708        {
     709                typedef CThreadT<CMediaSamplePropertyPage> CThread;
     710
    628711        public:
    629712                enum { IDD = IDD_MEDIASAMPLETRACE_MEDIASAMPLE_PROPERTYPAGE };
     
    634717                CHAIN_MSG_MAP(CDialogResize<CMediaSamplePropertyPage>)
    635718                MSG_WM_INITDIALOG(OnInitDialog)
     719                MSG_WM_DESTROY(OnDestroy)
    636720                MSG_LVN_GETDISPINFO(IDC_MEDIASAMPLETRACE_MEDIASAMPLE_LIST, OnListViewGetDispInfo)
    637721                MSG_LVN_GETINFOTIP(IDC_MEDIASAMPLETRACE_MEDIASAMPLE_LIST, OnListViewGetInfoTip)
     
    642726                COMMAND_ID_HANDLER_EX(IDC_MEDIASAMPLETRACE_MEDIASAMPLE_RESETDATA, OnResetData)
    643727                COMMAND_ID_HANDLER_EX(IDC_MEDIASAMPLETRACE_MEDIASAMPLE_OPENFILTERGRAPHLIST, OnOpenFilterGraphList)
     728                COMMAND_ID_HANDLER_EX(IDC_MEDIASAMPLETRACE_MEDIASAMPLE_OPENFILTERGRAPHPROPERTIES, OnOpenFilterGraphProperties)
    644729                REFLECT_NOTIFICATIONS()
    645730        END_MSG_MAP()
     
    647732        BEGIN_DLGRESIZE_MAP(CMediaSamplePropertyPage)
    648733                DLGRESIZE_CONTROL(IDC_MEDIASAMPLETRACE_MEDIASAMPLE_INTRODUCTION, DLSZ_SIZE_X)
     734                DLGRESIZE_CONTROL(IDD_MEDIASAMPLETRACE_MEDIASAMPLE_FILTER, DLSZ_SIZE_X)
    649735                DLGRESIZE_CONTROL(IDC_MEDIASAMPLETRACE_MEDIASAMPLE_LIST, DLSZ_SIZE_X | DLSZ_SIZE_Y)
    650736                DLGRESIZE_CONTROL(IDC_MEDIASAMPLETRACE_MEDIASAMPLE_REFRESH, DLSZ_MOVE_Y)
     
    652738                DLGRESIZE_CONTROL(IDC_MEDIASAMPLETRACE_MEDIASAMPLE_SAVETOFILE, DLSZ_MOVE_Y)
    653739        END_DLGRESIZE_MAP()
     740
     741        public:
     742
     743                ////////////////////////////////////////////////////
     744                // CFilterDialog
     745
     746                class CFilterDialog :
     747                        public CDialogImpl<CFilterDialog>,
     748                        public CDialogResize<CFilterDialog>
     749                {
     750                public:
     751                        enum { IDD = IDD_MEDIASAMPLETRACE_MEDIASAMPLE_FILTER };
     752
     753                BEGIN_MSG_MAP_EX(CFilterDialog)
     754                        //CHAIN_MSG_MAP(CFilterDialog)
     755                        CHAIN_MSG_MAP(CDialogResize<CFilterDialog>)
     756                        MSG_WM_INITDIALOG(OnInitDialog)
     757                        COMMAND_HANDLER_EX(IDC_MEDIASAMPLETRACE_MEDIASAMPLE_FILTER_PROCESS, CBN_SELENDOK, OnProcessComboBoxSelEndOk)
     758                        COMMAND_HANDLER_EX(IDC_MEDIASAMPLETRACE_MEDIASAMPLE_FILTER_FILTERGRAPH, CBN_SELENDOK, OnFilterGraphComboBoxSelEndOk)
     759                        COMMAND_HANDLER_EX(IDC_MEDIASAMPLETRACE_MEDIASAMPLE_FILTER_FILTER, CBN_SELENDOK, OnFilterComboBoxSelEndOk)
     760                        COMMAND_HANDLER_EX(IDC_MEDIASAMPLETRACE_MEDIASAMPLE_FILTER_STREAM, CBN_SELENDOK, OnStreamComboBoxSelEndOk)
     761                        REFLECT_NOTIFICATIONS()
     762                END_MSG_MAP()
     763
     764                BEGIN_DLGRESIZE_MAP(CFilterDialog)
     765                        DLGRESIZE_CONTROL(IDC_MEDIASAMPLETRACE_MEDIASAMPLE_FILTER_PROCESS_TITLE, 0)
     766                        DLGRESIZE_CONTROL(IDC_MEDIASAMPLETRACE_MEDIASAMPLE_FILTER_PROCESS, 0) //DLSZ_SIZE_X)
     767                        DLGRESIZE_CONTROL(IDC_MEDIASAMPLETRACE_MEDIASAMPLE_FILTER_FILTERGRAPH_TITLE, 0)
     768                        DLGRESIZE_CONTROL(IDC_MEDIASAMPLETRACE_MEDIASAMPLE_FILTER_FILTERGRAPH, DLSZ_SIZE_X)
     769                        DLGRESIZE_CONTROL(IDC_MEDIASAMPLETRACE_MEDIASAMPLE_FILTER_FILTER_TITLE, 0)
     770                        DLGRESIZE_CONTROL(IDC_MEDIASAMPLETRACE_MEDIASAMPLE_FILTER_FILTER, DLSZ_SIZE_X)
     771                        DLGRESIZE_CONTROL(IDC_MEDIASAMPLETRACE_MEDIASAMPLE_FILTER_STREAM_TITLE, 0)
     772                        DLGRESIZE_CONTROL(IDC_MEDIASAMPLETRACE_MEDIASAMPLE_FILTER_STREAM, DLSZ_SIZE_X)
     773                END_DLGRESIZE_MAP()
     774
     775                public:
     776
     777                        ////////////////////////////////////////////////
     778                        // CValueT
     779
     780                        template <typename CIdentifier>
     781                        class CValueT
     782                        {
     783                        public:
     784                                CIdentifier m_nIdentifier;
     785                                CStringW m_sValue;
     786
     787                        public:
     788                        // CValueT
     789                                CValueT() :
     790                                        m_nIdentifier(0)
     791                                {
     792                                }
     793                                CValueT(CIdentifier nIdentifier, LPCWSTR pszValue = NULL) :
     794                                        m_nIdentifier(nIdentifier),
     795                                        m_sValue(pszValue)
     796                                {
     797                                }
     798                        };
     799
     800                        typedef CValueT<UINT32> CProcessValue;
     801                        typedef CValueT<UINT64> CFilterGraphValue;
     802                        typedef CValueT<UINT64> CFilterValue;
     803                        typedef CValueT<UINT> CStreamValue;
     804
     805                        class CProcessValueSortTraits :
     806                                public CSimpleSortTraitsT<CProcessValue>
     807                        {
     808                        public:
     809                        // CProcessValueSortTraits
     810                                static INT_PTR CompareElements(const CProcessValue& Element1, const CProcessValue& Element2, PARAMETERARGUMENT)
     811                                {
     812                                        return (INT_PTR) (Element1.m_nIdentifier - Element2.m_nIdentifier);
     813                                }
     814                        };
     815
     816                        class CFilterGraphValueSortTraits :
     817                                public CSimpleSortTraitsT<CFilterGraphValue>
     818                        {
     819                        public:
     820                        // CFilterGraphValueSortTraits
     821                                static INT_PTR CompareElements(const CFilterGraphValue& Element1, const CFilterGraphValue& Element2, PARAMETERARGUMENT)
     822                                {
     823                                        const INT nName = _wcsicmp(Element1.m_sValue, Element2.m_sValue);
     824                                        if(nName)
     825                                                return nName;
     826                                        return (INT_PTR) (Element1.m_nIdentifier - Element2.m_nIdentifier);
     827                                }
     828                        };
     829
     830                        class CFilterValueSortTraits :
     831                                public CSimpleSortTraitsT<CFilterValue>
     832                        {
     833                        public:
     834                        // CFilterValueSortTraits
     835                                static INT_PTR CompareElements(const CFilterValue& Element1, const CFilterValue& Element2, PARAMETERARGUMENT)
     836                                {
     837                                        const INT nName = _wcsicmp(Element1.m_sValue, Element2.m_sValue);
     838                                        if(nName)
     839                                                return nName;
     840                                        return (INT_PTR) (Element1.m_nIdentifier - Element2.m_nIdentifier);
     841                                }
     842                        };
     843
     844                        class CStreamValueSortTraits :
     845                                public CSimpleSortTraitsT<CStreamValue>
     846                        {
     847                        public:
     848                        // CStreamValueSortTraits
     849                                static INT_PTR CompareElements(const CStreamValue& Element1, const CStreamValue& Element2, PARAMETERARGUMENT)
     850                                {
     851                                        return _wcsicmp(Element1.m_sValue, Element2.m_sValue);
     852                                }
     853                        };
     854
     855                private:
     856                        CMediaSamplePropertyPage& m_Owner;
     857                        CRoComboBoxT<CProcessValue, CRoListControlDataTraitsT> m_ProcessComboBox;
     858                        CRoComboBoxT<CFilterGraphValue, CRoListControlDataTraitsT> m_FilterGraphComboBox;
     859                        CRoComboBoxT<CFilterValue, CRoListControlDataTraitsT> m_FilterComboBox;
     860                        CRoComboBoxT<CStreamValue, CRoListControlDataTraitsT> m_StreamComboBox;
     861                        CProcessValue* m_pProcessValue;
     862                        CFilterGraphValue* m_pFilterGraphValue;
     863                        CFilterValue* m_pFilterValue;
     864                        CStreamValue* m_pStreamValue;
     865
     866                public:
     867                // CFilterDialog
     868                        CFilterDialog(CMediaSamplePropertyPage* pOwner) :
     869                                m_Owner(*pOwner)
     870                        {
     871                        }
     872                        VOID UpdateProcessComboBox()
     873                        {
     874                                m_ProcessComboBox.ResetContent();
     875                                INT nItem = 0;
     876                                _W(m_ProcessComboBox.InsertString(nItem++, _T("<All Processes>")) == 0);
     877                                m_ProcessComboBox.SetCurSel(0);
     878                                CRoArrayT<UINT32> IdentifierArray;
     879                                CRoArrayT<CProcessValue> ValueArray;
     880                                for(auto&& Item: m_Owner.m_Data.m_ItemArray)
     881                                {
     882                                        if(IdentifierArray.FindFirst(Item.m_Item.nProcessIdentifier))
     883                                                continue;
     884                                        IdentifierArray.Add(Item.m_Item.nProcessIdentifier);
     885                                        ValueArray.Add(CProcessValue(Item.m_Item.nProcessIdentifier, AtlFormatStringW(L"%d", Item.m_Item.nProcessIdentifier)));
     886                                }
     887                                _SortHelper::QuickSort<CProcessValueSortTraits>(ValueArray);
     888                                for(auto&& Value: ValueArray)
     889                                        m_ProcessComboBox.InsertString(nItem++, Value.m_sValue, Value);
     890                                if(ValueArray.GetCount() == 1)
     891                                        m_ProcessComboBox.SetCurSel(1);
     892                                const BOOL bEnabled = m_ProcessComboBox.GetCount() > 2;
     893                                m_ProcessComboBox.GetWindow(GW_HWNDPREV).EnableWindow(bEnabled);
     894                                m_ProcessComboBox.EnableWindow(bEnabled);
     895                                OnProcessComboBoxSelEndOk();
     896                                UpdateFilterGraphComboBox();
     897                        }
     898                        VOID UpdateFilterGraphComboBox()
     899                        {
     900                                m_FilterGraphComboBox.ResetContent();
     901                                INT nItem = 0;
     902                                _W(m_FilterGraphComboBox.InsertString(nItem++, _T("<All Filter Graphs>")) == 0);
     903                                m_FilterGraphComboBox.SetCurSel(0);
     904                                CRoArrayT<UINT64> IdentifierArray;
     905                                CRoArrayT<CFilterGraphValue> ValueArray;
     906                                for(auto&& Item: m_Owner.m_Data.m_ItemArray)
     907                                {
     908                                        if(m_pProcessValue && m_pProcessValue->m_nIdentifier != Item.m_Item.nProcessIdentifier)
     909                                                continue;
     910                                        if(IdentifierArray.FindFirst(Item.m_Item.nFilterGraphIdentifier))
     911                                                continue;
     912                                        IdentifierArray.Add(Item.m_Item.nFilterGraphIdentifier);
     913                                        ValueArray.Add(CFilterGraphValue(Item.m_Item.nFilterGraphIdentifier, AtlFormatStringW(L"0x%p %ls", (UINT_PTR) Item.m_Item.nFilterGraphIdentifier, Item.m_Item.pszFilterGraphName)));
     914                                }
     915                                _SortHelper::QuickSort<CFilterGraphValueSortTraits>(ValueArray);
     916                                for(auto&& Value: ValueArray)
     917                                        m_FilterGraphComboBox.InsertString(nItem++, Value.m_sValue, Value);
     918                                if(ValueArray.GetCount() == 1)
     919                                        m_FilterGraphComboBox.SetCurSel(1);
     920                                const BOOL bEnabled = m_FilterGraphComboBox.GetCount() > 2;
     921                                m_FilterGraphComboBox.GetWindow(GW_HWNDPREV).EnableWindow(bEnabled);
     922                                m_FilterGraphComboBox.EnableWindow(bEnabled);
     923                                OnFilterGraphComboBoxSelEndOk();
     924                                UpdateFilterComboBox();
     925                        }
     926                        VOID UpdateFilterComboBox()
     927                        {
     928                                m_FilterComboBox.ResetContent();
     929                                INT nItem = 0;
     930                                _W(m_FilterComboBox.InsertString(nItem++, _T("<All Filters>")) == 0);
     931                                m_FilterComboBox.SetCurSel(0);
     932                                CRoArrayT<UINT64> IdentifierArray;
     933                                CRoArrayT<CFilterValue> ValueArray;
     934                                for(auto&& Item: m_Owner.m_Data.m_ItemArray)
     935                                {
     936                                        if(m_pProcessValue && m_pProcessValue->m_nIdentifier != Item.m_Item.nProcessIdentifier)
     937                                                continue;
     938                                        if(m_pFilterGraphValue && m_pFilterGraphValue->m_nIdentifier != Item.m_Item.nFilterGraphIdentifier)
     939                                                continue;
     940                                        if(IdentifierArray.FindFirst(Item.m_PageItem.nFilterIdentifier))
     941                                                continue;
     942                                        IdentifierArray.Add(Item.m_PageItem.nFilterIdentifier);
     943                                        ValueArray.Add(CFilterValue(Item.m_PageItem.nFilterIdentifier, AtlFormatStringW(L"0x%p %ls", (UINT_PTR) Item.m_PageItem.nFilterIdentifier, Item.m_PageItem.pszFilterName)));
     944                                }
     945                                _SortHelper::QuickSort<CFilterValueSortTraits>(ValueArray);
     946                                for(auto&& Value: ValueArray)
     947                                        m_FilterComboBox.InsertString(nItem++, Value.m_sValue, Value);
     948                                if(ValueArray.GetCount() == 1)
     949                                        m_FilterComboBox.SetCurSel(1);
     950                                const BOOL bEnabled = m_FilterComboBox.GetCount() > 2;
     951                                m_FilterComboBox.GetWindow(GW_HWNDPREV).EnableWindow(bEnabled);
     952                                m_FilterComboBox.EnableWindow(bEnabled);
     953                                OnFilterComboBoxSelEndOk();
     954                                UpdateStreamComboBox();
     955                        }
     956                        VOID UpdateStreamComboBox()
     957                        {
     958                                m_StreamComboBox.ResetContent();
     959                                INT nItem = 0;
     960                                _W(m_StreamComboBox.InsertString(nItem++, _T("<All Streams>")) == 0);
     961                                m_StreamComboBox.SetCurSel(0);
     962                                CRoArrayT<CStringW> IdentifierArray;
     963                                CRoArrayT<CStreamValue> ValueArray;
     964                                for(auto&& Item: m_Owner.m_Data.m_ItemArray)
     965                                {
     966                                        if(m_pProcessValue && m_pProcessValue->m_nIdentifier != Item.m_Item.nProcessIdentifier)
     967                                                continue;
     968                                        if(m_pFilterGraphValue && m_pFilterGraphValue->m_nIdentifier != Item.m_Item.nFilterGraphIdentifier)
     969                                                continue;
     970                                        if(m_pFilterValue && m_pFilterValue->m_nIdentifier != Item.m_PageItem.nFilterIdentifier)
     971                                                continue;
     972                                        if(!*Item.m_PageItem.pszStreamName)
     973                                                continue;
     974                                        if(IdentifierArray.FindFirst(Item.m_PageItem.pszStreamName))
     975                                                continue;
     976                                        IdentifierArray.Add(Item.m_PageItem.pszStreamName);
     977                                        ValueArray.Add(CStreamValue(1, Item.m_PageItem.pszStreamName));
     978                                }
     979                                _SortHelper::QuickSort<CStreamValueSortTraits>(ValueArray);
     980                                for(auto&& Value: ValueArray)
     981                                        m_StreamComboBox.InsertString(nItem++, Value.m_sValue, Value);
     982                                if(ValueArray.GetCount() == 1)
     983                                        m_StreamComboBox.SetCurSel(1);
     984                                const BOOL bEnabled = m_StreamComboBox.GetCount() > 2;
     985                                m_StreamComboBox.GetWindow(GW_HWNDPREV).EnableWindow(bEnabled);
     986                                m_StreamComboBox.EnableWindow(bEnabled);
     987                                OnStreamComboBoxSelEndOk();
     988                        }
     989                        VOID Reset()
     990                        {
     991                                m_pProcessValue = NULL;
     992                                UpdateProcessComboBox();
     993                        }
     994                        BOOL IsVisible(const CData::CItem& Item) const
     995                        {
     996                                if(m_pProcessValue && Item.m_Item.nProcessIdentifier != m_pProcessValue->m_nIdentifier)
     997                                        return FALSE;
     998                                if(m_pFilterGraphValue && Item.m_Item.nFilterGraphIdentifier != m_pFilterGraphValue->m_nIdentifier)
     999                                        return FALSE;
     1000                                if(m_pFilterValue && Item.m_PageItem.nFilterIdentifier != m_pFilterValue->m_nIdentifier)
     1001                                        return FALSE;
     1002                                if(m_pStreamValue && wcscmp(Item.m_PageItem.pszStreamName, m_pStreamValue->m_sValue) != 0)
     1003                                        return FALSE;
     1004                                return TRUE;
     1005                        }
     1006
     1007                // Window Message Handler
     1008                        LRESULT OnInitDialog(HWND, LPARAM)
     1009                        {
     1010                                m_ProcessComboBox = GetDlgItem(IDC_MEDIASAMPLETRACE_MEDIASAMPLE_FILTER_PROCESS);
     1011                                m_FilterGraphComboBox = GetDlgItem(IDC_MEDIASAMPLETRACE_MEDIASAMPLE_FILTER_FILTERGRAPH);
     1012                                m_FilterComboBox = GetDlgItem(IDC_MEDIASAMPLETRACE_MEDIASAMPLE_FILTER_FILTER);
     1013                                m_StreamComboBox = GetDlgItem(IDC_MEDIASAMPLETRACE_MEDIASAMPLE_FILTER_STREAM);
     1014                                m_pProcessValue = NULL;
     1015                                m_pFilterGraphValue = NULL;
     1016                                m_pFilterValue = NULL;
     1017                                m_pStreamValue = NULL;
     1018                                DlgResize_Init(FALSE);
     1019                                return TRUE;
     1020                        }
     1021                        LRESULT OnProcessComboBoxSelEndOk(UINT = 0, INT = 0, HWND = NULL)
     1022                        {
     1023                                CProcessValue& ProcessValue = m_ProcessComboBox.GetItemData(m_ProcessComboBox.GetCurSel());
     1024                                m_pProcessValue = ProcessValue.m_nIdentifier ? &ProcessValue : NULL;
     1025                                UpdateFilterGraphComboBox();
     1026                                m_Owner.HandleFilterUpdate();
     1027                                return 0;
     1028                        }
     1029                        LRESULT OnFilterGraphComboBoxSelEndOk(UINT = 0, INT = 0, HWND = NULL)
     1030                        {
     1031                                CFilterGraphValue& FilterGraphValue = m_FilterGraphComboBox.GetItemData(m_FilterGraphComboBox.GetCurSel());
     1032                                m_pFilterGraphValue = FilterGraphValue.m_nIdentifier ? &FilterGraphValue : NULL;
     1033                                UpdateFilterComboBox();
     1034                                m_Owner.HandleFilterUpdate();
     1035                                return 0;
     1036                        }
     1037                        LRESULT OnFilterComboBoxSelEndOk(UINT = 0, INT = 0, HWND = NULL)
     1038                        {
     1039                                CFilterValue& FilterValue = m_FilterComboBox.GetItemData(m_FilterComboBox.GetCurSel());
     1040                                m_pFilterValue = FilterValue.m_nIdentifier ? &FilterValue : NULL;
     1041                                UpdateStreamComboBox();
     1042                                m_Owner.HandleFilterUpdate();
     1043                                return 0;
     1044                        }
     1045                        LRESULT OnStreamComboBoxSelEndOk(UINT = 0, INT = 0, HWND = NULL)
     1046                        {
     1047                                CStreamValue& StreamValue = m_StreamComboBox.GetItemData(m_StreamComboBox.GetCurSel());
     1048                                m_pStreamValue = !StreamValue.m_sValue.IsEmpty() ? &StreamValue : NULL;
     1049                                m_Owner.HandleFilterUpdate();
     1050                                return 0;
     1051                        }
     1052                };
    6541053
    6551054        private:
     
    6601059                CRoHyperStatic m_CopyToClipboardStatic;
    6611060                CRoHyperStatic m_SaveToFileStatic;
     1061                CFilterDialog m_FilterDialog;
    6621062                CRoMapT<INT, BOOL> m_ChangeMap;
    663                 CPages m_Pages;
     1063                CData m_Data;
     1064                CObjectPtr<CThread> m_pThread;
     1065                CHandleMap m_HandleMap;
     1066
     1067                DWORD ThreadProc(CThread*, CEvent& InitializationEvent, CEvent& TerminationEvent)
     1068                {
     1069                        CMultiThreadedApartment Apartment;
     1070                        CEvent RequestEvent, ResponseEvent;
     1071                        _W(RequestEvent.Create(NULL, FALSE, FALSE, CString(CPages::GetFileMappingName()) + _T(".TransferRequest")));
     1072                        _W(ResponseEvent.Create(NULL, FALSE, FALSE, CString(CPages::GetFileMappingName()) + _T(".TransferResponse")));
     1073                        _W(InitializationEvent.Set());
     1074                        if(!RequestEvent || !ResponseEvent)
     1075                                return 0;
     1076                        CStackPointer StackPointer;
     1077                        const HANDLE phObjects[] = { TerminationEvent, RequestEvent };
     1078                        for(; ; )
     1079                        {
     1080                                _A(StackPointer.Check()); StackPointer;
     1081                                const DWORD nWaitResult = WaitForMultipleObjects(DIM(phObjects), phObjects, FALSE, INFINITE);
     1082                                _Z4_WAITRESULT(nWaitResult);
     1083                                _A(nWaitResult - WAIT_OBJECT_0 < DIM(phObjects));
     1084                                if(nWaitResult != WAIT_OBJECT_0 + 1) // RequestEvent
     1085                                        break;
     1086                                CPages Pages;
     1087                                if(Pages.Initialize())
     1088                                        Pages.GetData(m_Data, &m_HandleMap);
     1089                                _W(ResponseEvent.Set());
     1090                        }
     1091                        return 0;
     1092                }
    6641093
    6651094        public:
    6661095        // CMediaSamplePropertyPage
    6671096                CMediaSamplePropertyPage(CMediaSampleTracePropertySheet* pPropertySheet) :
    668                         m_PropertySheet(*pPropertySheet)
     1097                        m_PropertySheet(*pPropertySheet),
     1098                        m_FilterDialog(this)
    6691099                {
    6701100                }
     
    6761106                        CWindowRedraw ListViewRedraw(m_ListView);
    6771107                        m_ListView.DeleteAllItems();
     1108                        m_Data.Initialize();
    6781109                        CPages Pages;
    6791110                        if(Pages.Initialize())
    6801111                        {
    681                                 CData Data;
    682                                 Pages.GetData(Data);
    683                                 Data.Sort();
     1112                                Pages.GetData(m_Data, &m_HandleMap);
     1113                                m_Data.Sort();
    6841114                                INT nItem = 0;
    685                                 for(auto&& Item: Data.m_ItemArray)
     1115                                for(auto&& Item: m_Data.m_ItemArray)
    6861116                                        m_ListView.InsertItem(nItem++, Item);
    6871117                        }
     1118                        m_FilterDialog.Reset();
    6881119                }
    6891120                static CString FormatTime(UINT64 nTime)
     
    7711202                        return CStringA(sText);
    7721203                }
     1204                VOID HandleFilterUpdate()
     1205                {
     1206                        CWindowRedraw ListViewRedraw(m_ListView);
     1207                        m_ListView.DeleteAllItems();
     1208                        INT nItem = 0;
     1209                        for(auto&& Item: m_Data.m_ItemArray)
     1210                                if(m_FilterDialog.IsVisible(Item))
     1211                                        m_ListView.InsertItem(nItem++, Item);
     1212                        // SUGG: Preserve selection
     1213                }
    7731214
    7741215        // Window Message Handler
     
    7871228                                m_SaveToFileStatic.SetExtendedStyle(CRoHyperStatic::CS_ANCHORCLICKCOMMAND);
    7881229                                CRoHyperStatic::ArrangeHorizontally(&m_RefreshStatic, &m_CopyToClipboardStatic, &m_SaveToFileStatic, NULL);
     1230                                #pragma region Filter
     1231                                __E(m_FilterDialog.Create(m_hWnd, (LPARAM) this));
     1232                                {
     1233                                        CRect FilterPosition, Position;
     1234                                        _W(m_FilterDialog.GetWindowRect(FilterPosition));
     1235                                        m_FilterDialog.SetDlgCtrlID(CFilterDialog::IDD);
     1236                                        const CSize FilterExtent = FilterPosition.Size();
     1237                                        _W(m_ListView.GetWindowRect(Position));
     1238                                        _W(ScreenToClient(Position));
     1239                                        const LONG nSpacing = Position.left;
     1240                                        FilterPosition.left = Position.left;
     1241                                        FilterPosition.right = Position.right;
     1242                                        FilterPosition.top = Position.top;
     1243                                        FilterPosition.bottom = FilterPosition.top + FilterExtent.cy;
     1244                                        Position.top = FilterPosition.bottom + nSpacing;
     1245                                        _W(m_FilterDialog.SetWindowPos(m_IntroductionStatic, FilterPosition, SWP_NOACTIVATE | SWP_SHOWWINDOW));
     1246                                        _W(m_ListView.MoveWindow(Position));
     1247                                }
     1248                                #pragma endregion
    7891249                                DlgResize_Init(FALSE, FALSE);
    790                                 _ATLTRY
    791                                 {
    792                                         // NOTE: This forces the global file mapping open referenced by UI
    793                                         // WARN: This is however incomplete since we only keep master mapping and process mappings are gone once the process is gone
    794                                         m_Pages.Initialize(TRUE);
    795                                 }
    796                                 _ATLCATCHALL()
    797                                 {
    798                                         _Z_EXCEPTION();
    799                                 }
    8001250                                UpdateListView();
    8011251                                m_ChangeMap.RemoveAll();
     
    8151265                                _W(m_PropertySheet.CenterWindow());
    8161266                                #pragma endregion
     1267                                m_pThread.Construct()->Initialize(this, &CMediaSamplePropertyPage::ThreadProc);
    8171268                        }
    8181269                        _ATLCATCHALL()
     
    8231274                        }
    8241275                        return TRUE;
     1276                }
     1277                LRESULT OnDestroy()
     1278                {
     1279                        CWaitCursor WaitCursor;
     1280                        m_pThread.Release();
     1281                        return 0;
    8251282                }
    8261283                LRESULT OnTranslateAccelerator(MSG* pMessage)
     
    8881345                                }
    8891346                                pHeader->item.pszText = m_ListView.GetTextBuffer();
     1347                                pHeader->item.mask |= LVIF_DI_SETITEM;
    8901348                        }
    8911349                        return 0;
     
    10101468                {
    10111469                        CWaitCursor WaitCursor;
    1012                         m_Pages.ResetData();
     1470                        m_HandleMap.RemoveAll();
     1471                        CPages Pages;
     1472                        if(Pages.Initialize())
     1473                                Pages.ResetData();
    10131474                        UpdateListView();
    10141475                        return 0;
     
    10181479                        CLocalObjectPtr<CFilterGraphHelper> pFilterGraphHelper;
    10191480                        pFilterGraphHelper->DoFilterGraphListModal((LONG) (LONG_PTR) m_hWnd);
     1481                        return 0;
     1482                }
     1483                LRESULT OnOpenFilterGraphProperties(UINT, INT, HWND)
     1484                {
     1485                        if(m_ListView.GetSelectedCount() == 1)
     1486                        {
     1487                                const INT nItem = m_ListView.GetNextItem(-1, LVNI_SELECTED);
     1488                                _A(nItem >= 0);
     1489                                CData::CItem& Item = m_ListView.GetItemData(nItem);
     1490                                const LONG nProcessIdentifier = Item.m_Item.nProcessIdentifier;
     1491                                CComPtr<IRunningObjectTable> pRunningObjectTable;
     1492                                __C(GetRunningObjectTable(0, &pRunningObjectTable));
     1493                                CRoMapT<CStringW, CFilterGraphListPropertySheet::CListPropertyPage::CItem> ItemMap;
     1494                                CFilterGraphListPropertySheet::CListPropertyPage::EnumerateItems(pRunningObjectTable, ItemMap, &nProcessIdentifier);
     1495                                for(auto&& GraphItem: ItemMap.GetValues())
     1496                                {
     1497                                        if(abs((LONG_PTR) (GraphItem.m_nInstance - Item.m_Item.nFilterGraphIdentifier)) < 0x0100)
     1498                                                if(GraphItem.FilterGraphNeeded(pRunningObjectTable))
     1499                                                {
     1500                                                        CLocalObjectPtr<CFilterGraphHelper> pFilterGraphHelper;
     1501                                                        pFilterGraphHelper->SetFilterGraph(GraphItem.m_pFilterGraph);
     1502                                                        _V(pFilterGraphHelper->DoPropertyFrameModal((LONG) (LONG_PTR) m_hWnd));
     1503                                                        return 0;
     1504                                                }
     1505                                }
     1506                        }
     1507                        _W(PostMessage(WM_COMMAND, IDC_MEDIASAMPLETRACE_MEDIASAMPLE_OPENFILTERGRAPHLIST));
    10201508                        return 0;
    10211509                }
     
    10651553        }
    10661554};
    1067 
    1068 // TODO: Double-Click on media trace entry opens graph
  • trunk/DirectShowSpy/resource.h

    r440 r441  
    131131#define IDC_MEDIASAMPLETRACE_MEDIASAMPLE_RESETDATA 2114
    132132#define IDC_MEDIASAMPLETRACE_MEDIASAMPLE_OPENFILTERGRAPHLIST 2120
     133#define IDC_MEDIASAMPLETRACE_MEDIASAMPLE_OPENFILTERGRAPHPROPERTIES 2121
     134#define IDD_MEDIASAMPLETRACE_MEDIASAMPLE_FILTER 2130
     135#define IDC_MEDIASAMPLETRACE_MEDIASAMPLE_FILTER_PROCESS_TITLE 2131
     136#define IDC_MEDIASAMPLETRACE_MEDIASAMPLE_FILTER_PROCESS 2132
     137#define IDC_MEDIASAMPLETRACE_MEDIASAMPLE_FILTER_FILTERGRAPH_TITLE 2133
     138#define IDC_MEDIASAMPLETRACE_MEDIASAMPLE_FILTER_FILTERGRAPH 2134
     139#define IDC_MEDIASAMPLETRACE_MEDIASAMPLE_FILTER_FILTER_TITLE 2135
     140#define IDC_MEDIASAMPLETRACE_MEDIASAMPLE_FILTER_FILTER 2136
     141#define IDC_MEDIASAMPLETRACE_MEDIASAMPLE_FILTER_STREAM_TITLE 2137
     142#define IDC_MEDIASAMPLETRACE_MEDIASAMPLE_FILTER_STREAM 2138
    133143#define IDR_FILTERGRAPHSPY              25000
    134144#define IDR_NOTHREADFILTERGRAPHSPY      25001
     
    152162#ifdef APSTUDIO_INVOKED
    153163#ifndef APSTUDIO_READONLY_SYMBOLS
    154 #define _APS_NEXT_RESOURCE_VALUE        213
    155 #define _APS_NEXT_COMMAND_VALUE         32796
    156 #define _APS_NEXT_CONTROL_VALUE         252
     164#define _APS_NEXT_RESOURCE_VALUE        214
     165#define _APS_NEXT_COMMAND_VALUE         32798
     166#define _APS_NEXT_CONTROL_VALUE         257
    157167#define _APS_NEXT_SYMED_VALUE           103
    158168#endif
Note: See TracChangeset for help on using the changeset viewer.