• DirectShow 应用开发过程


    开发环境:Win10 + VS2015

    本文先介绍 DirectShow 中使用的基本术语和概念,然后就可以编写第一个 DirectShow 应用程序。这是一个播放音频或视频文件的简单控制台应用程序,虽然程序只有几行,但它演示了 DirectShow 编程的一些重要功能。


    一、开发环境的配置

    我们先来介绍一下 DirectShow 应用程序开发环境的配置。

    1.1 需要包含的头文件

    DirectShow SDK 建议,所有的 DirectShow 应用都需要 Dshow.h 这个头文件,某些 DirectShow 接口需要附加的头文件,参考接口的说明视具体情况定。


    1.2 需要包含的库文件

    DirectShow SDK 建议,DirectShow 应用程序应该至少连接库文件 Strmiids.lib 和 Quartz.lib。

    • Strmiids.lib:定义了 DirectShow 标准的类标识(CLSID)和接口标识(IID)。
    • Quartz.lib:定义了导出函数 AMGetErrorText,如果不调用此函数,此库不是必需的。

    1.3 VC++ 的系统编译环境

    确保 DirectShow SDK 的 Include 目录和 Lib 目录都已经加入了 VC++ 的系统编译环境。一般安装完 Visual Studio 即会自动配置。


    二、一般开发过程

    开发 DirectShow 应用程序,一般都有三个阶段,如下图:

    典型的DirectShow应用


    第一阶段,创建一个 Filter Graph Manager 组件,代码如下:

    IGraphBuilder *pGraph = NULL;
    HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void **)&pGraph);
    

    第二阶段,根据实际的应用,创建一条完整的 Filter 链路,比如播放一个本地文件,最简单快速的代码如下:

    hr = pGraph->RenderFile(L"D:\test.avi", NULL);
    

    第三阶段,调用 Filter Graph Manager 上(或者直接在某个 Filter 上)的各个接口方法进行控制,并且完成 Filter Graph Manager 与应用程序的事件交互。比如调用 IMediaControl 接口方法控制 Filter Graph 的状态转换,代码如下:

    IMediaControl *pControl = NULL;
    hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
    hr = pControl->Run();
    

    处理完成后,应用程序要释放 Filter Graph Manager 和所有 Filter。


    三、第一个 DirectShow 应用程序

    创建工程:文件 -> 新建 -> 项目 -> Win32 控制台应用程序,注意包括头文件 Dshow.h 并链接到静态库文件 strmiids.lib。完整实例代码如下:

    #include "stdafx.h"
    #include <dshow.h>
    
    // 用到的DirectShow SDK链接库
    #pragma comment(lib,"strmiids.lib")
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        IGraphBuilder *pGraph = NULL; // Filter Graph Manager(实例)
        IMediaControl *pControl = NULL; // 媒体控制
        IMediaEvent   *pEvent = NULL; // 媒体事件
    
        // (一)初始化COM库
        HRESULT hr = CoInitialize(NULL);
        if (FAILED(hr))
        {
            printf("错误 - 无法初始化 COM 组件");
            return -1;
        }
    
        // (二)创建Filter Graph Manager
        hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph);
        if (FAILED(hr))
        {
            printf("错误 - 无法创建 Filter Graph Manager.");
            return -1;
        }
    
        // (三)查询媒体控制和媒体事件接口
        hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
        hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);
    
        // (四)建立Graph,在这里你可以更改待播放的文件名称
        hr = pGraph->RenderFile(L"test.mp4", NULL);
        if (SUCCEEDED(hr))
        {
            // 运行Graph.
            hr = pControl->Run();
            if (SUCCEEDED(hr))
            {
                // IMediaEvent接口用于等待播放完成
                long evCode;
                pEvent->WaitForCompletion(INFINITE, &evCode);
                // 切记: 在实际应用当中,不能使用INFINITE标识, 因为它会不确定的阻塞程序
            }
        }
    
        // (五)释放接口指针并关闭COM库
        pControl->Release();
        pEvent->Release();
        pGraph->Release();
        CoUninitialize();
    
        return 0;
    }
    

    pControl->Run()运行 Graph,数据在 Filter 中移动并呈现为视频和音频。播放发生在单独的线程上。您可以通过调用 IMediaEvent :: WaitForCompletion 方法来等待播放完成。该方法将阻塞,直到文件播放完毕或经过指定的超时间隔为止。值 INFINITE 意味着应用程序将无限期阻塞,直到文件播放完毕。

    运行程序播放 "test.mp4" 的效果图如下:


    代码下载(VC2015):Github - DShow_simpleVideo


    参考:

    MSDN - DirectShow Application Programming

    MSDN - How To Play a File


  • 相关阅读:
    在没有源代码的情况下调试JAR包..
    Flex游戏篇——游戏开发概述
    CSDN、sina博客在Zoundry中登记的API URL 收藏
    标准博客 API .BLOG APIS
    SAXParseException An invalid XML character 问题的解决
    分布式存储方法
    拨号720错误解决记.txt
    xxx
    硬盘分区后的逻辑结构
    paip sms to blog.txt
  • 原文地址:https://www.cnblogs.com/linuxAndMcu/p/12058101.html
Copyright © 2020-2023  润新知