1. 程式人生 > >HC 原始碼分析 6:MediaInfo選項卡 (CPPageFileMediaInfo)

HC 原始碼分析 6:MediaInfo選項卡 (CPPageFileMediaInfo)

=====================================================

Media Player Classic - HC 原始碼分析系列文章列表:

=====================================================


前幾篇文章分析了Media Player Classic - HC(mpc-hc)的核心類(CMainFrame):

核心類分析完之後,分析了一下CAboutDlg:

發現CAboutDlg和普通的MFC對話方塊類其實沒有什麼區別。CAboutDlg功能相對比較簡單,本文將會分析一個功能相對比較複雜的類:MediaInfo選項卡。在播放視訊的時候,右鍵點選視訊->選擇“屬性”->MediaInfo就可以檢視該選項卡。一般情況下,該選項卡給出了正在播放的視訊檔案的詳細引數(確實是非常的詳細),包括:封裝格式,視訊編碼,音訊編碼等等。是獲取視訊詳細引數的最佳途徑。

該選項卡的功能實際上是呼叫了開源專案MediaInfo的庫。MediaInfo之前已經進行過詳細介紹:

在此不再重複。先看看該選項卡長什麼樣子。


先來看看MediaInfo選項卡類的定義是什麼樣的吧。該類的定義位於PPageFileMediaInfo.h檔案中。

/* 雷霄驊 
 * 中國傳媒大學/數字電視技術 
 * [email protected] 
 * 
 */  
