blob: 55c416bb61053961bd01b4795ca76e39706e2eff [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.
#ifndef SRC_CAMERA_DRIVERS_USB_VIDEO_UVC_FORMAT_H_
#define SRC_CAMERA_DRIVERS_USB_VIDEO_UVC_FORMAT_H_
#include <ddk/device.h>
#include <fbl/vector.h>
#include <fuchsia/camera/cpp/fidl.h>
#include <usb/usb.h>
#include <zircon/compiler.h>
#include <zircon/hw/usb.h>
#include <zircon/hw/usb/video.h>
namespace video {
namespace usb {
// Decoded video dimensions and other frame-specific characteristics
// supported by frame-based formats.
struct UvcFrameDesc {
uint8_t index;
// Specified in 100ns units.
uint32_t default_frame_interval;
uint16_t width;
uint16_t height;
// The number of bytes per line of video.
uint32_t stride;
};
enum UvcPixelFormat {
INVALID, // default value, not supported
BGRA32, // 32bpp BGRA, 1 plane.
I420,
M420,
NV12,
YUY2,
MJPEG
};
// This is a flattened structure. Instead of having a
// UvcFormat which has a vector of UvcFrameDesc, we create one
// UvcFormat for each framedesc.
struct UvcFormat {
uint8_t format_index;
UvcPixelFormat pixel_format;
uint8_t bits_per_pixel;
// Frame description
uint8_t frame_index;
// Specified in 100ns units.
uint32_t default_frame_interval;
uint16_t width;
uint16_t height;
// The number of bytes per line of video.
uint32_t stride;
uint8_t default_frame_index;
};
fuchsia::camera::VideoFormat ToFidl(const UvcFormat &format_in);
bool Compare(const fuchsia::camera::VideoFormat &vf, const UvcFormat &uf);
class UvcFormatList {
public:
size_t Size() { return formats_.size(); }
zx_status_t ParseUsbDescriptor(usb_video_vc_desc_header *format_desc,
usb_desc_iter_t *iter);
uint32_t number_of_formats() { return number_of_formats_; }
bool MatchFormat(const fuchsia::camera::VideoFormat &requested_format,
uint8_t *format_index, uint8_t *frame_index,
uint32_t *default_frame_interval) const {
for (const auto &format : formats_) {
if (Compare(requested_format, format)) {
*format_index = format.format_index;
*frame_index = format.frame_index;
*default_frame_interval = format.default_frame_interval;
return true;
}
}
return false;
}
void FillFormats(
fidl::VectorPtr<fuchsia::camera::VideoFormat> &formats) const {
for (auto &format : formats_) {
formats.push_back(ToFidl(format));
}
}
// Make sure we reset number_of_formats_ when this class is moved out.
UvcFormatList(UvcFormatList &&other) {
formats_ = std::move(other.formats_);
number_of_formats_ = other.number_of_formats_;
other.number_of_formats_ = 0;
}
UvcFormatList() = default;
private:
uint32_t number_of_formats_ = 0;
fbl::Vector<UvcFormat> formats_;
};
} // namespace usb
} // namespace video
#endif // SRC_CAMERA_DRIVERS_USB_VIDEO_UVC_FORMAT_H_