现在的位置: 首页 > 综合 > 正文

[DirectShow] 015 – Filter States

2012年07月22日 ⁄ 综合 ⁄ 共 5800字 ⁄ 字号 评论关闭


Filters have three possible
states: stopped, paused, and running. The purpose of the paused state is to cue
data in the graph, so that a run command responds immediately. The Filter Graph
Manager controls all state transitions. When an application calls IMediaControl::Run

,
IMediaControl::Pause

,
or IMediaControl::Stop

,
the Filter Graph Manager calls the corresponding IMediaFilter

method on all of the filters. Transitions between stopped and running always go
through the paused state, so if the application calls Run
on a stopped
graph, the Filter Graph Manager pauses the graph before running it.

filter
有三种状态:停止、暂停和运行。暂停状态的目的是提取数据到
graph
中,以便运行状态立即响应。
Filter Graph Manager
控制所有状态的转换。当应用程序调用
IMediaControl::Run

IMediaControl::Pause
或者
IMediaControl::Stop
的时候,
Filter Graph Manager
在所有
Filter
上调用相应的
IMediaFilter
方法。在停止和运行状态间转换总是会经过暂停状态,所以如果应用程序在停止的
graph
上调用
Run

Filter Graph Manager
在运行之前会先暂停
graph

For most filters, the running and paused states are identical. Consider
the following filter graph:

大多数
filter
运行和暂停状态是同一个。看下面的
filter graph

   

Source > Transform > Renderer

Assume for now that the source
filter is not a live capture source. When the source filter pauses, it creates
a thread that generates new data and writes it into media samples as quickly as
possible. The thread "pushes" the samples downstream by calling IMemInputPin::Receive

on the transform filter's input pin. The transform filter receives the samples
on the source filter's thread. It may use a worker thread to deliver the
samples to the renderer, but typically it delivers them on the same thread.
While the renderer is paused, it waits to receive a sample. After it receives
one, it blocks and holds that sample indefinitely. If it is a video renderer,
it displays the sample as a poster image, repainting the image as necessary.

假设
source filter
不是一个实时采集
source
。当
source filter
暂停,它创建一个线程以最快的速度产生数据并写到
media sample
中。线程在
transform filter

input pin
上调用
IMemInputPin::Receive
方法。
transform filter

source filter
的线程接收
sample

transform filter
可以使用工作线程传递
sample

renderer
。当
renderer
暂停俄时候,它等待接收
sample
。它接收到一个
sample
以后就无限期的阻塞这个
sample
。如果是一个视频
renderer
,它以图像的形式显示
sample
,有可能的话会重绘。

At this point, the stream is fully cued and ready for rendering.
If the graph remains paused, samples will "pile up" in the graph
behind the first sample, until every filter is blocked in Receive
or GetBuffer
.
No data is lost, though. Once the source thread is unblocked, it simply resumes
from the point where it blocked.

在这里,流是完全提取并准备供
render
使用。如果
graph
其他的部分暂停,第一个
sample
以后的
sample
将堆积在
sample
中,直到每一个
filter
都被阻塞在
Receive

GetBuffer
中。没有数据丢失。当
source
线程激活,它只需要简单从阻塞点恢复就可以。

The source filter and the transform filter ignore the transition
from paused to running—they simply continue to process data as fast as
possible. But when the renderer runs, it starts rendering samples. First it
renders the sample it held while it was paused. Then, each time it receives a
new sample, it calculates the sample's presentation time. (For details, see Time
and Clocks in DirectShow

.) The renderer holds each sample until the
presentation time, at which point it renders the sample. While it waits for the
presentation time, it either blocks in the Receive
method, or receives
new samples on a worker thread with a queue. Filters upstream from the renderer
are not involved in scheduling.

source filter

transform
filter