/*
 * (C) 2009-2013 see Authors.txt
 *
 * This file is part of MPC-HC.
 *
 * MPC-HC is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * MPC-HC is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#pragma once

// CPPageFileMediaInfo dialog
// 【屬性】頁面裡面的【MediaInfo】
class CPPageFileMediaInfo : public CPropertyPage
{
    DECLARE_DYNAMIC(CPPageFileMediaInfo)

private:
    CComPtr<IFilterGraph> m_pFG;
public:
	//建構函式都是兩個引數
    CPPageFileMediaInfo(CString fn, IFilterGraph* pFG);
    virtual ~CPPageFileMediaInfo();

    // Dialog Data
    enum { IDD = IDD_FILEMEDIAINFO };
	//顯示資訊的控制元件
    CEdit m_mediainfo;
    CString m_fn;
    CFont* m_pCFont;
	//資訊
    CString MI_Text;

#if !USE_STATIC_MEDIAINFO
    static bool HasMediaInfo();
#endif
protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//初始化,載入MediaInfo庫,讀取檔案資訊
    virtual BOOL OnInitDialog();

    DECLARE_MESSAGE_MAP()

public:
	//顯示視窗,並不做其他事情
    afx_msg void OnShowWindow(BOOL bShow, UINT nStatus);
};

該類和普通的MFC對話方塊類差別也不大。需要注意的有以下幾點:

1.有一個變數:CComPtr<IFilterGraph> m_pFG,這個是mpc-hc中的變數,先不分析該變數的全部程式碼,在這裡僅說一下它的作用:獲取正在播放的視訊檔案的路徑。

2.有一個控制元件類:CEdit m_mediainfo,對應介面上那個大框框,用於顯示資訊。

3.有一個字串變數:CString MI_Text,用於儲存MediaInfo得到的媒體資訊。

下面來看看具體類的實現,該類的實現位於PPageFileMediaInfo.cpp檔案中。

/* 雷霄驊 
 * 中國傳媒大學/數字電視技術 
 * [email protected]
* */ /* * (C) 2009-2013 see Authors.txt * * This file is part of MPC-HC. * * MPC-HC is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * MPC-HC is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * */ // PPageFileMediaInfo.cpp : implementation file #include "stdafx.h" #include "mplayerc.h" #include "PPageFileMediaInfo.h" #include "WinAPIUtils.h" #if USE_STATIC_MEDIAINFO #include "MediaInfo/MediaInfo.h" using namespace MediaInfoLib; #else #include "MediaInfoDLL.h" using namespace MediaInfoDLL; #endif // CPPageFileMediaInfo dialog IMPLEMENT_DYNAMIC(CPPageFileMediaInfo, CPropertyPage) CPPageFileMediaInfo::CPPageFileMediaInfo(CString fn, IFilterGraph* pFG) : CPropertyPage(CPPageFileMediaInfo::IDD, CPPageFileMediaInfo::IDD) , m_fn(fn) , m_pFG(pFG) , m_pCFont(nullptr) { } CPPageFileMediaInfo::~CPPageFileMediaInfo() { delete m_pCFont; m_pCFont = nullptr; } void CPPageFileMediaInfo::DoDataExchange(CDataExchange* pDX) { __super::DoDataExchange(pDX); DDX_Control(pDX, IDC_MIEDIT, m_mediainfo); } BEGIN_MESSAGE_MAP(CPPageFileMediaInfo, CPropertyPage) ON_WM_SHOWWINDOW() END_MESSAGE_MAP() // CPPageFileMediaInfo message handlers static WNDPROC OldControlProc; static LRESULT CALLBACK ControlProc(HWND control, UINT message, WPARAM wParam, LPARAM lParam) { if (message == WM_KEYDOWN) { if ((LOWORD(wParam) == 'A' || LOWORD(wParam) == 'a') && (GetKeyState(VK_CONTROL) < 0)) { CEdit* pEdit = (CEdit*)CWnd::FromHandle(control); pEdit->SetSel(0, pEdit->GetWindowTextLength(), TRUE); return 0; } } return CallWindowProc(OldControlProc, control, message, wParam, lParam); // call edit control's own windowproc } //初始化,載入MediaInfo庫,讀取檔案資訊 BOOL CPPageFileMediaInfo::OnInitDialog() { __super::OnInitDialog(); if (!m_pCFont) { m_pCFont = DEBUG_NEW CFont; } if (!m_pCFont) { return TRUE; } if (m_fn.IsEmpty()) { BeginEnumFilters(m_pFG, pEF, pBF) { CComQIPtr<IFileSourceFilter> pFSF = pBF; if (pFSF) { //當前檔案路徑 LPOLESTR pFN = nullptr; //媒體型別 AM_MEDIA_TYPE mt; //獲取當前檔案的路徑和媒體型別 if (SUCCEEDED(pFSF->GetCurFile(&pFN, &mt)) && pFN && *pFN) { m_fn = CStringW(pFN); CoTaskMemFree(pFN); } break; } } EndEnumFilters; } #if USE_STATIC_MEDIAINFO //使用靜態庫MediaInfo //檔案路徑 MediaInfoLib::String f_name = m_fn; MediaInfoLib::MediaInfo MI; #else MediaInfoDLL::String f_name = m_fn; MediaInfo MI; #endif //設定 MI.Option(_T("ParseSpeed"), _T("0")); MI.Open(f_name); MI.Option(_T("Complete")); MI.Option(_T("Language"), _T(" Config_Text_ColumnSize;30")); //資訊字串 MI_Text = MI.Inform().c_str(); MI.Close(); if (!MI_Text.Find(_T("Unable to load"))) { MI_Text = _T(""); } LOGFONT lf; ZeroMemory(&lf, sizeof(lf)); lf.lfPitchAndFamily = DEFAULT_PITCH | FF_MODERN; // The empty string will fallback to the first font that matches the other specified attributes. LPCTSTR fonts[] = { _T("Lucida Console"), _T("Courier New"), _T("") }; // Use a negative value to match the character height instead of the cell height. int fonts_size[] = { -10, -11, -11 }; UINT i = 0; BOOL success; do { _tcscpy_s(lf.lfFaceName, fonts[i]); lf.lfHeight = fonts_size[i]; success = IsFontInstalled(fonts[i]) && m_pCFont->CreateFontIndirect(&lf); i++; } while (!success && i < _countof(fonts)); //控制元件設定字型和內容 m_mediainfo.SetFont(m_pCFont); m_mediainfo.SetWindowText(MI_Text); // subclass the edit control OldControlProc = (WNDPROC)SetWindowLongPtr(m_mediainfo.m_hWnd, GWLP_WNDPROC, (LONG_PTR)ControlProc); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } //顯示or不顯示? void CPPageFileMediaInfo::OnShowWindow(BOOL bShow, UINT nStatus) { __super::OnShowWindow(bShow, nStatus); if (bShow) { GetParent()->GetDlgItem(IDC_BUTTON_MI)->ShowWindow(SW_SHOW); } else { GetParent()->GetDlgItem(IDC_BUTTON_MI)->ShowWindow(SW_HIDE); } } #if !USE_STATIC_MEDIAINFO bool CPPageFileMediaInfo::HasMediaInfo() { MediaInfo MI; return MI.IsReady(); } #endif

