• Media Player Classic


    注:写了一系列分析Media Player Classic - HC 源代码的文章,在此列一个列表:

    Media Player Classic - HC 源代码分析 1:整体结构
    Media Player Classic - HC 源代码分析 2:核心类 (CMainFrame)(1)
    Media Player Classic - HC 源代码分析 3:核心类 (CMainFrame)(2)
    Media Player Classic - HC 源代码分析 4:核心类 (CMainFrame)(3)
    Media Player Classic - HC 源代码分析 5:关于对话框 (CAboutDlg)
    Media Player Classic - HC 源代码分析 6:MediaInfo选项卡 (CPPageFileMediaInfo)
    Media Player Classic - HC 源代码分析 7:详细信息选项卡(CPPageFileInfoDetails)


    上一篇文章分析了Media Player Classic - HC(mpc-hc)的源代码中的核心类 CMainFrame:Media Player Classic - HC 源代码分析 2:核心类 (CMainFrame)(1)

    主要介绍了CMainFrame类中的以下几个函数(“->”代表调用关系):

    OpenMedia()->OpenMediaPrivate()->OpenFile()

    本文补充介绍CMainFrame类中的其他一些函数。

    再回顾一下打开文件功能主要所在的函数OpenMediaPrivate():

    //打开一个媒体(private)
    bool CMainFrame::OpenMediaPrivate(CAutoPtr<OpenMediaData> pOMD)
    {
    	//获得设置信息
        CAppSettings& s = AfxGetAppSettings();
    
        if (m_iMediaLoadState != MLS_CLOSED) {
            ASSERT(0);
            return false;
        }
    	//OpenFileData
    	//OpenDVDData
    	//OpenDeviceData
    	//里面包含了文件或者DVD信息(名称等)
        OpenFileData* pFileData = dynamic_cast<OpenFileData*>(pOMD.m_p);
        OpenDVDData* pDVDData = dynamic_cast<OpenDVDData*>(pOMD.m_p);
        OpenDeviceData* pDeviceData = dynamic_cast<OpenDeviceData*>(pOMD.m_p);
        if (!pFileData && !pDVDData  && !pDeviceData) {
            ASSERT(0);
            return false;
        }
    
        // Clear DXVA state ...
        ClearDXVAState();
    
    #ifdef _DEBUG
        // Debug trace code - Begin
        // Check for bad / buggy auto loading file code
        if (pFileData) {
            POSITION pos = pFileData->fns.GetHeadPosition();
            UINT index = 0;
            while (pos != nullptr) {
                CString path = pFileData->fns.GetNext(pos);
                TRACE(_T("--> CMainFrame::OpenMediaPrivate - pFileData->fns[%d]:
    "), index);
                TRACE(_T("	%ws
    "), path.GetString()); // %ws - wide character string always
                index++;
            }
        }
        // Debug trace code - End
    #endif
    
        CString mi_fn = _T("");
    
        if (pFileData) {
            if (pFileData->fns.IsEmpty()) {
                return false;
            }
    
            CString fn = pFileData->fns.GetHead();
    
            int i = fn.Find(_T(":\"));
            if (i > 0) {
                CString drive = fn.Left(i + 2);
                UINT type = GetDriveType(drive);
                CAtlList<CString> sl;
                if (type == DRIVE_REMOVABLE || type == DRIVE_CDROM && GetCDROMType(drive[0], sl) != CDROM_Audio) {
                    int ret = IDRETRY;
                    while (ret == IDRETRY) {
                        WIN32_FIND_DATA findFileData;
                        HANDLE h = FindFirstFile(fn, &findFileData);
                        if (h != INVALID_HANDLE_VALUE) {
                            FindClose(h);
                            ret = IDOK;
                        } else {
                            CString msg;
                            msg.Format(IDS_MAINFRM_114, fn);
                            ret = AfxMessageBox(msg, MB_RETRYCANCEL);
                        }
                    }
    
                    if (ret != IDOK) {
                        return false;
                    }
                }
                mi_fn = fn;
            }
        }
    
        SetLoadState(MLS_LOADING);
    
        // FIXME: Don't show "Closed" initially
        PostMessage(WM_KICKIDLE);
    
        CString err;
    
        m_fUpdateInfoBar = false;
        BeginWaitCursor();
    
        try {
            CComPtr<IVMRMixerBitmap9>    pVMB;
            CComPtr<IMFVideoMixerBitmap> pMFVMB;
            CComPtr<IMadVRTextOsd>       pMVTO;
            if (m_fOpeningAborted) {
                throw (UINT)IDS_AG_ABORTED;
            }
    
            OpenCreateGraphObject(pOMD);
    
            if (m_fOpeningAborted) {
                throw (UINT)IDS_AG_ABORTED;
            }
    
            SetupIViAudReg();
    
            if (m_fOpeningAborted) {
                throw (UINT)IDS_AG_ABORTED;
            }
    		//按类型的不同打开不同的文件
            if (pFileData) {
    			//文件
                OpenFile(pFileData);
            } else if (pDVDData) {
    			//DVD
                OpenDVD(pDVDData);
            } else if (pDeviceData) {
                if (s.iDefaultCaptureDevice == 1) {
                    HRESULT hr = OpenBDAGraph();
                    if (FAILED(hr)) {
                        throw (UINT)IDS_CAPTURE_ERROR_DEVICE;
                    }
                } else {
                    OpenCapture(pDeviceData);
                }
            } else {
                throw (UINT)IDS_INVALID_PARAMS_ERROR;
            }
    
            m_pCAP2 = nullptr;
            m_pCAP = nullptr;
    		//查找接口
            m_pGB->FindInterface(__uuidof(ISubPicAllocatorPresenter), (void**)&m_pCAP, TRUE);
            m_pGB->FindInterface(__uuidof(ISubPicAllocatorPresenter2), (void**)&m_pCAP2, TRUE);
            m_pGB->FindInterface(__uuidof(IVMRWindowlessControl9), (void**)&m_pVMRWC, FALSE); // might have IVMRMixerBitmap9, but not IVMRWindowlessControl9
            m_pGB->FindInterface(__uuidof(IVMRMixerControl9), (void**)&m_pVMRMC, TRUE);
            m_pGB->FindInterface(__uuidof(IVMRMixerBitmap9), (void**)&pVMB, TRUE);
            m_pGB->FindInterface(__uuidof(IMFVideoMixerBitmap), (void**)&pMFVMB, TRUE);
            pMVTO = m_pCAP;
    
            if (s.fShowOSD || s.fShowDebugInfo) { // Force OSD on when the debug switch is used
                if (pVMB) {
                    m_OSD.Start(m_pVideoWnd, pVMB, IsD3DFullScreenMode());
                } else if (pMFVMB) {
                    m_OSD.Start(m_pVideoWnd, pMFVMB, IsD3DFullScreenMode());
                } else if (pMVTO) {
                    m_OSD.Start(m_pVideoWnd, pMVTO);
                }
            }
    		//VMR9
            SetupVMR9ColorControl();
    
            // === EVR !
            m_pGB->FindInterface(__uuidof(IMFVideoDisplayControl), (void**)&m_pMFVDC,  TRUE);
            m_pGB->FindInterface(__uuidof(IMFVideoProcessor), (void**)&m_pMFVP, TRUE);
            if (m_pMFVDC) {
                m_pMFVDC->SetVideoWindow(m_pVideoWnd->m_hWnd);
            }
    
            //SetupEVRColorControl();
            //does not work at this location
            //need to choose the correct mode (IMFVideoProcessor::SetVideoProcessorMode)
    
            BeginEnumFilters(m_pGB, pEF, pBF) {
                if (m_pLN21 = pBF) {
                    m_pLN21->SetServiceState(s.fClosedCaptions ? AM_L21_CCSTATE_On : AM_L21_CCSTATE_Off);
                    break;
                }
            }
            EndEnumFilters;
    
            if (m_fOpeningAborted) {
                throw (UINT)IDS_AG_ABORTED;
            }
    		//打开自定义的Graph
            OpenCustomizeGraph();
    
            if (m_fOpeningAborted) {
                throw (UINT)IDS_AG_ABORTED;
            }
    		//设置视频窗口
            OpenSetupVideo();
    
            if (m_fOpeningAborted) {
                throw (UINT)IDS_AG_ABORTED;
            }
    		//设置音量
            OpenSetupAudio();
    
            if (m_fOpeningAborted) {
                throw (UINT)IDS_AG_ABORTED;
            }
    
            if (m_pCAP && (!m_fAudioOnly || m_fRealMediaGraph)) {
    
                if (s.fDisableInternalSubtitles) {
                    m_pSubStreams.RemoveAll(); // Needs to be replaced with code that checks for forced subtitles.
                }
    
                m_posFirstExtSub = nullptr;
                POSITION pos = pOMD->subs.GetHeadPosition();
                while (pos) {
                    LoadSubtitle(pOMD->subs.GetNext(pos), nullptr, true);
                }
            }
    
            if (m_fOpeningAborted) {
                throw (UINT)IDS_AG_ABORTED;
            }
    		//设置视频窗口标题
            OpenSetupWindowTitle(pOMD->title);
    
            if (s.fEnableEDLEditor) {
                m_wndEditListEditor.OpenFile(pOMD->title);
            }
    
            if (::GetCurrentThreadId() == AfxGetApp()->m_nThreadID) {
                OnFilePostOpenmedia();
            } else {
                PostMessage(WM_COMMAND, ID_FILE_POST_OPENMEDIA);
            }
    
            while (m_iMediaLoadState != MLS_LOADED
                    && m_iMediaLoadState != MLS_CLOSING // FIXME
                  ) {
                Sleep(50);
            }
    		//设置音频流
            DWORD audstm = SetupAudioStreams();
    		//设置字幕流
            DWORD substm = SetupSubtitleStreams();
    
            if (audstm) {
                OnPlayAudio(ID_AUDIO_SUBITEM_START + audstm);
            }
            if (substm) {
                SetSubtitle(substm - 1);
            }
    
            // PostMessage instead of SendMessage because the user might call CloseMedia and then we would deadlock
    
            PostMessage(WM_COMMAND, ID_PLAY_PAUSE);
    
            m_bFirstPlay = true;
    
            if (!(s.nCLSwitches & CLSW_OPEN) && (s.nLoops > 0)) {
                PostMessage(WM_COMMAND, ID_PLAY_PLAY);
            } else {
                // If we don't start playing immediately, we need to initialize
                // the seekbar and the time counter.
                OnTimer(TIMER_STREAMPOSPOLLER);
                OnTimer(TIMER_STREAMPOSPOLLER2);
            }
    
            s.nCLSwitches &= ~CLSW_OPEN;
    
            if (pFileData) {
                if (pFileData->rtStart > 0) {
                    PostMessage(WM_RESUMEFROMSTATE, (WPARAM)PM_FILE, (LPARAM)(pFileData->rtStart / 10000));  // REFERENCE_TIME doesn't fit in LPARAM under a 32bit env.
                }
            } else if (pDVDData) {
                if (pDVDData->pDvdState) {
                    PostMessage(WM_RESUMEFROMSTATE, (WPARAM)PM_DVD, (LPARAM)(CComPtr<IDvdState>(pDVDData->pDvdState).Detach()));    // must be released by the called message handler
                }
            } else if (pDeviceData) {
                m_wndCaptureBar.m_capdlg.SetVideoInput(pDeviceData->vinput);
                m_wndCaptureBar.m_capdlg.SetVideoChannel(pDeviceData->vchannel);
                m_wndCaptureBar.m_capdlg.SetAudioInput(pDeviceData->ainput);
            }
        } catch (LPCTSTR msg) {
            err = msg;
        } catch (CString& msg) {
            err = msg;
        } catch (UINT msg) {
            err.LoadString(msg);
        }
    
        EndWaitCursor();
    
        if (!err.IsEmpty()) {
    		//关闭
            CloseMediaPrivate();
            m_closingmsg = err;
    
            if (err != ResStr(IDS_AG_ABORTED)) {
                if (pFileData) {
                    m_wndPlaylistBar.SetCurValid(false);
    
                    if (m_wndPlaylistBar.IsAtEnd()) {
                        m_nLoops++;
                    }
    
                    if (s.fLoopForever || m_nLoops < s.nLoops) {
                        bool hasValidFile = false;
    
                        if (m_nLastSkipDirection == ID_NAVIGATE_SKIPBACK) {
                            hasValidFile = m_wndPlaylistBar.SetPrev();
                        } else {
                            hasValidFile = m_wndPlaylistBar.SetNext();
                        }
    
                        if (hasValidFile) {
                            OpenCurPlaylistItem();
                        }
                    } else if (m_wndPlaylistBar.GetCount() > 1) {
                        DoAfterPlaybackEvent();
                    }
                } else {
                    OnNavigateSkip(ID_NAVIGATE_SKIPFORWARD);
                }
            }
        } else {
            m_wndPlaylistBar.SetCurValid(true);
    
            // Apply command line audio shift
            if (s.rtShift != 0) {
                SetAudioDelay(s.rtShift);
                s.rtShift = 0;
            }
        }
    
        m_nLastSkipDirection = 0;
    
        if (s.AutoChangeFullscrRes.bEnabled && (m_fFullScreen || IsD3DFullScreenMode())) {
            AutoChangeMonitorMode();
        }
        if (m_fFullScreen && s.fRememberZoomLevel) {
            m_fFirstFSAfterLaunchOnFS = true;
        }
    
        m_LastOpenFile = pOMD->title;
    
        PostMessage(WM_KICKIDLE); // calls main thread to update things
    
        if (!m_bIsBDPlay) {
            m_MPLSPlaylist.RemoveAll();
            m_LastOpenBDPath = _T("");
        }
        m_bIsBDPlay = false;
    
        return err.IsEmpty();
    }

    来看一看OpenMediaPrivate()函数的细节:

    1.开始的时候有这么一句

    CAppSettings& s = AfxGetAppSettings();

    在这里涉及到一个类CAppSettings,存储的是mpc-hc用到的各种设置信息。源代码如下:

    //应用程序中的各种参数
    class CAppSettings
    {
        bool fInitialized;
    
        class CRecentFileAndURLList : public CRecentFileList
        {
        public:
            CRecentFileAndURLList(UINT nStart, LPCTSTR lpszSection,
                                  LPCTSTR lpszEntryFormat, int nSize,
                                  int nMaxDispLen = AFX_ABBREV_FILENAME_LEN);
    
            virtual void Add(LPCTSTR lpszPathName); // we have to override CRecentFileList::Add because the original version can't handle URLs
        };
    
    public:
        bool fShaderEditorWasOpened;
    
        // cmdline params
        UINT nCLSwitches;
        CAtlList<CString>   slFiles, slDubs, slSubs, slFilters;
    
        // Initial position (used by command line flags)
        REFERENCE_TIME      rtShift;
        REFERENCE_TIME      rtStart;
        ULONG               lDVDTitle;
        ULONG               lDVDChapter;
        DVD_HMSF_TIMECODE   DVDPosition;
    
        CSize sizeFixedWindow;
        bool HasFixedWindowSize() const { return sizeFixedWindow.cx > 0 || sizeFixedWindow.cy > 0; }
        //int           iFixedWidth, iFixedHeight;
        int             iMonitor;
    
        CString         ParseFileName(CString const& param);
        void            ParseCommandLine(CAtlList<CString>& cmdln);
    
        // Added a Debug display to the screen (/debug option)
        bool            fShowDebugInfo;
        int             iAdminOption;
    
    
        //播放器 Player
        bool            fAllowMultipleInst;
        bool            fTrayIcon;
        bool            fShowOSD;
        bool            fLimitWindowProportions;
        bool            fSnapToDesktopEdges;
        bool            fHideCDROMsSubMenu;
        DWORD           dwPriority;
        int             iTitleBarTextStyle;
        bool            fTitleBarTextTitle;
        bool            fKeepHistory;
        CRecentFileAndURLList MRU;
        CRecentFileAndURLList MRUDub;
        CFilePositionList filePositions;
        CDVDPositionList  dvdPositions;
        bool            fRememberDVDPos;
        bool            fRememberFilePos;
        bool            bRememberPlaylistItems;
        bool            fRememberWindowPos;
        CRect           rcLastWindowPos;
        bool            fRememberWindowSize;
        bool            fSavePnSZoom;
        double          dZoomX;
        double          dZoomY;
    
        // Formats
        CMediaFormats   m_Formats;
        bool            fAssociatedWithIcons;
    
        // Keys
        CList<wmcmd>    wmcmds;
        HACCEL          hAccel;
        bool            fWinLirc;
        CString         strWinLircAddr;
        CWinLircClient  WinLircClient;
        bool            fUIce;
        CString         strUIceAddr;
        CUIceClient     UIceClient;
        bool            fGlobalMedia;
    
        //图标 Logo
        UINT            nLogoId;
        bool            fLogoExternal;
        CString         strLogoFileName;
    
        //web界面? Web Inteface
        BOOL            fEnableWebServer;
        int             nWebServerPort;
        int             nCmdlnWebServerPort;
        bool            fWebServerUseCompression;
        bool            fWebServerLocalhostOnly;
        bool            fWebServerPrintDebugInfo;
        CString         strWebRoot, strWebDefIndex;
        CString         strWebServerCGI;
    
        //播放时候 Playback
        int             nVolume;
        bool            fMute;
        int             nBalance;
        int             nLoops;
        bool            fLoopForever;
        bool            fRewind;
        bool            fRememberZoomLevel;
        int             nAutoFitFactor;
        int             iZoomLevel;
        CStringW        strAudiosLanguageOrder;
        CStringW        strSubtitlesLanguageOrder;
        bool            fEnableWorkerThreadForOpening;
        bool            fReportFailedPins;
        bool            fAutoloadAudio;
        bool            fAutoloadSubtitles;
        bool            fBlockVSFilter;
        UINT            nVolumeStep;
        UINT            nSpeedStep;
    
        // DVD/OGM
        bool            fUseDVDPath;
        CString         strDVDPath;
        LCID            idMenuLang, idAudioLang, idSubtitlesLang;
        bool            fAutoSpeakerConf;
        bool            fClosedCaptions;
    
        //输出 Output
        CRenderersSettings m_RenderersSettings;
        int             iDSVideoRendererType;
        int             iRMVideoRendererType;
        int             iQTVideoRendererType;
    
        CStringW        strAudioRendererDisplayName;
        bool            fD3DFullscreen;
    
        //全屏 Fullscreen
        bool            fLaunchfullscreen;
        bool            fShowBarsWhenFullScreen;
        int             nShowBarsWhenFullScreenTimeOut;
        bool            fExitFullScreenAtTheEnd;
        CStringW        strFullScreenMonitor;
        AChFR           AutoChangeFullscrRes;
        bool            fRestoreResAfterExit;
    
        // Sync Renderer Settings
    
        // Capture (BDA configuration)
        int             iDefaultCaptureDevice;      // Default capture device (analog=0, 1=digital)
        CString         strAnalogVideo;
        CString         strAnalogAudio;
        int             iAnalogCountry;
        CString         strBDANetworkProvider;
        CString         strBDATuner;
        CString         strBDAReceiver;
        //CString           strBDAStandard;
        int             iBDAScanFreqStart;
        int             iBDAScanFreqEnd;
        int             iBDABandwidth;
        bool            fBDAUseOffset;
        int             iBDAOffset;
        bool            fBDAIgnoreEncryptedChannels;
        UINT            nDVBLastChannel;
        CAtlList<CDVBChannel> m_DVBChannels;
        DVB_RebuildFilterGraph nDVBRebuildFilterGraph;
        DVB_StopFilterGraph nDVBStopFilterGraph;
    
        // Internal Filters
        bool            SrcFilters[SRC_LAST + !SRC_LAST];
        bool            TraFilters[TRA_LAST + !TRA_LAST];
    
        //音频 Audio Switcher
        bool            fEnableAudioSwitcher;
        bool            fAudioNormalize;
        UINT            nAudioMaxNormFactor;
        bool            fAudioNormalizeRecover;
        UINT            nAudioBoost;
        bool            fDownSampleTo441;
        bool            fAudioTimeShift;
        int             iAudioTimeShift;
        bool            fCustomChannelMapping;
        int             nSpeakerChannels;
        DWORD           pSpeakerToChannelMap[AS_MAX_CHANNELS][AS_MAX_CHANNELS];
    
        // External Filters
        CAutoPtrList<FilterOverride> m_filters;
    
        //字幕 Subtitles
        bool            fOverridePlacement;
        int             nHorPos, nVerPos;
        int             nSubDelayInterval;
    
        // Default Style
        STSStyle        subdefstyle;
    
        // Misc
        bool            bPreferDefaultForcedSubtitles;
        bool            fPrioritizeExternalSubtitles;
        bool            fDisableInternalSubtitles;
        bool            bAllowOverridingExternalSplitterChoice;
        CString         strSubtitlePaths;
        CString         strISDb;
    
        // Tweaks
        int             nJumpDistS;
        int             nJumpDistM;
        int             nJumpDistL;
        bool            fFastSeek;
        bool            fShowChapters;
        bool            bNotifySkype;
        bool            fPreventMinimize;
        bool            fUseWin7TaskBar;
        bool            fLCDSupport;
        bool            fUseSearchInFolder;
        bool            fUseTimeTooltip;
        int             nTimeTooltipPosition;
        CString         strOSDFont;
        int             nOSDSize;
    
        //亮度色度饱和度 Miscellaneous
        int             iBrightness;
        int             iContrast;
        int             iHue;
        int             iSaturation;
        int             nUpdaterAutoCheck;
        int             nUpdaterDelay;
    
        // MENUS
        // View
        int             iCaptionMenuMode; // normal -> hidemenu -> frameonly -> borderless
        bool            fHideNavigation;
        UINT            nCS; // Control state for toolbars
        // Language
        LANGID          language;
        // Subtitles menu
        bool            fEnableSubtitles;
        bool            fUseDefaultSubtitlesStyle;
        // Video Frame
        int             iDefaultVideoSize;
        bool            fKeepAspectRatio;
        CSize           sizeAspectRatio;
        bool            fCompMonDeskARDiff;
        // Pan&Scan
        CString         strPnSPreset;
        CStringArray    m_pnspresets;
        // On top menu
        int             iOnTop;
        // After Playback
        bool            fExitAfterPlayback;
        bool            fNextInDirAfterPlayback;
    
        // WINDOWS
        // Add Favorite
        bool            bFavRememberPos;
        bool            bFavRelativeDrive;
        // Save Image...
        CString         strSnapShotPath, strSnapShotExt;
        // Save Thumbnails...
        int             iThumbRows, iThumbCols, iThumbWidth;
        // Shader Editor
        struct Shader {
            CString     label;
            CString     target;
            CString     srcdata;
        };
        CAtlList<Shader> m_shaders;
        // Shader Combiner
        bool            fToggleShader;
        bool            fToggleShaderScreenSpace;
        CString         strShaderList;
        CString         strShaderListScreenSpace;
        // Playlist (contex menu)
        bool            bShufflePlaylistItems;
        bool            bHidePlaylistFullScreen;
    
        // OTHER STATES
        CStringW        strLastOpenDir;
        UINT            nLastWindowType;
        UINT            nLastUsedPage;
        bool            fRemainingTime;
        bool            fLastFullScreen;
    
        bool            fIntRealMedia;
        //bool          fRealMediaRenderless;
        //float         dRealMediaQuickTimeFPS;
        //int           iVideoRendererType;
        //int           iQuickTimeRenderer;
        //bool          fMonitorAutoRefreshRate;
        bool            fEnableEDLEditor;
    
        HWND            hMasterWnd;
    
        bool            IsD3DFullscreen() const;
        CString         SelectedAudioRenderer() const;
        bool            IsISREnabled() const;
    
    private:
        CString         SrcFiltersKeys[SRC_LAST + !SRC_LAST];
        CString         TraFiltersKeys[TRA_LAST + !TRA_LAST];
    
        __int64         ConvertTimeToMSec(const CString& time) const;
        void            ExtractDVDStartPos(CString& strParam);
    
        void            CreateCommands();
    
        void            SaveExternalFilters(CAutoPtrList<FilterOverride>& filters, LPCTSTR baseKey = IDS_R_EXTERNAL_FILTERS);
        void            LoadExternalFilters(CAutoPtrList<FilterOverride>& filters, LPCTSTR baseKey = IDS_R_EXTERNAL_FILTERS);
        void            ConvertOldExternalFiltersList();
    
        void            UpdateRenderersData(bool fSave);
        friend void     CRenderersSettings::UpdateData(bool bSave);
    
    public:
        CAppSettings();
        virtual ~CAppSettings();
    
        void            SaveSettings();
        void            LoadSettings();
        void            SaveExternalFilters() { if (fInitialized) { SaveExternalFilters(m_filters); } };
    
        void            GetFav(favtype ft, CAtlList<CString>& sl) const;
        void            SetFav(favtype ft, CAtlList<CString>& sl);
        void            AddFav(favtype ft, CString s);
    
        CDVBChannel*    FindChannelByPref(int nPrefNumber);
    
        bool            GetAllowMultiInst() const;
    
        static bool     IsVSFilterInstalled();
        static bool     HasEVR();
    };

    由代码可见,包含的参数信息很多。在mpc-hc中,任何需要获取设置信息的地方,都可以使用AfxGetAppSettings()获得CAppSettings的引用。

    2.OpenSetupVideo()这个函数的作用是设置视频窗口,源代码如下:

    //设置视频窗口
    void CMainFrame::OpenSetupVideo()
    {
    	//大部分都在确定:m_fAudioOnly是否为True
        m_fAudioOnly = true;
    	//获得视频的宽和高,然后调整窗口大小
        if (m_pMFVDC) { // EVR
            m_fAudioOnly = false;
        } else if (m_pCAP) {
            CSize vs = m_pCAP->GetVideoSize();
            m_fAudioOnly = (vs.cx <= 0 || vs.cy <= 0);
        } else {
            {
                long w = 0, h = 0;
    
                if (CComQIPtr<IBasicVideo> pBV = m_pGB) {
                    pBV->GetVideoSize(&w, &h);
                }
    
                if (w > 0 && h > 0) {
                    m_fAudioOnly = false;
                }
            }
    		//如果 m_fAudioOnly=true;再检查
            if (m_fAudioOnly) {
                BeginEnumFilters(m_pGB, pEF, pBF) {
                    long w = 0, h = 0;
    
                    if (CComQIPtr<IVideoWindow> pVW = pBF) {
                        long lVisible;
                        if (FAILED(pVW->get_Visible(&lVisible))) {
                            continue;
                        }
    
                        pVW->get_Width(&w);
                        pVW->get_Height(&h);
                    }
    
                    if (w > 0 && h > 0) {
                        m_fAudioOnly = false;
                        break;
                    }
                }
                EndEnumFilters;
            }
        }
    
        if (m_fShockwaveGraph) {
            m_fAudioOnly = false;
        }
    
        if (m_pCAP) {
            SetShaders();
        }
        // else
        {
            // TESTME
    		//设置所有者。。。
            m_pVW->put_Owner((OAHWND)m_pVideoWnd->m_hWnd);
            m_pVW->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
            m_pVW->put_MessageDrain((OAHWND)m_hWnd);
    
            for (CWnd* pWnd = m_wndView.GetWindow(GW_CHILD); pWnd; pWnd = pWnd->GetNextWindow()) {
                pWnd->EnableWindow(FALSE);    // little trick to let WM_SETCURSOR thru
            }
        }
    	//如果只有音频,则消灭视频窗口!
        if (m_fAudioOnly && IsD3DFullScreenMode()) {
            m_pFullscreenWnd->DestroyWindow();
        }
    }

    3.OpenSetupAudio()这个函数的作用是设置音频,源代码如下:

    //设置音量
    void CMainFrame::OpenSetupAudio()
    {
    	//设置音量
        m_pBA->put_Volume(m_wndToolBar.Volume);
    
        // FIXME
        int balance = AfxGetAppSettings().nBalance;
    
        int sign = balance > 0 ? -1 : 1; // -1: invert sign for more right channel
        if (balance > -100 && balance < 100) {
            balance = sign * (int)(100 * 20 * log10(1 - abs(balance) / 100.0f));
        } else {
            balance = sign * (-10000);  // -10000: only left, 10000: only right
        }
    	//设置均衡
        m_pBA->put_Balance(balance);
    }

    4.如果出现问题,则会调用CloseMediaPrivate(),关闭打开的媒体。

    //关闭
    void CMainFrame::CloseMediaPrivate()
    {
        SetLoadState(MLS_CLOSING); // why it before OnPlayStop()? // TODO: remake or add detailed comments
        OnPlayStop(); // SendMessage(WM_COMMAND, ID_PLAY_STOP);
        if (m_pMC) {
            m_pMC->Stop(); // needed for StreamBufferSource, because m_iMediaLoadState is always MLS_CLOSED // TODO: fix the opening for such media
        }
        SetPlaybackMode(PM_NONE);
        m_fLiveWM = false;
        m_fEndOfStream = false;
        m_rtDurationOverride = -1;
        m_kfs.RemoveAll();
        m_pCB.Release();
    
        {
            CAutoLock cAutoLock(&m_csSubLock);
            m_pSubStreams.RemoveAll();
        }
        m_pSubClock.Release();
    
        //if (m_pVW) m_pVW->put_Visible(OAFALSE);
        //if (m_pVW) m_pVW->put_MessageDrain((OAHWND)NULL), m_pVW->put_Owner((OAHWND)NULL);
    
        // IMPORTANT: IVMRSurfaceAllocatorNotify/IVMRSurfaceAllocatorNotify9 has to be released before the VMR/VMR9, otherwise it will crash in Release()
        //各种清空
    	m_OSD.Stop();
        m_pCAP2.Release();
        m_pCAP.Release();
        m_pVMRWC.Release();
        m_pVMRMC.Release();
        m_pMFVP.Release();
        m_pMFVDC.Release();
        m_pLN21.Release();
        m_pSyncClock.Release();
    
        m_pAMXBar.Release();
        m_pAMDF.Release();
        m_pAMVCCap.Release();
        m_pAMVCPrev.Release();
        m_pAMVSCCap.Release();
        m_pAMVSCPrev.Release();
        m_pAMASC.Release();
        m_pVidCap.Release();
        m_pAudCap.Release();
        m_pAMTuner.Release();
        m_pCGB.Release();
    
        m_pDVDC.Release();
        m_pDVDI.Release();
        m_pAMOP.Release();
        m_pBI.Release();
        m_pQP.Release();
        m_pFS.Release();
        m_pMS.Release();
        m_pBA.Release();
        m_pBV.Release();
        m_pVW.Release();
        m_pME.Release();
        m_pMC.Release();
    
        if (m_pGB) {
            m_pGB->RemoveFromROT();
            m_pGB.Release();
        }
    
        m_pProv.Release();
    
        m_fRealMediaGraph = m_fShockwaveGraph = m_fQuicktimeGraph = false;
    
        m_VidDispName.Empty();
        m_AudDispName.Empty();
    
        m_closingmsg.LoadString(IDS_CONTROLS_CLOSED);
    
        AfxGetAppSettings().nCLSwitches &= CLSW_OPEN | CLSW_PLAY | CLSW_AFTERPLAYBACK_MASK | CLSW_NOFOCUS;
    	//设置状态
        SetLoadState(MLS_CLOSED);
    }









  • 相关阅读:
    join()方法的使用
    synchronized关键字
    voliatle关键字
    一.线程概述
    NIO demo
    同步阻塞I/O
    Ubuntu16.04.1 安装Nginx
    垃圾收集
    如何从头开始安装 wordpress
    centos 6 安装 gnu c++ 等开发工具
  • 原文地址:https://www.cnblogs.com/leixiaohua1020/p/3902007.html
Copyright © 2020-2023  润新知