Directshow中Filter开发基础[4]

[入库:2005年8月19日] [更新:2007年3月24日]

本文简介:选择自 aoosang 的 blog

// propagate endofstream call downstream, via your output pin(s).
for (each output pin)
{
hr = poutputpin->deliverendofstream();
}
return s_ok;
}
cbaseoutputpin::deliverendofstream调用了与输出pin连接的输入pin的ipin::endofstream方法来通知下游的filter数据流即将停止了。
5 flushing data
下面的伪代码演示ipin::beginflush方法
hresult cmyinputpin::beginflush()
{
cautolock lock_it(m_plock);

// first, make sure the receive method will fail from now on.
hresult hr = cbaseinputpin::beginflush();

// force downstream filters to release samples. if our receive method
// is blocked in getbuffer or deliver, this will unblock it.
for (each output pin)
{
hr = poutputpin->deliverbeginflush();
}

// unblock our receive method if it is waiting on an event.
setevent(m_hsomeeventthatreceiveneedstowaiton);

// at this point, the receive method can't be blocked. make sure
// it finishes, by taking the streaming lock. (not necessary if this
// is the last step.)
{
cautolock lock_2(&m_csreceive);

/* now it's safe to do anything that would crash or hang
if receive were executing. */
}
return hr;
}
当开始flushing的时候,beginflush方法使用了filter锁。如果使用streaming锁不是很安全,因为flush是发生在应用程序中,有可能此时streaming 线程正处于receive方法中。pin要保证receive方法没有被阻塞,否则,后续调用receive方法都会失败。
cbaseinputpin::beginflush设置了一个标志位cbaseinputpin::m_bflushing.,如果这个标志为true,receive方法就会失败。
在下游filter传递beginflush方法的时候,pin一定要保证下游的filter释放他们的samples并且从receive方法中返回。这就保证了输入pin不会阻塞在getbuffer和receive方法中。如果你的pin的receive方法正在等待某种资源,那么geginflush方法就通知设置某些特定事件来结束这种等待,这就保证receive方法能够立即返回,m_bflushing标志就阻止receive方法调用。
对于一些filter来说,这些都是必须要做的,endflush方法通知filter可以重新接收数据了。endflush方法使用的是filter锁。然后向下传播。
hresult cmyinputpin::endflush()
{
cautolock lock_it(m_plock);
for (each output pin)
hr = poutputpin->deliverendflush();
return cbaseinputpin::endflush();
}
cbaseinputpin::endflush重新设置m_bflushing标志为false。这样receive方法就可以开始接收数据了,必须在最后调用这个方法。
6 stopping
stop方法必须unblock receive方法并且decommit filter的内存分配器。这样就使getbuffer返回。stop方法使用了filter锁,然后调用了cbasefilter::stop,这个stop方法调用了filter pins上的cbasepin::inactive方法。
hresult cmyfilter::stop()
{
cautolock lock_it(m_plock);
// inactivate all the pins, to protect the filter resources.
hr = cbasefilter::stop();

/* safe to destroy filter resources used by the streaming thread. */

return hr;
}
override the input pin's inactive method as follows:

hresult cmyinputpin::inactive()
{
// you do not need to hold the filter lock here.
// it is already locked in stop.

// unblock receive.
setevent(m_hsomeeventthatreceiveneedstowaiton);

// make sure receive will fail.
// this also decommits the allocator.
hresult hr = cbaseinputpin::inactive();

// make sure receive has completed, and is not using resources.
{
cautolock c(&m_csreceive);

/* it is now safe to destroy filter resources used by the
streaming thread. */
}
return hr;
}
7 getting buffers
如果你有一个内存分配器来分配资源,那么getbuffer方法采用streaming锁。
hresult cmyinputallocator::getbuffer(
imediasample **ppbuffer,
reference_time *pstarttime,
reference_time *pendtime,
dword dwflags)
{
cautolock cobjectlock(&m_csreceive);

/* use resources. */

return cmemallocator::getbuffer(ppbuffer, pstarttime, pendtime, dwflags);
}
8 streaming threads and the filter graph manager
当filter图表管理器停止graph,它要等待所有的streaming线程停止,
9 summary of filter threading
streaming线程调用的函数
imeminputpin::receive
imeminputpin::receivemultiple
ipin::endofstream
ipin::newsegment
imemallocator::getbuffer

本文关键:Directshow中Filter开发基础
  相关方案
Google
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top