可以看出,主要的工作都是在OnInitDialog()函式中實現的。大體的步驟如下:

1.通過呼叫pFSF->GetCurFile(&pFN, &mt),獲得當前檔案的路徑,存入pFN中。

2.因為字串型別不同,幾經轉換把pFN轉換為MediaInfo可以識別的字串f_name

3.根據該路徑,呼叫MediaInfo庫,獲得視訊的詳細資訊存入字串變數MI_Text。

4.將MI_Text顯示到控制元件上。

總體說來,過程並不複雜,理解起來還是比較簡單的。

相關推薦

HC 原始碼分析 6MediaInfo選項 CPPageFileMediaInfo

=====================================================Media Player Classic - HC 原始碼分析系列文章列表:===============================================

XBMC原始碼分析 6視訊播放器dvdplayer-檔案頭以ffmpeg為例

XBMC分析系列文章: XBMC原始碼簡析 5:視訊播放器(dvdplayer)-解複用器(以ffmpeg為例)本文我們分析XBMC中視訊播放器(dvdplayer)中的檔案頭部分。檔案頭部分裡包含的是封裝Dll用到的標頭檔案。由於檔案頭種類很多,不可能一一分析,

XBMC原始碼分析 4視訊播放器dvdplayer-解碼器以ffmpeg為例

XBMC分析系列文章: 本文我們分析XBMC中視訊播放器(dvdplayer)中的解碼器部分。由於解碼器種類很多,不可能一一分析,因此以ffmpeg解碼器為例進行分析。 XBMC解碼器部分檔案目錄如下圖所示: 解碼器分為音訊解碼器和視訊解碼器。在這裡我們看一下視訊

tab選項1一級tab選項

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <style>

選項1

lec set 樣式 gin relative ctype ive css樣式 lac 選項卡控件它提供一系列操作按鈕,單擊不同的按鈕可以在各個頁面之間進行切換。 選項卡實現的幾種方法: html+css <!DOCTYPE html> <htm

【spring原始碼分析】IOC容器初始化

前言:在【spring原始碼分析】IOC容器初始化(一)中已經分析了匯入bean階段,本篇接著分析bean解析階段。 1.解析bean程式呼叫鏈 同樣,先給出解析bean的程式呼叫鏈: 根據程式呼叫鏈,整理出在解析bean過程中主要涉及的類和相關方法。 2.解析bean原始碼分

Java原始碼分析——java.util工具包解析——UUID、Base64、內建觀察者模式Observer介面、EventListener、RandomAccess

UUID     關於UUID,我們需要知道它最重要的一點,就是它會生成全地球唯一的一個id,它可以作為資料庫的主鍵存在,標識各個元組。 UUID保證對在同一時空中的所有機器都是唯一的,利用機器的當前日期和時間、時鐘序列、全域性唯一的IEEE機

Java原始碼分析——java.util工具包解析——四大引用型別以及WeakHashMap類解析

    WeakHashMap是Map的一種很獨特的實現,從它的名字可以看出,它是存貯弱引用的對映的,先來複習一下Java中的四大引用型別: 強引用:我們使用的大部分引用實際上都是強引用,這是使用最普遍的引用。強引用的物件垃圾回收器絕不

