Microsoft Media foundation概述(附实例)

Microsoft Media Foundation是微软新一代多媒体开发平台,用以取代原来的Directshow,为了满足现在多媒体播放的高清晰,高品质,颜色管理,以及充分利用硬件加速等功能而建立的新一代开发平台。本文概述了Media Foundation的结构和相关信息,最后附上一个再次基础编写的一个视频播放器,由于时间的原因,视频播放器的功能并不完整,比如,所建立的时间线还没有添加插入播放时间的功能。但是这不影响我们了解和学习Media Foundation。

正如微软给我们的开发文档一样,我们首先应该了解一些基础知识,这对于我们学习很有帮助。首先是流,流的概念很广泛,基本意义也就是按一定序列(顺序)的数据,比如,网络传输有数据流。在Media Foundation中,就是一定序列的媒体数据。然后是压缩,压缩从字面意思也可以明白,就是通过一定的算法重新保存数据或剔除一些不重要的数据信息,以减少数据的大小,压缩分为有损压缩和无损压缩,压缩的过程也就是我们常说的编码,反过来的过程就是解码。第三,容器(container),对于一个已经编码的流,我们不可能直接存储为一个文件,因为,当我们解码的时候,就可能不知道应该用何种解码器,于是,通过一个容器,来保存了一些文件头,用来描述我们编码的数据,那么在解码的时候,就可以从文件头中读取信息,正确解码,如下图(来自msdn):

Microsoft Media foundation概述(附实例)_第1张图片这个是一个典型的容器结构,可以看见视频数据和音频数据交错存储,我们Media Foundation的MedaSource的任务就是解析文件头,然后对交错的数据分布解析为音频流和视频流,然后交由MFT。容器其实离我们不远,就在我们身边,例如,我们常常说的媒体文件的“格式”,其实指的是容器格式,如,MP4,avi,等等,其实指的是容器格式,也就是说,媒体文件的扩展名标明了它使用的容器,这个概念要和我们说的音频格式和视频格式要分开。最后就是格式,刚刚已经说了要和容器格式分开,那么,实际说的视频格式和音频格式,应该是只它的无压缩格式或是压缩格式,具体的,无压缩格式具体有哪些格式,可以在msdn Media Foundation章节中可以查到,有表列出,对于压缩格式,也就是编码格式,如,MP4的编码格式有H.264格式。所以,我们进行这方面的开发应该要将这些概念分清楚。

Media Foundation有两个编程模型,如下图(来自MSDN):

Microsoft Media foundation概述(附实例)_第2张图片本文主要是针对基于Media Foundation控制层的编程模型的分析。右边的模型适用于媒体文件的播放,右边的模型适用于要对媒体数据的访问。

由上图可以看到,程序通过Medal Session来控制管道中数据的流动,也就是说,Media Foundation控制管道的,管道上面呢有一些节点(node)可以分为三类,源节点,转换节点,Sink节点。下面就以MSDN中提供的基本播放框架的程序来说明。

在前面也有提到,源节点的作用就是解析一个媒体的文件头,读取相关信息,如流的数目,每个流的格式等等。然后对文件进行解析,产生数据流,交给下一个节点。这里呢,在具体一点描述:

  HRESULT hr = MFCreateSourceResolver(&pSourceResolver);
    if (FAILED(hr))
    {
        goto done;
    }

    // Use the source resolver to create the media source.

    // Note: For simplicity this sample uses the synchronous method to create 
    // the media source. However, creating a media source can take a noticeable
    // amount of time, especially for a network source. For a more responsive 
    // UI, use the asynchronous BeginCreateObjectFromURL method.

    hr = pSourceResolver->CreateObjectFromURL(
        sURL,                       // URL of the source.
        MF_RESOLUTION_MEDIASOURCE,  // Create a source object.
        NULL,                       // Optional property store.
        &ObjectType,        // Receives the created object type. 
        &pSource            // Receives a pointer to the media source.
        );
    if (FAILED(hr))
    {
        goto done;
    }

    // Get the IMFMediaSource interface from the media source.
    hr = pSource->QueryInterface(IID_PPV_ARGS(ppSource));