忽略从暂停到运行的过渡,他们以最快的速度连续处理数据。但是当
renderer
运行的时候,它开始演示
sample
。首先它演示暂停时获得的
sample
,然后每当接收到一个新的
sample
,就计算
sample
的演示时间。
renderer
保存每一个
sample
直到
sample
的演示时间到。当它等待演示时间的时候,它要么阻塞在
Receive
中,要么在工作线程中接收新的
sample

Live sources, such as capture devices, are an exception to this
general architecture. With a live source, it is not appropriate to cue any data
in advance. The application might pause the graph and then wait for a long time
before running it. The graph should not render "stale" samples.
Therefore, a live source produces no samples while paused, only while running.
To signal this fact to the Filter Graph Manager, the source filter's IMediaFilter::GetState

method returns VFW_S_CANT_CUE. This return code indicates that the filter has
switched to the paused state, even though the renderer did not receive any
data.

实时
source
,例如采集设备,是这个机制的一个例外。实时
source
不预先提取数据。应用程序会暂停
graph
,在运行之前等待很长的时间。
graph
不演示旧的
sample
。因此
live source
在暂停的时候不产生
sample
,只有在
run
的时候才产生
sample
。为了向
Filter
Graph Manager

标识这个事实,
source
filter


IMediaFilter::GetState
方法返回
VFW_S_CANT_CUE
。这个标记表明
filter
已经切换到暂停状态。这个时候
renderer
没有接收到任何数据。

When a filter stops, it rejects any more samples delivered to it.
Source filters shut down their streaming threads, and other filters shut down
any worker threads they may have created. Pins decommit their allocators.


filter
停止,它拒绝传递过来的
sample

source
filter

关闭流线程,其他的
filter
也会关闭工作线程,
pin
释放他们约束的
allocator

The Filter Graph Manager carries out all state transitions in upstream
order, starting from the renderer and working backward to the source filter.
This ordering is necessary to prevent samples from being dropped and to prevent
the graph from deadlocking. The most crucial state transitions are between
paused and stopped:

·        



Stopped to paused:

As each filter pauses, it becomes ready to receive samples from the next
filter. The source filter is the last to pause. It creates the streaming thread
and begins delivering samples. Because all of the downstream filters are
paused, no filter rejects any samples. The Filter Graph Manager does not
complete the transition until every renderer in the graph has received a sample
(with the exception of live sources, as described earlier).

·        



Paused to stopped:

When a filter stops, it releases any samples that it holds, which
unblocks any upstream filters waiting in GetBuffer
. If the filter is waiting
for a resource inside the Receive
method, it stops waiting and returns
from Receive
, which unblocks the calling filter. Therefore, when the
Filter Graph Manager stops the next upstream filter, that filter is not blocked
in either GetBuffer
or Receive
, and can respond to the stop
command. The upstream filter might deliver a few extra samples before it gets
the stop command, but the downstream filter simply rejects them, because it
already stopped.

Filter Graph Manager
按照逆向切换所有状态,从
renderer
开始向
source
filter

回溯工作。对于防止漏掉
sample

graph
死锁,这个顺序是必须的。最关键的状态切换发生在暂停和停止之间:

·        



Stopped to paused:

每一个
filter
暂停,都是为从下一个
filter
接收
sample
做准备。
source filter
是最后一个暂停的。它创建流线程,并开始传递
sample
。因为所有的下游线程都已经暂停了。没有
filter
会拒绝
sample
。直到
graph
中的每个
renderer
接收到
sample

Filter Graph Manager
才会完成状态转换。

·        



Paused to stopped:



filter
停止,它会释放它保存的所有
sample
,阻塞在
GetBuffer
中的上游
filter
会恢复。如果
filter

Receive
方法中等待一个资源,它将停止等待并从
Receive
返回,并恢复调用
filter
。上游
filter
在接到停止命令之前可能会传递一些额外的
sampl,
但是下游
filter
会简单俄拒绝,因为下游
filter
已经停止了。

 

 

 

 

 

 

 

抱歉!评论已关闭.