Search code examples
c++multithreadingvideo-streamingbuffercircular-buffer

Circular buffer of <Mat> holds less than it should


I'm processing a video stream, using a boost circular buffer of Mat in a C++ code. One thread pushes Mat objects:

void* capture(void* arg){
    boost::circular_buffer<Mat> cb(2000);
    Mat frame;
        while ((VideoCapture >> frame), !frame.empty()) {
                pthread_mutex_lock(&mtx);
                cb.push_back(frame);
                pthread_mutex_unlock(&mtx);
        }
}

other thread processes and pops them:

void* process(void* arg){
    while (1){
        Mat frame;
        pthread_mutex_lock(&mtx);
        frame =cb.front();
        cb.pop_front();
        pthread_mutex_unlock(&mtx);
        scan(frame);           
    }
}

However, even with a full buffer, there is no delay compared to the video stream. I checked the first (front) image in the buffer cb[1] and the last (back) image, when the buffer was full cb[1999] and they are both the same, also the same as the last captured image from the stream. It is as if the buffer holds only the last captured image and retrieves it for any called slot. Any ideas why the buffer isn't storing all the images that it should be?


Solution

  • Thanks to Sean Cline i was able to solve this problem. I had to change my capture thread from:

    void* capture(void* arg){
        boost::circular_buffer<Mat> cb(2000);
        Mat frame;
            while ((VideoCapture >> frame), !frame.empty()) {
                    pthread_mutex_lock(&mtx);
                    cb.push_back(frame);
                    pthread_mutex_unlock(&mtx);
            }
    }
    

    to:

    void* capture(void* arg){
        boost::circular_buffer<Mat> cb(2000);
        Mat frame;
            while ((VideoCapture >> frame), !frame.empty()) {
                    Mat image;
                    frame.copyTo(image);
                    pthread_mutex_lock(&mtx);
                    cb.push_back(image);
                    pthread_mutex_unlock(&mtx);
            }
    }
    

    So that the Mat object that is pushed into the buffer is declared in the same while loop. I used copyTo(), because the Mat frame is used in the conditions of the while loop. This makes all the instances of Mat image have their own buffer instead of sharing one.