Microsoft Media Foundation是微软新一代多媒体开发平台,用以取代原来的Directshow,为了满足现在多媒体播放的高清晰,高品质,颜色管理,以及充分利用硬件加速等功能而建立的新一代开发平台。本文概述了Media Foundation的结构和相关信息,最后附上一个再次基础编写的一个视频播放器,由于时间的原因,视频播放器的功能并不完整,比如,所建立的时间线还没有添加插入播放时间的功能。但是这不影响我们了解和学习Media Foundation。
正如微软给我们的开发文档一样,我们首先应该了解一些基础知识,这对于我们学习很有帮助。首先是流,流的概念很广泛,基本意义也就是按一定序列(顺序)的数据,比如,网络传输有数据流。在Media Foundation中,就是一定序列的媒体数据。然后是压缩,压缩从字面意思也可以明白,就是通过一定的算法重新保存数据或剔除一些不重要的数据信息,以减少数据的大小,压缩分为有损压缩和无损压缩,压缩的过程也就是我们常说的编码,反过来的过程就是解码。第三,容器(container),对于一个已经编码的流,我们不可能直接存储为一个文件,因为,当我们解码的时候,就可能不知道应该用何种解码器,于是,通过一个容器,来保存了一些文件头,用来描述我们编码的数据,那么在解码的时候,就可以从文件头中读取信息,正确解码,如下图(来自msdn):
这个是一个典型的容器结构,可以看见视频数据和音频数据交错存储,我们Media Foundation的MedaSource的任务就是解析文件头,然后对交错的数据分布解析为音频流和视频流,然后交由MFT。容器其实离我们不远,就在我们身边,例如,我们常常说的媒体文件的“格式”,其实指的是容器格式,如,MP4,avi,等等,其实指的是容器格式,也就是说,媒体文件的扩展名标明了它使用的容器,这个概念要和我们说的音频格式和视频格式要分开。最后就是格式,刚刚已经说了要和容器格式分开,那么,实际说的视频格式和音频格式,应该是只它的无压缩格式或是压缩格式,具体的,无压缩格式具体有哪些格式,可以在msdn Media Foundation章节中可以查到,有表列出,对于压缩格式,也就是编码格式,如,MP4的编码格式有H.264格式。所以,我们进行这方面的开发应该要将这些概念分清楚。
Media Foundation有两个编程模型,如下图(来自MSDN):
本文主要是针对基于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。如下:
这时候,我们再创建一个输出节点,首先创建一个 Activation Objects对象,并返回 IMFActivate 接口,它是一个帮助对象,用于建立Sink,SInk我们可以理解为使用已经解码的数据产生图像及音频的一个节点: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);
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。如果要支持别的编码器,也需要自己编写插件。
基本情况就说明到这些,下面是一个实例图:
该程序在win7系统,vs2010下基于对话框程序框架编写。
资源链接地址:http://download.csdn.net/detail/xinzhiyounizhiyouni/6398691