从同步队列读取错误的前端

时间:2016-05-02 15:07:05

标签: c++ multithreading opencv boost blockingqueue

我在C ++中使用Boost库来为OpenCV中的视频文件帧实现多线程IO队列 我遇到了一个问题,因为Push线程运行良好,但是当读取所有视频帧时,弹出队列的使用者函数总是返回相同的帧,我不知道为什么。

这里是队列类:

#include "videoqueue.h"

VideoQueue::VideoQueue()
{
    std::cout << "Class initialized" << std::endl;
}

void VideoQueue::InitReader(std::string filename)
{
    VideoQueue::cap = cv::VideoCapture(filename);
    if(!cap.isOpened())
    {
        std::cout << "Error opening video file" << std::endl;
    }
    else
    {
        std::cout << "File opened: " << cap.get(cv::CAP_PROP_FRAME_COUNT) << " frames" << std::endl;
        framesAcquired = 0;
        framesAvailable = 0;
    }
}

void VideoQueue::start()
{
    while(framesAcquired < cap.get(cv::CAP_PROP_FRAME_COUNT))
    {
        //frame read from file
        cap.read(captureFrame);
        //safe push
        boost::mutex::scoped_lock lock(queueMutex);
        bool const was_empty = queueFrame.empty();
        queueFrame.push(captureFrame);
        //frames amount updated
        framesAcquired++;
        std::cout << "Frames acquired " << framesAcquired << std::endl;
        framesAvailable = queueFrame.size();
        //mutex unlock
        lock.unlock();
        if(was_empty)
            queueCondition.notify_one();
    }
}

bool VideoQueue::queueEmpty() const
{
    boost::mutex::scoped_lock lock(queueMutex);
    return queueFrame.empty();
}

int VideoQueue::framesQueued()
{
    boost::mutex::scoped_lock lock(queueMutex);
    return queueFrame.size();
}

void VideoQueue::readFrame(cv::Mat &output)
{
    boost::mutex::scoped_lock lock(queueMutex);
    std::cout << "mutex lettura bloccato" << std::endl;
    while(queueFrame.empty())
    {
                std::cout << "aspetto" << std::endl;
        queueCondition.wait(lock);
    }
    output = queueFrame.front();
    queueFrame.pop();
    std::cout << "front pop eseguito" << std::endl;
    //framesAvailable = queueFrame.size();
    framesConsumed++;
    //mutex unlock
    //lock.unlock();
    //queueCondition.notify_one();
    std::cout << "Frames consumed: " << framesConsumed << std::endl;
}

标题为

#ifndef VIDEOQUEUE_H
#define VIDEOQUEUE_H

#include <opencv2/opencv.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/core/core.hpp>
#include <boost/thread.hpp>
#include <string>
#include <iostream>
#include <queue>

class VideoQueue
{
    public:
        VideoQueue();
        void InitReader(std::string filename);
        void start();
        bool queueEmpty() const;
        int framesQueued();
        void readFrame(cv::Mat& output);
    private:
        //std::queue<Mat> frameQueue;
        cv::VideoCapture cap;
        int framesAcquired;
        int framesAvailable;
        int framesConsumed;
        cv::Mat captureFrame;
        cv::Mat outputFrame;
        //concurrent queue
        std::queue<cv::Mat> queueFrame;
        mutable boost::mutex queueMutex;
        boost::condition_variable queueCondition;
};

#endif // VIDEOQUEUE_H

和带有线程初始化的测试程序

#include <iostream>
#include <string>
#include <opencv2/highgui/highgui.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/chrono.hpp>
#include "videoqueue.h"

void wait(int milliseconds)
{
    boost::this_thread::sleep_for(boost::chrono::milliseconds(milliseconds));
}

int main()
{
    VideoQueue prova;
    cv::Mat frame;
    prova.InitReader("/home/exeless/DEV/C++/1_10_rest.avi");
    boost::thread t(&VideoQueue::start, &prova);

    wait(500);
    while(prova.framesQueued()>0)
    {
        wait(100);
        prova.readFrame(frame);
        std::cout << "frames " << prova.framesQueued() << std::endl;
        std::cout << "value " << cv::mean(frame) << std::endl;
        imshow("output",frame);
        cv::waitKey(10);
    }
    t.join();
    return 0;
}

我认为问题出在线程安排的某个地方,但我不知道在哪里。任何帮助都会很棒。

0 个答案:

没有答案