Java原始碼分析——java.util工具包解析——HashMap、TreeMap、LinkedHashMap、Hashtable類解析

    Map,中文名字對映,它儲存了鍵-值對的一對一的關係形式,並用雜湊值來作為存貯的索引依據,在查詢、插入以及刪除時的時間複雜度都為O(1),是一種在程式中用的最多的幾種資料結構。Java在java.util工具包中實現了Map介面,來作為各大

Java原始碼分析——java.util工具包解析——HashSet、TreeSet、LinkedHashSet類解析

    Set,即集合,與數學上的定義一樣,集合具有三個特點: 無序性:一個集合中,每個元素的地位都是相同的,元素之間是無序的。 互異性:一個集合中,任何兩個元素都認為是不相同的,即每個元素只能出現一次。 確定性:給定一個集

Java原始碼分析——java.util工具包解析——ArrayList、LinkedList、Vector類解析

    Java中,List列表類與Set集合類的共同源頭是Collection介面,而Collection的父介面是Iterable介面,在Collection介面下又實現了三個常用的介面以及一個抽象方法,分別為Queue介面、List介面、Se

Spark core原始碼分析之spark叢集的啟動

2.2 Worker的啟動 org.apache.spark.deploy.worker 1 從Worker的伴生物件的main方法進入 在main方法中首先是得到一個SparkConf例項conf,然後將conf和啟動Worker傳入的引數封裝得到Wor

Rxjava2.x 原始碼分析,以及手動實現Rxjava

這兩年Rxjava火的一塌糊塗,不會點Rxjava+Okhttp+Retrofit+MVP+Dagger2架構都不好意思說自己混Android的。Rxjava 到底是什麼和Rxjava到底怎麼用,這裡就不講了,網上太多了,具體可以參考 這位大佬 和扔物線的。  Rxjava

選項Tab切換事件

選項卡切換事件 <style type="text/css"> *{margin: 0; padding: 0; font-family: "微軟雅黑";font-size: 14px;} #container{ width: 398px; ma

springMVC原始碼分析--HandlerInterceptor攔截器呼叫過程

在上一篇部落格springMVC原始碼分析--HandlerInterceptor攔截器(一)中我們介紹了HandlerInterceptor攔截器相關的內容,瞭解到了HandlerInterceptor提供的三個介面方法:(1)preHandle: 在執行controlle

Vue學習之原始碼分析--VNode節點(Vue.js實現

抽象DOM樹 在刀耕火種的年代,我們需要在各個事件方法中直接操作DOM來達到修改檢視的目的。但是當應用一大就會變得難以維護。 那我們是不是可以把真實DOM樹抽象成一棵以JavaScript物件構成的抽象樹,在修改抽象樹資料後將抽象樹轉化成真實DOM重繪到頁面

spark mllib原始碼分析之隨機森林(Random Forest)

4. 特徵處理 這部分主要在DecisionTree.scala的findSplitsBins函式,將所有特徵封裝成Split,然後裝箱Bin。首先對split和bin的結構進行說明 4.1. 資料結構 4.1.1. Split cl

Java選項JTabbedPane的使用

JTabbedPane是一種可以放多個面板的並且可以方便切換的容器 1.  建構函式 (1)JTabbedPane( )  建立空的JTabbedPane物件,但實際它的默             認值為JTabbedPane.Top,也就是說卡片名將放在容器頂部。 (2

springboot原始碼分析7-環境屬性構造過程

使用springboot的目的就是在專案開發中,快速出東西,因此springboot對於配置檔案的格式支援是非常豐富的,最常見的配置檔案字尾有如下四種:properties、xml、yml、yaml,比

(萊昂氏unix原始碼分析導讀-11)系統初啟4

本章討論程序複製,繼續Main函式。 1625 */ 1626 1627 if(newproc()) {                         …… 現在看newproc的程式碼。 1826 newproc() 1827 {           ......