blob: 6bb208ee4f7218fddb34aa794389471b8e9d1d81 [file] [log] [blame]
// 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