Неисправное фронтальное чтение из синхронизированной очереди

Я использую библиотеки Boost в C ++ для достижения многопоточной очереди ввода-вывода для кадров видеофайлов в OpenCV
У меня возникла проблема, потому что поток 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

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …