# Why does OpenCV need gstreamer and how to roll back?

**URL:** <https://forum.opencv.org/t/why-does-opencv-need-gstreamer-and-how-to-roll-back/310>\
**Category:** Uncategorized\
**Created:** [December 14, 2020, 2:37pm UTC](https://forum.opencv.org/t/why-does-opencv-need-gstreamer-and-how-to-roll-back/310 "2020-12-14T14:37:50Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![student4K](https://avatars.discourse-cdn.com/v4/letter/s/e79b87/32.png) [@student4K](https://forum.opencv.org/u/student4K)\
**Post date:** [December 14, 2020, 2:37pm UTC](https://forum.opencv.org/t/why-does-opencv-need-gstreamer-and-how-to-roll-back/310/1 "2020-12-14T14:37:50Z")

</div>

I have tried OpenCV cv::VideoCapture on Ubuntu 20.04 and found out, that it uses gstreamer.  
At least I get error messages and capturing not working when using two USB cameras attached (they both work separately up to some FPS issues, but that might be different issue).

So I wanted first to figure out if gstreamer setup is guilty in my issue and if it is possible to not use gstreamer at all and use the old method (accessing V4L directly, I guess) when using cv::VideoCapture?

---

<div class="post-metadata">

**Author:** ![berak](https://avatars.discourse-cdn.com/v4/letter/b/85f322/32.png) [@berak](https://forum.opencv.org/u/berak)\
**Post date:** [December 14, 2020, 2:54pm UTC](https://forum.opencv.org/t/why-does-opencv-need-gstreamer-and-how-to-roll-back/310/2 "2020-12-14T14:54:36Z")

</div>

- on linux, either gstreamer or ffmpeg can be used to read video _files_ (and none of them are mandatory)  
(you can also use gstreamer with webcams, but normally it should use the V4l backend)  
so, imho, you should not “roll back” anything.

- you can specify, which backend to use, like `VideoCapture(0, CAP_V4L)`

- you can set the OPENCV\_VIDEOIO\_DEBUG environment variable, to see, which backends are checked / selected

  

> [@student4K](#):
>
> capturing not working when using two USB cameras attached

“not working” means ? it’s usually a bandwidth problem, a typical usb hub can process a single camera so so, but you might need to decrease the resolution for more than 1 camera on the same hub (or choose a different hub, if you have)

---

<div class="post-metadata">

**Author:** ![crackwitz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/crackwitz/32/14_2.png) [@crackwitz](https://forum.opencv.org/u/crackwitz)\
**Post date:** [December 14, 2020, 9:24pm UTC](https://forum.opencv.org/t/why-does-opencv-need-gstreamer-and-how-to-roll-back/310/3 "2020-12-14T21:24:01Z")

</div>

your FPS issues can stem from the USB hub/controller not being fast enough. that’s particularly the case for USB 2. cameras produce a lot of data. if you attach multiple to the same USB hub/controller, the first gets as much reserved data rate as it wants, while the second gets to fall back on some reduced/compressed mode. plug them into USB ports that are on different controllers.

---

<div class="post-metadata">

**Author:** ![student4K](https://avatars.discourse-cdn.com/v4/letter/s/e79b87/32.png) [@student4K](https://forum.opencv.org/u/student4K)\
**Post date:** [December 20, 2020, 9:17pm UTC](https://forum.opencv.org/t/why-does-opencv-need-gstreamer-and-how-to-roll-back/310/4 "2020-12-20T21:17:35Z")

</div>

Thanks for the quick answers. Switching to V4L backend solves the warnings issue (should have read the docs first :)). I have an issue with FPS on the slower camera (5 real FPS vs. 30 reported by cv::VideoCamera::get call), but that is another issue I guess.

---

<div class="post-metadata">

**Author:** ![student4K](https://avatars.discourse-cdn.com/v4/letter/s/e79b87/32.png) [@student4K](https://forum.opencv.org/u/student4K)\
**Post date:** [December 20, 2020, 9:23pm UTC](https://forum.opencv.org/t/why-does-opencv-need-gstreamer-and-how-to-roll-back/310/5 "2020-12-20T21:23:28Z")

</div>

I used USB 3.0 ports. Actually, I took wrong measurements. The slower camera (“typical” 640x480 30FPS webcam) was quite slow to get the very first frame, whereas the faster one (260FPS with approx. the same resolution as the first one) initialized quicker. Besides, the observation was just 50 frames, so it looked like as if two cameras used the bus sequentially, first the faster camera, and afterwards the slower one. I should have just made longer observations. However, I still have an issue with the slower camera reporting 30 FPS from the CV API, but delivering about 5 FPS in reality.

---

<div class="post-metadata">

**Author:** ![crackwitz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/crackwitz/32/14_2.png) [@crackwitz](https://forum.opencv.org/u/crackwitz)\
**Post date:** [December 20, 2020, 11:20pm UTC](https://forum.opencv.org/t/why-does-opencv-need-gstreamer-and-how-to-roll-back/310/6 "2020-12-20T23:20:36Z")

</div>

post code. as always, cameras produce frames on their own time. if you don’t read them _at least_ as quickly as they’re produced, they WILL queue up and cause all kinds of problems. you absolutely MUST read them in a timely manner. reading from a camera MUST NOT involve any delays.

---

<div class="post-metadata">

**Author:** ![student4K](https://avatars.discourse-cdn.com/v4/letter/s/e79b87/32.png) [@student4K](https://forum.opencv.org/u/student4K)\
**Post date:** [December 21, 2020, 12:00am UTC](https://forum.opencv.org/t/why-does-opencv-need-gstreamer-and-how-to-roll-back/310/7 "2020-12-21T00:00:17Z")

</div>

```
#include <opencv2/videoio.hpp>
#include <chrono>
#include <vector>
#include <stdio.h>
#include <string>
#include <thread>
#include <functional>
#include <unistd.h>
#include <assert.h>
#include "log.hpp"
#include <stdio.h>

namespace chr = std::chrono;
using sclk = std::chrono::steady_clock;

struct Capture
{
    const int MaxCounter = 300;
    const double cols = 640;
    const double rows = 480;
    const double Fps = 30.0;
    std::string devFname;
    int counter{};

    void runCapture()
    {
        // sleep is here to give main thread more time for capture.set(...)
        sleep(1);
        LOG("Have set ", (int)capture.get(cv::CAP_PROP_FPS), "fps ", (int)capture.get(cv::CAP_PROP_FRAME_WIDTH), "x", (int)capture.get(cv::CAP_PROP_FRAME_HEIGHT), " for camera ", devFname);

        sclk::time_point begin = sclk::now();
        while (counter++ < MaxCounter)
        {
            if (! capture.read(mat))
            {
                LOG(devFname, ": Cannot read");
                exit(1);
                return;
            }
        }
        sclk::time_point end = sclk::now();
        const auto fps = 1000.0 * MaxCounter / chr::duration_cast<chr::milliseconds>(end - begin).count();
        LOG("measured frame rate: ", fps);
    }

    Capture(std::string devFname_)
        : devFname(devFname_)
        , capture(devFname, cv::CAP_V4L2)
        , thread(std::bind(&Capture::runCapture, this))
    {
        capture.set(cv::CAP_PROP_FRAME_WIDTH, cols);
        capture.set(cv::CAP_PROP_FRAME_HEIGHT, rows);
        capture.set(cv::CAP_PROP_FPS, Fps);
    }
    ~Capture()
    {
        if (capture.isOpened())
        {
            capture.release();
        }
    }

    void join()
    {
        thread.join();
    }

    cv::VideoCapture capture;
    cv::Mat mat;
    std::thread thread;
};

int main(int argc, char* argv[])
{
    Capture n1(argv[1]);
    n1.join();
}

```

I create one Capture instance per camera (only one is created here to test single camera). Running this code now with 300 frames actually shows 9.5FPS, but that is still not even close to 30. LOG is a function that acquires scoped lock on global mutex, but I got similar results if running without it.

---

<div class="post-metadata">

**Author:** ![crackwitz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/crackwitz/32/14_2.png) [@crackwitz](https://forum.opencv.org/u/crackwitz)\
**Post date:** [December 21, 2020, 1:35am UTC](https://forum.opencv.org/t/why-does-opencv-need-gstreamer-and-how-to-roll-back/310/8 "2020-12-21T01:35:37Z")

</div>

curious. what camera is that specifically? does it have any auto-features that could increase exposure time (reduce frame rate)?

what happens when you try to capture from that camera using ffmpeg, gstreamer, OBS Studio, …?

---

<div class="post-metadata">

**Author:** ![student4K](https://avatars.discourse-cdn.com/v4/letter/s/e79b87/32.png) [@student4K](https://forum.opencv.org/u/student4K)\
**Post date:** [December 21, 2020, 10:35pm UTC](https://forum.opencv.org/t/why-does-opencv-need-gstreamer-and-how-to-roll-back/310/9 "2020-12-21T22:35:57Z")

</div>

The camera is “Trust SpotLight Webcam 1.3 Megapixel USB 2.0”.

With  
`ffmpeg -y -f v4l2 -r 25 -i /dev/video0 out.mp4`  
it indeed recorded 25 fps video.

Surprisingly, now I run a capture using the posted code (but for 1000 frames) and get every time different average, from 7 to 28 FPS per trial.

As for the controls, v4l-ctl shows the following for the available streaming parameters:

> ```
> Streaming Parameters Video Capture:
> Capabilities : timeperframe
> Frames per second: 30.000 (30/1)
> Read buffers : 0
> brightness 0x00980900 (int) : min=-64 max=64 step=1 default=0 value=0
> contrast 0x00980901 (int) : min=0 max=64 step=1 default=32 value=32
> saturation 0x00980902 (int) : min=1 max=128 step=1 default=64 value=64
> hue 0x00980903 (int) : min=-40 max=40 step=1 default=0 value=0
> gamma 0x00980910 (int) : min=72 max=500 step=1 default=100 value=100
> gain 0x00980913 (int) : min=0 max=100 step=1 default=0 value=0
> power_line_frequency 0x00980918 (menu) : min=0 max=2 default=1 value=1
> 0: Disabled
> 1: 50 Hz
> 2: 60 Hz
> sharpness 0x0098091b (int) : min=0 max=6 step=1 default=2 value=2
> backlight_compensation 0x0098091c (int) : min=0 max=2 step=1 default=1 value=1
> exposure_auto 0x009a0901 (menu) : min=0 max=3 default=3 value=3
> 1: Manual Mode
> 3: Aperture Priority Mode
> 
> ```

So I guess this `exposure_auto`should be set to `Aperture Priority Mode`.  
However, cv::VideoCapture::get for cv::CAP\_PROP\_EXPOSURE and cv::CAP\_PROP\_EXPOSUREPROGRAM returns “-1”.

---

<div class="post-metadata">

**Author:** ![crackwitz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/crackwitz/32/14_2.png) [@crackwitz](https://forum.opencv.org/u/crackwitz)\
**Post date:** [December 22, 2020, 8:27pm UTC](https://forum.opencv.org/t/why-does-opencv-need-gstreamer-and-how-to-roll-back/310/10 "2020-12-22T20:27:58Z")

</div>

OpenCV may not expose all possible properties. it should be possible to use v4l-ctl to set those properties before or while OpenCV accesses the camera.

try disabling all auto modes (set to manual) and see if that does anything.

also point your camera at a brightly lit area or shine a flashlight into it. then cover it (darkness). if that makes a difference in frame rates, the camera probably reduces the frame rate to get a better picture.

---

<div class="post-metadata">

**Author:** ![klinkouch](https://avatars.discourse-cdn.com/v4/letter/k/e19b73/32.png) [@klinkouch](https://forum.opencv.org/u/klinkouch)\
**Post date:** [January 2, 2021, 6:11pm UTC](https://forum.opencv.org/t/why-does-opencv-need-gstreamer-and-how-to-roll-back/310/11 "2021-01-02T18:11:14Z")

</div>

Much obliged for the answers.