MFCreateSourceResolver这个函数就会查找注册表(有规定的目录,具体自己查),通过文件的扩展名,找到相应的处理程序,建立Source对象并返回pSource接口指针。通过这个接口指针,就可以获取有关这个文件的信息,然后创建一个管道Topology,创建一个源节点,将这些信息给源节点,再把这个节点给Topolgy。如下:
 HRESULT hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &pNode);
    if (FAILED(hr))
    {
        goto done;
    }

    // Set the attributes.
    hr = pNode->SetUnknown(MF_TOPONODE_SOURCE, pSource);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pNode->SetUnknown(MF_TOPONODE_PRESENTATION_DESCRIPTOR, pPD);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pNode->SetUnknown(MF_TOPONODE_STREAM_DESCRIPTOR, pSD);
    if (FAILED(hr))
    {
        goto done;
    }
    
    // Add the node to the topology.
    hr = pTopology->AddNode(pNode);

这时候,我们再创建一个输出节点,首先创建一个 Activation Objects对象,并返回 IMFActivate 接口,它是一个帮助对象,用于建立Sink,SInk我们可以理解为使用已经解码的数据产生图像及音频的一个节点:
 HRESULT hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &pNode);
    if (FAILED(hr))
    {
        goto done;
    }

    // Set the object pointer.
    hr = pNode->SetObject(pActivate);
    if (FAILED(hr))
    {
        goto done;
    }

    // Set the stream sink ID attribute.
    hr = pNode->SetUINT32(MF_TOPONODE_STREAMID, dwId);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pNode->SetUINT32(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, FALSE);
    if (FAILED(hr))
    {
        goto done;
    }
hr = pTopology->AddNode(pNode);

设置节点的信息,然后添加到管道。

接着是将源节点和输出节点连接:

 hr = pSourceNode->ConnectOutput(0, pOutputNode, 0);
最后,将这个管道给Media Session:
 hr = m_pSession->SetTopology(0, pTopology);
这个时候,我们就可以利用Media Foundation来控制如播放,暂停,停止等操作了。但是大家也许奇怪,为什么没有转换节点,转换节点的作用其实就是解码,我们并没有设置转换节点,可是怎么播放了呢。

这里就有一个概念,就是partial Topology,这个技术,Media Session会根据你的源节点的输出格式来自动到注册表中(固定位置,自己了解)查找解码器,然后可以接受源节点的输出格式的解码器,然后Media Session将MFT转换节点添加到管道中。所以我们尽管没有设置解码器,但是照样播放了,就是这个原因。

说到这里呢,Media Session的播放模型就是这样的。下面还有补充说明:

Media Foundation在不同的系统平台上,功能有所不同,但是最低要求是Vista系统以上,越往后,系统平台越新,功能也更加强大。Media Foundation默认支持的格式非常有限,在MSDN中有说明,对于如RM,RMVB,FLV等格式,默认的Media Foundation不支持,如果要支持,必须要我们自己编写插件,并注册到系统,才可以对别的格式支持。如,MP4,AVI,这样的格式也支持,但是我们前面说过,这些知识容器格式,但是如果一个文件的编码器格式与Media Foundation不支持,也不能播放,在Media Foundation中,MP4格式的编解码器为H.264。如果要支持别的编码器,也需要自己编写插件。

基本情况就说明到这些,下面是一个实例图:

Microsoft Media foundation概述(附实例)_第3张图片

该程序在win7系统,vs2010下基于对话框程序框架编写。

资源链接地址:http://download.csdn.net/detail/xinzhiyounizhiyouni/6398691


你可能感兴趣的:(Media,Foundation,视频)