首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网络技术 > 网络基础 >

Media Player Classic - HC 源代码分析 二:核心类 (CMainFrame)(1)

2013-10-29 
Media Player Classic - HC 源代码分析 2:核心类 (CMainFrame)(1)上一篇文章概括性的介绍了Media Player C

Media Player Classic - HC 源代码分析 2:核心类 (CMainFrame)(1)

上一篇文章概括性的介绍了Media Player Classic - Home Cinema (mpc-hc)播放器的源代码:Media Player Classic - HC 源代码分析 1:整体结构
现在可以开始看看具体的源代码了。

mpc-hc最核心的类名字叫CMainFrame,它的定义位于MainFrm.h文件中

CMainFrame定义非常的长,包含了视频播放器的方方面面,一共900多行,在这里应该快放不下了。因此我删掉了很多代码,只保留了部分代码。关键的函数上面都写上了注释。

//打开文件void CMainFrame::OpenFile(OpenFileData* pOFD){    if (pOFD->fns.IsEmpty()) {        throw (UINT)IDS_MAINFRM_81;    }//获取设置    CAppSettings& s = AfxGetAppSettings();    bool bMainFile = true;    POSITION pos = pOFD->fns.GetHeadPosition();    while (pos) {        CString fn = pOFD->fns.GetNext(pos);        fn.Trim();        if (fn.IsEmpty() && !bMainFile) {            break;        }//使用DirectShow播放文件        HRESULT hr = m_pGB->RenderFile(CStringW(fn), nullptr);        if (bMainFile) {            // Don't try to save file position if source isn't seekable            REFERENCE_TIME rtDur = 0;            m_pMS->GetDuration(&rtDur);            m_bRememberFilePos = s.fKeepHistory && s.fRememberFilePos && rtDur > 0;            if (m_bRememberFilePos && !s.filePositions.AddEntry(fn)) {                REFERENCE_TIME rtPos = s.filePositions.GetLatestEntry()->llPosition;                if (m_pMS) {                    m_pMS->SetPositions(&rtPos, AM_SEEKING_AbsolutePositioning, nullptr, AM_SEEKING_NoPositioning);                }            }        }        QueryPerformanceCounter(&m_liLastSaveTime);        if (FAILED(hr)) {            if (bMainFile) {                if (s.fReportFailedPins) {                    CComQIPtr<IGraphBuilderDeadEnd> pGBDE = m_pGB;                    if (pGBDE && pGBDE->GetCount()) {                        CMediaTypesDlg(pGBDE, GetModalParent()).DoModal();                    }                }                UINT err;                switch (hr) {                    case E_ABORT:                    case RFS_E_ABORT:                        err = IDS_MAINFRM_82;                        break;                    case E_FAIL:                    case E_POINTER:                    default:                        err = IDS_MAINFRM_83;                        break;                    case E_INVALIDARG:                        err = IDS_MAINFRM_84;                        break;                    case E_OUTOFMEMORY:                        err = IDS_AG_OUT_OF_MEMORY;                        break;                    case VFW_E_CANNOT_CONNECT:                        err = IDS_MAINFRM_86;                        break;                    case VFW_E_CANNOT_LOAD_SOURCE_FILTER:                        err = IDS_MAINFRM_87;                        break;                    case VFW_E_CANNOT_RENDER:                        err = IDS_MAINFRM_88;                        break;                    case VFW_E_INVALID_FILE_FORMAT:                        err = IDS_MAINFRM_89;                        break;                    case VFW_E_NOT_FOUND:                        err = IDS_MAINFRM_90;                        break;                    case VFW_E_UNKNOWN_FILE_TYPE:                        err = IDS_MAINFRM_91;                        break;                    case VFW_E_UNSUPPORTED_STREAM:                        err = IDS_MAINFRM_92;                        break;                    case RFS_E_NO_FILES:                        err = IDS_RFS_NO_FILES;                        break;                    case RFS_E_COMPRESSED:                        err = IDS_RFS_COMPRESSED;                        break;                    case RFS_E_ENCRYPTED:                        err = IDS_RFS_ENCRYPTED;                        break;                    case RFS_E_MISSING_VOLS:                        err = IDS_RFS_MISSING_VOLS;                        break;                }                throw err;            }        }        // We don't keep track of the standard input since that hardly makes any sense        if (s.fKeepHistory && fn != _T("pipe:0")) {            CRecentFileList* pMRU = bMainFile ? &s.MRU : &s.MRUDub;            pMRU->ReadList();            pMRU->Add(fn);            pMRU->WriteList();            SHAddToRecentDocs(SHARD_PATH, fn);        }        if (bMainFile) {            pOFD->title = fn;        }        bMainFile = false;        if (m_fCustomGraph) {            break;        }    }    if (s.fReportFailedPins) {        CComQIPtr<IGraphBuilderDeadEnd> pGBDE = m_pGB;        if (pGBDE && pGBDE->GetCount()) {            CMediaTypesDlg(pGBDE, GetModalParent()).DoModal();        }    }    if (!(m_pAMOP = m_pGB)) {        BeginEnumFilters(m_pGB, pEF, pBF);        if (m_pAMOP = pBF) {            break;        }        EndEnumFilters;    }    if (FindFilter(CLSID_MPCShoutcastSource, m_pGB)) {        m_fUpdateInfoBar = true;    }    SetupChapters();    CComQIPtr<IKeyFrameInfo> pKFI;    BeginEnumFilters(m_pGB, pEF, pBF);    if (pKFI = pBF) {        break;    }    EndEnumFilters;    UINT nKFs = 0;    if (pKFI && S_OK == pKFI->GetKeyFrameCount(nKFs) && nKFs > 0) {        UINT k = nKFs;        if (!m_kfs.SetCount(k) || S_OK != pKFI->GetKeyFrames(&TIME_FORMAT_MEDIA_TIME, m_kfs.GetData(), k) || k != nKFs) {            m_kfs.RemoveAll();        }    }//设置播放模式    SetPlaybackMode(PM_FILE);}

从OpenFile()函数的源代码我们可以看出,mpc-hc调用了DirectShow的函数,打开相应的文件。比如说:

HRESULT hr = m_pGB->RenderFile(CStringW(fn), nullptr);









热点排行