| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #pragma once |
| |
| #include <fbl/unique_ptr.h> |
| #include <fbl/vector.h> |
| #include <zircon/types.h> |
| #include <lib/zx/vmo.h> |
| |
| namespace video { |
| namespace usb { |
| |
| // This class is not thread safe. |
| class VideoBuffer { |
| |
| public: |
| // The position (in bytes) of the start of the frame in the video buffer. |
| typedef uint64_t FrameOffset; |
| |
| // Creates a VideoBuffer with the given VMO buffer handle. |
| // If successful, returns ZX_OK and a pointer to the created |
| // VideoBuffer will be stored in out. |
| static zx_status_t Create(zx::vmo&& vmo, |
| fbl::unique_ptr<VideoBuffer>* out, |
| uint32_t max_frame_size); |
| |
| // Initializes the video buffer for a new streaming session. |
| void Init(); |
| |
| // Finds the next available frame for the driver to write to, and sets |
| // the frame as currently in progress. |
| // Returns ZX_OK if successful, and stores the frame offset into out_offset. |
| // Returns ZX_ERR_NOT_FOUND if no frames were available or ZX_ERR_BAD_STATE |
| // if a frame is in the currently in progress state. |
| zx_status_t GetNewFrame(FrameOffset* out_offset); |
| |
| // Sets the currently in progress frame as completed and ready to consume. |
| // The frame will be locked until FrameRelease is called with its offset. |
| // Returns ZX_OK if successful, or ZX_ERR_NOT_FOUND if no frame is |
| // currently in progress. |
| zx_status_t FrameCompleted(); |
| |
| // Unlocks the frame with the specified offset and sets it as ready to be |
| // reused. |
| // Returns ZX_OK if successful, or ZX_ERR_NOT_FOUND if no locked frame |
| // was found with the given offset. |
| zx_status_t FrameRelease(FrameOffset offset); |
| |
| uint64_t size() const { return size_; } |
| void* virt() const { return virt_; } |
| |
| ~VideoBuffer(); |
| |
| private: |
| VideoBuffer(zx::vmo&& vmo, uint64_t size, void* virt) |
| : vmo_(fbl::move(vmo)), |
| size_(size), |
| virt_(virt) {} |
| |
| // Allocates the free_frames_ and locked_frames_ vectors. |
| zx_status_t Alloc(uint32_t max_frame_size); |
| |
| // VMO backing the video buffer. |
| zx::vmo vmo_; |
| // Size of the VMO. |
| uint64_t size_ = 0; |
| // The mapped address of the start of the video buffer. |
| void* virt_ = nullptr; |
| |
| // Frames that are available for writing to. |
| fbl::Vector<FrameOffset> free_frames_; |
| // Frames that have been locked for the client and should not be overwritten. |
| fbl::Vector<FrameOffset> locked_frames_; |
| |
| // Whether the driver is currently writing to the in_progress_frame_. |
| bool has_in_progress_frame_ = false; |
| // The frame that is currently being written to. |
| // Only valid if in_progress_frame_valid_ is true. |
| FrameOffset in_progress_frame_; |
| }; |
| |
| } // namespace usb |
| } // namespace video |