Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RAW MMAL Buffer callback #51

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open

Conversation

kaomoneus
Copy link

@kaomoneus kaomoneus commented Dec 17, 2018

Hola! This pull request is rather an idea, and I just ask you to consider it, and if you like it, then I work on making changeset sequence of better quality.

The main goal is to prevent extra copy operation during "grab".
The main idea is to provide user with callback, and comfortable way to release buffer back into pool when we're done with it. So in short when we got a video_buffer_callback, our steps as follows:

  1. Borrow MMAL buffer and pass it into RawBufferCallback function.
  2. Determine point when borrowed buffer is safe to release back into pool.
  3. Release buffer.

For that purpose RaspiCamRawBuffer has been introduced. Which is a wrapper for MMAL buffer. It is passed into RawBufferCallback, and for a while it is out of main frame grabbing pipeline.
It counts references, and once user finished its processing, reference counters will become zero, and buffer is released back into pool.

I have tested this approach in my own application and it allows to achieve much better FPS on high resolution frames.

How to use it

Setup

    class MyClass {
        // ...
        void init() {
            // ...
            raspiCam.setRawBufferCallback(onCamRawBuff, this);
            // ...
        }
        // ...
    }

Callback

    class MyClass {
        // ...
        static void onCamRawBuff(const raspicam::RaspiCamRawBuffer& buffer, void* _thisVoid) {

            auto _this = static_cast<TextureUpdaterBackendContextRpiBase*>(_thisVoid);

            // Prevent local buffer from concurrent usage
            _this->lockLocalBuffer();

            // Save buffer reference.
            // Decrease reference counter for buffer stored before.
            // Increase reference couter for new buffer.
            // If it is the only place we save RaspiCamRawBuffer, then
            // * old buffer will be released,
            // * new buffer will be held until next callback event.
            _this->buffer = buffer;

            _this->unlockLocalBuffer();
        }

        void useBuffer() {
            lockLocalBuffer();
            process(this->buffer.getData());
            unlockLocalBuffer();
        }
        // ...
    }

P.S.: this PR also contains another improvements, I'll probably clean out, since it is subject of another PRs. Namely:

  • RGBA support (it is already proposed by another guy)
  • Ability to select camera port, for sometimes it is better to use MMAL_CAMERA_PREVIEW_PORT.
  • Some refactoring of CMakeLists.txt
  • Some minor refactoring of private_impl.cpp
  • Zero copy mode. Usefull mode, but when use it on my GL textures, I get zeroes (just totally black textures), so it is still unfinished, and I'd probably remove it.

Stepan Dyatkovskiy added 15 commits December 6, 2018 18:20
… been moved into separate 'process_video_buffer'.
public_hdrs_base and srcs_base initialization has been multilined.
Now if you will add new values to these variables, you will see more readable changesets with diff tools.
…eed to use buffers asyncronously on client side. So this commit adds some amount of buffers to recommended buffers for camera component.
…header holder, with custom deleter which releases buffer.
…t. Target texture seems to be filled by zeroes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant