我最近开始tbb
在 Ubuntu 12.04 上使用 4.0+r233-1 版本来加速视频全景拼接器。我看到的错误有点奇怪,希望有人能阐明这个问题。
似乎发生的是令牌无序到达接收节点(尽管我发现很难相信这实际上是 TBB 中的错误)。我在混合视频帧中看到抖动(例如,在显示混合帧 N 时显示混合帧 N + 3,这会导致视频出现断断续续的现象)。我知道这与并行过滤器有关,因为如果我将飞行中的数字标记设置为 1 而不是 4,则不再发生口吃。
我的管道架构如下:
Read Frames Vector from files (serial) -> Warp Frames Vector (parallel) -> Blend Frames Vector (parallel) -> Write Blended Frame to file (serial)
以下是相关的代码片段,我相信可以显示问题区域:
PipelineStitcher.h
class PipelinedStitcher {
public:
PipelinedStitcher(
const std::string& projectFilename,
const std::string& outputFilename,
double scaleFactor);
...
void run();
private:
std::vector<PanoramaParameters> panoParams;
std::vector<cv::Mat> readFramesFromVideos();
std::vector<cv::Mat> warpFrames(const std::vector<cv::Mat>& frames);
cv::Mat blendFrames(std::vector<cv::Mat>& warpedFrames);
};
PipelineStitcher::run()
void PipelinedStitcher::run()
{
parallel_pipeline( 4,
make_filter< void, std::vector<Mat> > (
tbb::filter::serial,
[&](flow_control & fc)-> std::vector<Mat>
{
vector<Mat> frames = readFramesFromVideos();
if(frames.empty())
{
fc.stop();
}
return frames;
}
) &
make_filter< std::vector<Mat>, std::vector<Mat> > (
tbb::filter::parallel,
[&](std::vector<Mat> src) {
vector<Mat> dst = warpFrames(src);
return dst;
}
) &
make_filter< std::vector<Mat>, Mat > (
tbb::filter::parallel,
[&](std::vector<Mat> src) {
Mat dst = blendFrames(src);
return dst;
}
) &
make_filter<Mat, void> (
tbb::filter::serial,
[&](Mat src) {
if(!videoWriter.isOpened())
{
videoWriter.open(outputFilename, CV_FOURCC('D','I','V','X'), 30.0, src.size(), true);
}
videoWriter << src;
imshow("panoramic view", src);
waitKey(3);
}
)
);
videoWriter.release();
}
几个问题:
- 既然
warpFrames
, 和blendFrames
两者都访问成员变量vector<PanoramaParameters> panoParams
, 那么这个成员应该是一个concurrent_vector
类型吗?这些参数在构造函数中创建一次并且永远不会更新。 - 什么可能导致混合帧通过 TBB 无序到达末端过滤器?
2013 年 6 月 19 日更新:
感谢@AlexeyKukanov,我能够证明令牌肯定是按顺序到达的。似乎发生的情况是,当所有 CPU 内核都处于 100% 利用率时,源过滤器或接收器过滤器都会出现缓冲问题。我有一个 4 核处理器,一旦我允许 4 个令牌在飞行中,CPU 就会完全饱和并且开始出现口吃。但是,当 1、2 或 3 个令牌在飞行时,似乎没有任何卡顿。
任何帮助将不胜感激!