首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

VC 調用 DirectShow 全屏播放視頻:DirectDraw 表面渲染實戰

     編輯:VC 教學

架構概覽

DirectShow (DirectX Media) 提供高級多媒體管線,自動識別格式(含 MPEG-2),構建過濾器圖。全屏播放核心流程:

  1. 創建 DirectDraw 主表面(全屏獨佔模式)
  2. 構建多媒體流,添加視頻/音頻流
  3. 從文件加載媒體流
  4. 在 DirectDraw 表面渲染播放

必要頭文件與接口


#include <ddraw.h>
#include <mmstream.h>
#include <amstream.h>
#include <ddstream.h>

// 核心接口
IDirectDraw*           pDD;             // DirectDraw 對象
IDirectDrawSurface*    pPrimarySurface; // 主表面
IMultiMediaStream*     pMMStream;       // 多媒體流(最高層接口)
IAMMultiMediaStream*   pAMStream;       // 進階多媒體流(構建圖用)

初始化流程

1. COM 與 DirectDraw 初始化


HRESULT Init() {
    CoInitialize(NULL); // COM 初始化

    HRESULT r = DirectDrawCreate(NULL, &pDD, NULL);
    pDD->SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
    pDD->SetDisplayMode(640, 480, 16); // 分辨率、色深

    DDSURFACEDESC ddsd = { sizeof(ddsd) };
    ddsd.dwFlags = DDSD_CAPS;
    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
    pDD->CreateSurface(&ddsd, &pPrimarySurface, NULL);

    return S_OK;
}

2. 從文件加載媒體流


HRESULT LoadFromFile(const char* szFileName,
                     IMultiMediaStream** ppMMStream,
                     IDirectDraw* pDD) {
    // 創建進階流構建器
    CoCreateInstance(CLSID_AMMultiMediaStream, NULL, CLSCTX_INPROC_SERVER,
                     IID_IAMMultiMediaStream, (void**)&pAMStream);

    // 字符串轉 Unicode
    WCHAR wPath[MAX_PATH];
    MultiByteToWideChar(CP_ACP, 0, szFileName, -1, wPath, MAX_PATH);

    // 初始化流:讀取模式,無圖線程
    pAMStream->Initialize(STREAMTYPE_READ, AMMSF_NOGRAPHTHREAD, NULL);

    // 添加視頻流(綁定 DirectDraw)
    pAMStream->AddMediaStream(pDD, &MSPID_PrimaryVideo, 0, NULL);

    // 添加音頻流(默認渲染器)
    pAMStream->AddMediaStream(NULL, &MSPID_PrimaryAudio,
                              AMMSF_ADDDEFAULTRENDERER, NULL);

    // 打開文件(自動構建過濾器圖)
    pAMStream->OpenFile(wPath, 0);

    *ppMMStream = pAMStream; // 返回基礎接口
    return S_OK;
}

3. 播放控制(原文截斷,補充核心邏輯)


HRESULT Play() {
    IMediaControl* pControl;
    pMMStream->QueryInterface(IID_IMediaControl, (void**)&pControl);
    return pControl->Run(); // 開始播放
}

HRESULT Stop() {
    IMediaControl* pControl;
    pMMStream->QueryInterface(IID_IMediaControl, (void**)&pControl);
    return pControl->Stop();
}

資源釋放


void Uninit() {
    if (pMMStream) pMMStream->Release();
    if (pPrimarySurface) pPrimarySurface->Release();
    if (pDD) pDD->Release();
    CoUninitialize();
}

關鍵技術點解析

組件角色關鍵點
IMultiMediaStream統一流容器包含一個或多個媒體流(視頻/音頻/文本)
IAMMultiMediaStream流構建器Initialize/AddMediaStream/OpenFile 構建過濾器圖
MSPID_PrimaryVideo視頻流標識綁定 DirectDraw 表面硬件渲染
MSPID_PrimaryAudio音頻流標識AMMSF_ADDDEFAULTRENDERER 自動添加音頻渲染器
STREAMTYPE_READ流類型從文件讀取;另可 STREAMTYPE_WRITE 捕獲
AMMSF_NOGRAPHTHREAD標志無獨立圖線程,主線程處理事件

優勢與局限

  • 優勢:格式自動識別、硬件加速渲染、DirectX 集成、支持 MPEG-2、過濾器圖自動構建
  • 局限:DirectDraw 已棄用、DirectShow 維護模式、現代應用建議 Media Foundation / Media Engine

現代替代方案

  • Media Foundation (MF):Windows Vista+ 原生媒體平台,管線化架構、硬件加速、DRM 支持
  • Media Engine / MFT:更高層封裝、自適應串流
  • FFmpeg + Direct3D 11:跨平台、完全可控、硬件解碼渲染

總結

DirectShow + DirectDraw 曾是 Windows 全屏視頻播放的標準方案。理解其「流構建 → 表面綁定 → 過濾器圖運行」模式,有助於掌握現代媒體管線架構。遷移新項目請優先選擇 Media Foundation 或 FFmpeg 方案。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved