mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-20 00:51:42 +00:00
@@ -6,11 +6,9 @@
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include "SourceImpl.hpp"
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "Instance.hpp"
|
||||
#include "SourceImpl.hpp"
|
||||
#include "wpi/util/PixelFormat.hpp"
|
||||
|
||||
using namespace wpi::cs;
|
||||
|
||||
@@ -67,7 +68,7 @@ Image* Frame::GetNearestImage(int width, int height) const {
|
||||
}
|
||||
|
||||
Image* Frame::GetNearestImage(int width, int height,
|
||||
VideoMode::PixelFormat pixelFormat,
|
||||
wpi::util::PixelFormat pixelFormat,
|
||||
int jpegQuality) const {
|
||||
if (!m_impl) {
|
||||
return nullptr;
|
||||
@@ -93,22 +94,23 @@ Image* Frame::GetNearestImage(int width, int height,
|
||||
|
||||
// 2) Same width, height, different (but non-JPEG) pixelFormat (color conv)
|
||||
// 2a) If we want JPEG output, prefer BGR over other pixel formats
|
||||
if (pixelFormat == VideoMode::kMJPEG) {
|
||||
if (pixelFormat == wpi::util::PixelFormat::kMJPEG) {
|
||||
for (auto i : m_impl->images) {
|
||||
if (i->Is(width, height, VideoMode::kBGR)) {
|
||||
if (i->Is(width, height, wpi::util::PixelFormat::kBGR)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto i : m_impl->images) {
|
||||
if (i->Is(width, height) && i->pixelFormat != VideoMode::kMJPEG) {
|
||||
if (i->Is(width, height) &&
|
||||
i->pixelFormat != wpi::util::PixelFormat::kMJPEG) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// 3) Different width, height, same pixelFormat (only if non-JPEG) (resample)
|
||||
if (pixelFormat != VideoMode::kMJPEG) {
|
||||
if (pixelFormat != wpi::util::PixelFormat::kMJPEG) {
|
||||
// 3a) Smallest image at least width/height in size
|
||||
for (auto i : m_impl->images) {
|
||||
if (i->IsLarger(width, height) && i->pixelFormat == pixelFormat &&
|
||||
@@ -135,7 +137,8 @@ Image* Frame::GetNearestImage(int width, int height,
|
||||
// (color conversion + resample)
|
||||
// 4a) Smallest image at least width/height in size
|
||||
for (auto i : m_impl->images) {
|
||||
if (i->IsLarger(width, height) && i->pixelFormat != VideoMode::kMJPEG &&
|
||||
if (i->IsLarger(width, height) &&
|
||||
i->pixelFormat != wpi::util::PixelFormat::kMJPEG &&
|
||||
(!found || (i->IsSmaller(*found)))) {
|
||||
found = i;
|
||||
}
|
||||
@@ -146,7 +149,7 @@ Image* Frame::GetNearestImage(int width, int height,
|
||||
|
||||
// 4b) Largest image (less than width/height)
|
||||
for (auto i : m_impl->images) {
|
||||
if (i->pixelFormat != VideoMode::kMJPEG &&
|
||||
if (i->pixelFormat != wpi::util::PixelFormat::kMJPEG &&
|
||||
(!found || (i->IsLarger(*found)))) {
|
||||
found = i;
|
||||
}
|
||||
@@ -158,7 +161,7 @@ Image* Frame::GetNearestImage(int width, int height,
|
||||
// 5) Same width, height, JPEG pixelFormat (decompression). As there may be
|
||||
// multiple JPEG images, find the highest quality one.
|
||||
for (auto i : m_impl->images) {
|
||||
if (i->Is(width, height, VideoMode::kMJPEG) &&
|
||||
if (i->Is(width, height, wpi::util::PixelFormat::kMJPEG) &&
|
||||
(!found || i->jpegQuality > found->jpegQuality)) {
|
||||
found = i;
|
||||
// consider one without a quality setting to be the highest quality
|
||||
@@ -175,7 +178,8 @@ Image* Frame::GetNearestImage(int width, int height,
|
||||
// 6) Different width, height, JPEG pixelFormat (decompression)
|
||||
// 6a) Smallest image at least width/height in size
|
||||
for (auto i : m_impl->images) {
|
||||
if (i->IsLarger(width, height) && i->pixelFormat == VideoMode::kMJPEG &&
|
||||
if (i->IsLarger(width, height) &&
|
||||
i->pixelFormat == wpi::util::PixelFormat::kMJPEG &&
|
||||
(!found || (i->IsSmaller(*found)))) {
|
||||
found = i;
|
||||
}
|
||||
@@ -186,7 +190,7 @@ Image* Frame::GetNearestImage(int width, int height,
|
||||
|
||||
// 6b) Largest image (less than width/height)
|
||||
for (auto i : m_impl->images) {
|
||||
if (i->pixelFormat != VideoMode::kMJPEG &&
|
||||
if (i->pixelFormat != wpi::util::PixelFormat::kMJPEG &&
|
||||
(!found || (i->IsLarger(*found)))) {
|
||||
found = i;
|
||||
}
|
||||
@@ -199,7 +203,7 @@ Image* Frame::GetNearestImage(int width, int height,
|
||||
return m_impl->images.empty() ? nullptr : m_impl->images[0];
|
||||
}
|
||||
|
||||
Image* Frame::ConvertImpl(Image* image, VideoMode::PixelFormat pixelFormat,
|
||||
Image* Frame::ConvertImpl(Image* image, wpi::util::PixelFormat pixelFormat,
|
||||
int requiredJpegQuality, int defaultJpegQuality) {
|
||||
if (!image || image->Is(image->width, image->height, pixelFormat,
|
||||
requiredJpegQuality)) {
|
||||
@@ -211,169 +215,171 @@ Image* Frame::ConvertImpl(Image* image, VideoMode::PixelFormat pixelFormat,
|
||||
// anything else with it. Note that if the destination format is JPEG, we
|
||||
// still need to do this (unless it was already a JPEG, in which case we
|
||||
// would have returned above).
|
||||
if (cur->pixelFormat == VideoMode::kMJPEG) {
|
||||
if (cur->pixelFormat == wpi::util::PixelFormat::kMJPEG) {
|
||||
cur = ConvertMJPEGToBGR(cur);
|
||||
if (pixelFormat == VideoMode::kBGR) {
|
||||
if (pixelFormat == wpi::util::PixelFormat::kBGR) {
|
||||
return cur;
|
||||
}
|
||||
}
|
||||
|
||||
// Color convert
|
||||
switch (pixelFormat) {
|
||||
case VideoMode::kRGB565:
|
||||
case wpi::util::PixelFormat::kRGB565:
|
||||
// If source is YUYV, UYVY, Gray, or Y16, need to convert to BGR first
|
||||
if (cur->pixelFormat == VideoMode::kYUYV) {
|
||||
if (cur->pixelFormat == wpi::util::PixelFormat::kYUYV) {
|
||||
// Check to see if BGR version already exists...
|
||||
if (Image* newImage =
|
||||
GetExistingImage(cur->width, cur->height, VideoMode::kBGR)) {
|
||||
if (Image* newImage = GetExistingImage(cur->width, cur->height,
|
||||
wpi::util::PixelFormat::kBGR)) {
|
||||
cur = newImage;
|
||||
} else {
|
||||
cur = ConvertYUYVToBGR(cur);
|
||||
}
|
||||
} else if (cur->pixelFormat == VideoMode::kUYVY) {
|
||||
} else if (cur->pixelFormat == wpi::util::PixelFormat::kUYVY) {
|
||||
// Check to see if BGR version already exists...
|
||||
if (Image* newImage =
|
||||
GetExistingImage(cur->width, cur->height, VideoMode::kBGR)) {
|
||||
if (Image* newImage = GetExistingImage(cur->width, cur->height,
|
||||
wpi::util::PixelFormat::kBGR)) {
|
||||
cur = newImage;
|
||||
} else {
|
||||
cur = ConvertUYVYToBGR(cur);
|
||||
}
|
||||
} else if (cur->pixelFormat == VideoMode::kGray) {
|
||||
} else if (cur->pixelFormat == wpi::util::PixelFormat::kGray) {
|
||||
// Check to see if BGR version already exists...
|
||||
if (Image* newImage =
|
||||
GetExistingImage(cur->width, cur->height, VideoMode::kBGR)) {
|
||||
if (Image* newImage = GetExistingImage(cur->width, cur->height,
|
||||
wpi::util::PixelFormat::kBGR)) {
|
||||
cur = newImage;
|
||||
} else {
|
||||
cur = ConvertGrayToBGR(cur);
|
||||
}
|
||||
} else if (cur->pixelFormat == VideoMode::kY16) {
|
||||
} else if (cur->pixelFormat == wpi::util::PixelFormat::kY16) {
|
||||
// Check to see if BGR version already exists...
|
||||
if (Image* newImage =
|
||||
GetExistingImage(cur->width, cur->height, VideoMode::kBGR)) {
|
||||
if (Image* newImage = GetExistingImage(cur->width, cur->height,
|
||||
wpi::util::PixelFormat::kBGR)) {
|
||||
cur = newImage;
|
||||
} else if (Image* newImage = GetExistingImage(cur->width, cur->height,
|
||||
VideoMode::kGray)) {
|
||||
} else if (Image* newImage =
|
||||
GetExistingImage(cur->width, cur->height,
|
||||
wpi::util::PixelFormat::kGray)) {
|
||||
cur = ConvertGrayToBGR(newImage);
|
||||
} else {
|
||||
cur = ConvertGrayToBGR(ConvertY16ToGray(cur));
|
||||
}
|
||||
}
|
||||
return ConvertBGRToRGB565(cur);
|
||||
case VideoMode::kGray:
|
||||
case VideoMode::kY16:
|
||||
case wpi::util::PixelFormat::kGray:
|
||||
case wpi::util::PixelFormat::kY16:
|
||||
// If source is also grayscale, convert directly
|
||||
if (pixelFormat == VideoMode::kGray &&
|
||||
cur->pixelFormat == VideoMode::kY16) {
|
||||
if (pixelFormat == wpi::util::PixelFormat::kGray &&
|
||||
cur->pixelFormat == wpi::util::PixelFormat::kY16) {
|
||||
return ConvertY16ToGray(cur);
|
||||
} else if (pixelFormat == VideoMode::kY16 &&
|
||||
cur->pixelFormat == VideoMode::kGray) {
|
||||
} else if (pixelFormat == wpi::util::PixelFormat::kY16 &&
|
||||
cur->pixelFormat == wpi::util::PixelFormat::kGray) {
|
||||
return ConvertGrayToY16(cur);
|
||||
}
|
||||
// If source is YUYV, UYVY, convert directly to Gray
|
||||
// If RGB565, need to convert to BGR first
|
||||
if (cur->pixelFormat == VideoMode::kYUYV) {
|
||||
if (cur->pixelFormat == wpi::util::PixelFormat::kYUYV) {
|
||||
cur = ConvertYUYVToGray(cur);
|
||||
} else if (cur->pixelFormat == VideoMode::kUYVY) {
|
||||
} else if (cur->pixelFormat == wpi::util::PixelFormat::kUYVY) {
|
||||
cur = ConvertUYVYToGray(cur);
|
||||
} else if (cur->pixelFormat == VideoMode::kRGB565) {
|
||||
} else if (cur->pixelFormat == wpi::util::PixelFormat::kRGB565) {
|
||||
// Check to see if BGR version already exists...
|
||||
if (Image* newImage =
|
||||
GetExistingImage(cur->width, cur->height, VideoMode::kBGR)) {
|
||||
if (Image* newImage = GetExistingImage(cur->width, cur->height,
|
||||
wpi::util::PixelFormat::kBGR)) {
|
||||
cur = newImage;
|
||||
} else {
|
||||
cur = ConvertRGB565ToBGR(cur);
|
||||
}
|
||||
cur = ConvertBGRToGray(cur);
|
||||
}
|
||||
if (pixelFormat == VideoMode::kY16) {
|
||||
if (pixelFormat == wpi::util::PixelFormat::kY16) {
|
||||
cur = ConvertGrayToY16(cur);
|
||||
}
|
||||
return cur;
|
||||
case VideoMode::kBGR:
|
||||
case VideoMode::kMJPEG:
|
||||
if (cur->pixelFormat == VideoMode::kYUYV) {
|
||||
case wpi::util::PixelFormat::kBGR:
|
||||
case wpi::util::PixelFormat::kMJPEG:
|
||||
if (cur->pixelFormat == wpi::util::PixelFormat::kYUYV) {
|
||||
cur = ConvertYUYVToBGR(cur);
|
||||
} else if (cur->pixelFormat == VideoMode::kUYVY) {
|
||||
} else if (cur->pixelFormat == wpi::util::PixelFormat::kUYVY) {
|
||||
cur = ConvertUYVYToBGR(cur);
|
||||
} else if (cur->pixelFormat == VideoMode::kRGB565) {
|
||||
} else if (cur->pixelFormat == wpi::util::PixelFormat::kRGB565) {
|
||||
cur = ConvertRGB565ToBGR(cur);
|
||||
} else if (cur->pixelFormat == VideoMode::kGray) {
|
||||
if (pixelFormat == VideoMode::kBGR) {
|
||||
} else if (cur->pixelFormat == wpi::util::PixelFormat::kGray) {
|
||||
if (pixelFormat == wpi::util::PixelFormat::kBGR) {
|
||||
return ConvertGrayToBGR(cur);
|
||||
} else {
|
||||
return ConvertGrayToMJPEG(cur, defaultJpegQuality);
|
||||
}
|
||||
} else if (cur->pixelFormat == VideoMode::kY16) {
|
||||
} else if (cur->pixelFormat == wpi::util::PixelFormat::kY16) {
|
||||
// Check to see if Gray version already exists...
|
||||
if (Image* newImage =
|
||||
GetExistingImage(cur->width, cur->height, VideoMode::kGray)) {
|
||||
if (Image* newImage = GetExistingImage(cur->width, cur->height,
|
||||
wpi::util::PixelFormat::kGray)) {
|
||||
cur = newImage;
|
||||
} else {
|
||||
cur = ConvertY16ToGray(cur);
|
||||
}
|
||||
if (pixelFormat == VideoMode::kBGR) {
|
||||
if (pixelFormat == wpi::util::PixelFormat::kBGR) {
|
||||
return ConvertGrayToBGR(cur);
|
||||
} else {
|
||||
return ConvertGrayToMJPEG(cur, defaultJpegQuality);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VideoMode::kBGRA:
|
||||
case wpi::util::PixelFormat::kBGRA:
|
||||
// If source is RGB565, YUYV, UYVY, Gray or Y16, need to convert to BGR
|
||||
// first
|
||||
if (cur->pixelFormat == VideoMode::kRGB565) {
|
||||
if (cur->pixelFormat == wpi::util::PixelFormat::kRGB565) {
|
||||
// Check to see if BGR version already exists...
|
||||
if (Image* newImage =
|
||||
GetExistingImage(cur->width, cur->height, VideoMode::kBGR)) {
|
||||
if (Image* newImage = GetExistingImage(cur->width, cur->height,
|
||||
wpi::util::PixelFormat::kBGR)) {
|
||||
cur = newImage;
|
||||
} else {
|
||||
cur = ConvertRGB565ToBGR(cur);
|
||||
}
|
||||
} else if (cur->pixelFormat == VideoMode::kYUYV) {
|
||||
} else if (cur->pixelFormat == wpi::util::PixelFormat::kYUYV) {
|
||||
// Check to see if BGR version already exists...
|
||||
if (Image* newImage =
|
||||
GetExistingImage(cur->width, cur->height, VideoMode::kBGR)) {
|
||||
if (Image* newImage = GetExistingImage(cur->width, cur->height,
|
||||
wpi::util::PixelFormat::kBGR)) {
|
||||
cur = newImage;
|
||||
} else {
|
||||
cur = ConvertYUYVToBGR(cur);
|
||||
}
|
||||
} else if (cur->pixelFormat == VideoMode::kUYVY) {
|
||||
} else if (cur->pixelFormat == wpi::util::PixelFormat::kUYVY) {
|
||||
// Check to see if BGR version already exists...
|
||||
if (Image* newImage =
|
||||
GetExistingImage(cur->width, cur->height, VideoMode::kBGR)) {
|
||||
if (Image* newImage = GetExistingImage(cur->width, cur->height,
|
||||
wpi::util::PixelFormat::kBGR)) {
|
||||
cur = newImage;
|
||||
} else {
|
||||
cur = ConvertUYVYToBGR(cur);
|
||||
}
|
||||
} else if (cur->pixelFormat == VideoMode::kGray) {
|
||||
} else if (cur->pixelFormat == wpi::util::PixelFormat::kGray) {
|
||||
// Check to see if BGR version already exists...
|
||||
if (Image* newImage =
|
||||
GetExistingImage(cur->width, cur->height, VideoMode::kBGR)) {
|
||||
if (Image* newImage = GetExistingImage(cur->width, cur->height,
|
||||
wpi::util::PixelFormat::kBGR)) {
|
||||
cur = newImage;
|
||||
} else {
|
||||
cur = ConvertGrayToBGR(cur);
|
||||
}
|
||||
} else if (cur->pixelFormat == VideoMode::kY16) {
|
||||
} else if (cur->pixelFormat == wpi::util::PixelFormat::kY16) {
|
||||
// Check to see if BGR version already exists...
|
||||
if (Image* newImage =
|
||||
GetExistingImage(cur->width, cur->height, VideoMode::kBGR)) {
|
||||
if (Image* newImage = GetExistingImage(cur->width, cur->height,
|
||||
wpi::util::PixelFormat::kBGR)) {
|
||||
cur = newImage;
|
||||
} else if (Image* newImage = GetExistingImage(cur->width, cur->height,
|
||||
VideoMode::kGray)) {
|
||||
} else if (Image* newImage =
|
||||
GetExistingImage(cur->width, cur->height,
|
||||
wpi::util::PixelFormat::kGray)) {
|
||||
cur = ConvertGrayToBGR(newImage);
|
||||
} else {
|
||||
cur = ConvertGrayToBGR(ConvertY16ToGray(cur));
|
||||
}
|
||||
}
|
||||
return ConvertBGRToBGRA(cur);
|
||||
case VideoMode::kYUYV:
|
||||
case VideoMode::kUYVY:
|
||||
case wpi::util::PixelFormat::kYUYV:
|
||||
case wpi::util::PixelFormat::kUYVY:
|
||||
default:
|
||||
return nullptr; // Unsupported
|
||||
}
|
||||
|
||||
// Compress if destination is JPEG
|
||||
if (pixelFormat == VideoMode::kMJPEG) {
|
||||
if (pixelFormat == wpi::util::PixelFormat::kMJPEG) {
|
||||
cur = ConvertBGRToMJPEG(cur, defaultJpegQuality);
|
||||
}
|
||||
|
||||
@@ -381,14 +387,14 @@ Image* Frame::ConvertImpl(Image* image, VideoMode::PixelFormat pixelFormat,
|
||||
}
|
||||
|
||||
Image* Frame::ConvertMJPEGToBGR(Image* image) {
|
||||
if (!image || image->pixelFormat != VideoMode::kMJPEG) {
|
||||
if (!image || image->pixelFormat != wpi::util::PixelFormat::kMJPEG) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Allocate an BGR image
|
||||
auto newImage =
|
||||
m_impl->source.AllocImage(VideoMode::kBGR, image->width, image->height,
|
||||
image->width * image->height * 3);
|
||||
auto newImage = m_impl->source.AllocImage(wpi::util::PixelFormat::kBGR,
|
||||
image->width, image->height,
|
||||
image->width * image->height * 3);
|
||||
|
||||
// Decode
|
||||
cv::Mat newMat = newImage->AsMat();
|
||||
@@ -404,14 +410,14 @@ Image* Frame::ConvertMJPEGToBGR(Image* image) {
|
||||
}
|
||||
|
||||
Image* Frame::ConvertMJPEGToGray(Image* image) {
|
||||
if (!image || image->pixelFormat != VideoMode::kMJPEG) {
|
||||
if (!image || image->pixelFormat != wpi::util::PixelFormat::kMJPEG) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Allocate an grayscale image
|
||||
auto newImage =
|
||||
m_impl->source.AllocImage(VideoMode::kGray, image->width, image->height,
|
||||
image->width * image->height);
|
||||
m_impl->source.AllocImage(wpi::util::PixelFormat::kGray, image->width,
|
||||
image->height, image->width * image->height);
|
||||
|
||||
// Decode
|
||||
cv::Mat newMat = newImage->AsMat();
|
||||
@@ -427,14 +433,14 @@ Image* Frame::ConvertMJPEGToGray(Image* image) {
|
||||
}
|
||||
|
||||
Image* Frame::ConvertYUYVToBGR(Image* image) {
|
||||
if (!image || image->pixelFormat != VideoMode::kYUYV) {
|
||||
if (!image || image->pixelFormat != wpi::util::PixelFormat::kYUYV) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Allocate a BGR image
|
||||
auto newImage =
|
||||
m_impl->source.AllocImage(VideoMode::kBGR, image->width, image->height,
|
||||
image->width * image->height * 3);
|
||||
auto newImage = m_impl->source.AllocImage(wpi::util::PixelFormat::kBGR,
|
||||
image->width, image->height,
|
||||
image->width * image->height * 3);
|
||||
|
||||
// Convert
|
||||
cv::cvtColor(image->AsMat(), newImage->AsMat(), cv::COLOR_YUV2BGR_YUYV);
|
||||
@@ -449,14 +455,14 @@ Image* Frame::ConvertYUYVToBGR(Image* image) {
|
||||
}
|
||||
|
||||
Image* Frame::ConvertYUYVToGray(Image* image) {
|
||||
if (!image || image->pixelFormat != VideoMode::kYUYV) {
|
||||
if (!image || image->pixelFormat != wpi::util::PixelFormat::kYUYV) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Allocate a grayscale image
|
||||
auto newImage =
|
||||
m_impl->source.AllocImage(VideoMode::kGray, image->width, image->height,
|
||||
image->width * image->height);
|
||||
m_impl->source.AllocImage(wpi::util::PixelFormat::kGray, image->width,
|
||||
image->height, image->width * image->height);
|
||||
|
||||
// Convert
|
||||
cv::cvtColor(image->AsMat(), newImage->AsMat(), cv::COLOR_YUV2GRAY_YUYV);
|
||||
@@ -471,14 +477,14 @@ Image* Frame::ConvertYUYVToGray(Image* image) {
|
||||
}
|
||||
|
||||
Image* Frame::ConvertUYVYToBGR(Image* image) {
|
||||
if (!image || image->pixelFormat != VideoMode::kUYVY) {
|
||||
if (!image || image->pixelFormat != wpi::util::PixelFormat::kUYVY) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Allocate a BGR image
|
||||
auto newImage =
|
||||
m_impl->source.AllocImage(VideoMode::kBGR, image->width, image->height,
|
||||
image->width * image->height * 3);
|
||||
auto newImage = m_impl->source.AllocImage(wpi::util::PixelFormat::kBGR,
|
||||
image->width, image->height,
|
||||
image->width * image->height * 3);
|
||||
|
||||
// Convert
|
||||
cv::cvtColor(image->AsMat(), newImage->AsMat(), cv::COLOR_YUV2BGR_UYVY);
|
||||
@@ -493,14 +499,14 @@ Image* Frame::ConvertUYVYToBGR(Image* image) {
|
||||
}
|
||||
|
||||
Image* Frame::ConvertUYVYToGray(Image* image) {
|
||||
if (!image || image->pixelFormat != VideoMode::kUYVY) {
|
||||
if (!image || image->pixelFormat != wpi::util::PixelFormat::kUYVY) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Allocate a grayscale image
|
||||
auto newImage =
|
||||
m_impl->source.AllocImage(VideoMode::kGray, image->width, image->height,
|
||||
image->width * image->height);
|
||||
m_impl->source.AllocImage(wpi::util::PixelFormat::kGray, image->width,
|
||||
image->height, image->width * image->height);
|
||||
|
||||
// Convert
|
||||
cv::cvtColor(image->AsMat(), newImage->AsMat(), cv::COLOR_YUV2GRAY_UYVY);
|
||||
@@ -515,14 +521,14 @@ Image* Frame::ConvertUYVYToGray(Image* image) {
|
||||
}
|
||||
|
||||
Image* Frame::ConvertBGRToRGB565(Image* image) {
|
||||
if (!image || image->pixelFormat != VideoMode::kBGR) {
|
||||
if (!image || image->pixelFormat != wpi::util::PixelFormat::kBGR) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Allocate a RGB565 image
|
||||
auto newImage =
|
||||
m_impl->source.AllocImage(VideoMode::kRGB565, image->width, image->height,
|
||||
image->width * image->height * 2);
|
||||
auto newImage = m_impl->source.AllocImage(wpi::util::PixelFormat::kRGB565,
|
||||
image->width, image->height,
|
||||
image->width * image->height * 2);
|
||||
|
||||
// Convert
|
||||
cv::cvtColor(image->AsMat(), newImage->AsMat(), cv::COLOR_RGB2BGR565);
|
||||
@@ -537,14 +543,14 @@ Image* Frame::ConvertBGRToRGB565(Image* image) {
|
||||
}
|
||||
|
||||
Image* Frame::ConvertRGB565ToBGR(Image* image) {
|
||||
if (!image || image->pixelFormat != VideoMode::kRGB565) {
|
||||
if (!image || image->pixelFormat != wpi::util::PixelFormat::kRGB565) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Allocate a BGR image
|
||||
auto newImage =
|
||||
m_impl->source.AllocImage(VideoMode::kBGR, image->width, image->height,
|
||||
image->width * image->height * 3);
|
||||
auto newImage = m_impl->source.AllocImage(wpi::util::PixelFormat::kBGR,
|
||||
image->width, image->height,
|
||||
image->width * image->height * 3);
|
||||
|
||||
// Convert
|
||||
cv::cvtColor(image->AsMat(), newImage->AsMat(), cv::COLOR_BGR5652RGB);
|
||||
@@ -559,14 +565,14 @@ Image* Frame::ConvertRGB565ToBGR(Image* image) {
|
||||
}
|
||||
|
||||
Image* Frame::ConvertBGRToGray(Image* image) {
|
||||
if (!image || image->pixelFormat != VideoMode::kBGR) {
|
||||
if (!image || image->pixelFormat != wpi::util::PixelFormat::kBGR) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Allocate a Grayscale image
|
||||
auto newImage =
|
||||
m_impl->source.AllocImage(VideoMode::kGray, image->width, image->height,
|
||||
image->width * image->height);
|
||||
m_impl->source.AllocImage(wpi::util::PixelFormat::kGray, image->width,
|
||||
image->height, image->width * image->height);
|
||||
|
||||
// Convert
|
||||
cv::cvtColor(image->AsMat(), newImage->AsMat(), cv::COLOR_BGR2GRAY);
|
||||
@@ -581,14 +587,14 @@ Image* Frame::ConvertBGRToGray(Image* image) {
|
||||
}
|
||||
|
||||
Image* Frame::ConvertGrayToBGR(Image* image) {
|
||||
if (!image || image->pixelFormat != VideoMode::kGray) {
|
||||
if (!image || image->pixelFormat != wpi::util::PixelFormat::kGray) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Allocate a BGR image
|
||||
auto newImage =
|
||||
m_impl->source.AllocImage(VideoMode::kBGR, image->width, image->height,
|
||||
image->width * image->height * 3);
|
||||
auto newImage = m_impl->source.AllocImage(wpi::util::PixelFormat::kBGR,
|
||||
image->width, image->height,
|
||||
image->width * image->height * 3);
|
||||
|
||||
// Convert
|
||||
cv::cvtColor(image->AsMat(), newImage->AsMat(), cv::COLOR_GRAY2BGR);
|
||||
@@ -603,7 +609,7 @@ Image* Frame::ConvertGrayToBGR(Image* image) {
|
||||
}
|
||||
|
||||
Image* Frame::ConvertBGRToMJPEG(Image* image, int quality) {
|
||||
if (!image || image->pixelFormat != VideoMode::kBGR) {
|
||||
if (!image || image->pixelFormat != wpi::util::PixelFormat::kBGR) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!m_impl) {
|
||||
@@ -617,9 +623,9 @@ Image* Frame::ConvertBGRToMJPEG(Image* image, int quality) {
|
||||
// Per Wikipedia, Q=100 on a sample image results in 8.25 bits per pixel,
|
||||
// this is a little bit more conservative in assuming 50% space savings over
|
||||
// the equivalent BGR image.
|
||||
auto newImage =
|
||||
m_impl->source.AllocImage(VideoMode::kMJPEG, image->width, image->height,
|
||||
image->width * image->height * 1.5);
|
||||
auto newImage = m_impl->source.AllocImage(wpi::util::PixelFormat::kMJPEG,
|
||||
image->width, image->height,
|
||||
image->width * image->height * 1.5);
|
||||
|
||||
// Compress
|
||||
if (m_impl->compressionParams.empty()) {
|
||||
@@ -638,7 +644,7 @@ Image* Frame::ConvertBGRToMJPEG(Image* image, int quality) {
|
||||
}
|
||||
|
||||
Image* Frame::ConvertGrayToMJPEG(Image* image, int quality) {
|
||||
if (!image || image->pixelFormat != VideoMode::kGray) {
|
||||
if (!image || image->pixelFormat != wpi::util::PixelFormat::kGray) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!m_impl) {
|
||||
@@ -652,9 +658,9 @@ Image* Frame::ConvertGrayToMJPEG(Image* image, int quality) {
|
||||
// Per Wikipedia, Q=100 on a sample image results in 8.25 bits per pixel,
|
||||
// this is a little bit more conservative in assuming 25% space savings over
|
||||
// the equivalent grayscale image.
|
||||
auto newImage =
|
||||
m_impl->source.AllocImage(VideoMode::kMJPEG, image->width, image->height,
|
||||
image->width * image->height * 0.75);
|
||||
auto newImage = m_impl->source.AllocImage(
|
||||
wpi::util::PixelFormat::kMJPEG, image->width, image->height,
|
||||
image->width * image->height * 0.75);
|
||||
|
||||
// Compress
|
||||
if (m_impl->compressionParams.empty()) {
|
||||
@@ -673,14 +679,14 @@ Image* Frame::ConvertGrayToMJPEG(Image* image, int quality) {
|
||||
}
|
||||
|
||||
Image* Frame::ConvertGrayToY16(Image* image) {
|
||||
if (!image || image->pixelFormat != VideoMode::kGray) {
|
||||
if (!image || image->pixelFormat != wpi::util::PixelFormat::kGray) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Allocate a Y16 image
|
||||
auto newImage =
|
||||
m_impl->source.AllocImage(VideoMode::kY16, image->width, image->height,
|
||||
image->width * image->height * 2);
|
||||
auto newImage = m_impl->source.AllocImage(wpi::util::PixelFormat::kY16,
|
||||
image->width, image->height,
|
||||
image->width * image->height * 2);
|
||||
|
||||
// Convert with linear scaling
|
||||
image->AsMat().convertTo(newImage->AsMat(), CV_16U, 256);
|
||||
@@ -695,14 +701,14 @@ Image* Frame::ConvertGrayToY16(Image* image) {
|
||||
}
|
||||
|
||||
Image* Frame::ConvertY16ToGray(Image* image) {
|
||||
if (!image || image->pixelFormat != VideoMode::kY16) {
|
||||
if (!image || image->pixelFormat != wpi::util::PixelFormat::kY16) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Allocate a Grayscale image
|
||||
auto newImage =
|
||||
m_impl->source.AllocImage(VideoMode::kGray, image->width, image->height,
|
||||
image->width * image->height);
|
||||
m_impl->source.AllocImage(wpi::util::PixelFormat::kGray, image->width,
|
||||
image->height, image->width * image->height);
|
||||
|
||||
// Scale min to 0 and max to 255
|
||||
cv::normalize(image->AsMat(), newImage->AsMat(), 255, 0, cv::NORM_MINMAX);
|
||||
@@ -717,14 +723,14 @@ Image* Frame::ConvertY16ToGray(Image* image) {
|
||||
}
|
||||
|
||||
Image* Frame::ConvertBGRToBGRA(Image* image) {
|
||||
if (!image || image->pixelFormat != VideoMode::kBGR) {
|
||||
if (!image || image->pixelFormat != wpi::util::PixelFormat::kBGR) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Allocate a RGB565 image
|
||||
auto newImage =
|
||||
m_impl->source.AllocImage(VideoMode::kBGRA, image->width, image->height,
|
||||
image->width * image->height * 4);
|
||||
auto newImage = m_impl->source.AllocImage(wpi::util::PixelFormat::kBGRA,
|
||||
image->width, image->height,
|
||||
image->width * image->height * 4);
|
||||
|
||||
// Convert
|
||||
cv::cvtColor(image->AsMat(), newImage->AsMat(), cv::COLOR_BGR2BGRA);
|
||||
@@ -739,7 +745,7 @@ Image* Frame::ConvertBGRToBGRA(Image* image) {
|
||||
}
|
||||
|
||||
Image* Frame::GetImageImpl(int width, int height,
|
||||
VideoMode::PixelFormat pixelFormat,
|
||||
wpi::util::PixelFormat pixelFormat,
|
||||
int requiredJpegQuality, int defaultJpegQuality) {
|
||||
if (!m_impl) {
|
||||
return nullptr;
|
||||
@@ -759,7 +765,7 @@ Image* Frame::GetImageImpl(int width, int height,
|
||||
// anything else with it. Note that if the destination format is JPEG, we
|
||||
// still need to do this (unless the width/height/compression were the same,
|
||||
// in which case we already returned the existing JPEG above).
|
||||
if (cur->pixelFormat == VideoMode::kMJPEG) {
|
||||
if (cur->pixelFormat == wpi::util::PixelFormat::kMJPEG) {
|
||||
cur = ConvertMJPEGToBGR(cur);
|
||||
}
|
||||
|
||||
@@ -784,7 +790,7 @@ Image* Frame::GetImageImpl(int width, int height,
|
||||
}
|
||||
|
||||
bool Frame::GetCv(cv::Mat& image, int width, int height,
|
||||
VideoMode::PixelFormat pixelFormat) {
|
||||
wpi::util::PixelFormat pixelFormat) {
|
||||
Image* rawImage = GetImage(width, height, pixelFormat);
|
||||
if (!rawImage) {
|
||||
return false;
|
||||
@@ -809,7 +815,7 @@ std::unique_ptr<Image> CreateImageFromBGRA(wpi::cs::SourceImpl* source,
|
||||
cv::Mat finalImage{static_cast<int>(height), static_cast<int>(width), CV_8UC4,
|
||||
const_cast<uint8_t*>(data), stride};
|
||||
std::unique_ptr<Image> dest = source->AllocImage(
|
||||
VideoMode::PixelFormat::kBGR, width, height, width * height * 3);
|
||||
wpi::util::PixelFormat::kBGR, width, height, width * height * 3);
|
||||
cv::cvtColor(finalImage, dest->AsMat(), cv::COLOR_BGRA2BGR);
|
||||
return dest;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
#include <vector>
|
||||
|
||||
#include "Image.hpp"
|
||||
#include "wpi/cs/cscore_cpp.hpp"
|
||||
#include "wpi/util/PixelFormat.hpp"
|
||||
#include "wpi/util/RawFrame.h"
|
||||
#include "wpi/util/SmallVector.hpp"
|
||||
#include "wpi/util/mutex.hpp"
|
||||
|
||||
@@ -109,13 +110,13 @@ class Frame {
|
||||
return m_impl->images[0]->height;
|
||||
}
|
||||
|
||||
int GetOriginalPixelFormat() const {
|
||||
wpi::util::PixelFormat GetOriginalPixelFormat() const {
|
||||
if (!m_impl) {
|
||||
return 0;
|
||||
return wpi::util::PixelFormat::kUnknown;
|
||||
}
|
||||
std::scoped_lock lock(m_impl->mutex);
|
||||
if (m_impl->images.empty()) {
|
||||
return 0;
|
||||
return wpi::util::PixelFormat::kUnknown;
|
||||
}
|
||||
return m_impl->images[0]->pixelFormat;
|
||||
}
|
||||
@@ -156,7 +157,7 @@ class Frame {
|
||||
}
|
||||
|
||||
Image* GetExistingImage(int width, int height,
|
||||
VideoMode::PixelFormat pixelFormat) const {
|
||||
wpi::util::PixelFormat pixelFormat) const {
|
||||
if (!m_impl) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -170,7 +171,7 @@ class Frame {
|
||||
}
|
||||
|
||||
Image* GetExistingImage(int width, int height,
|
||||
VideoMode::PixelFormat pixelFormat,
|
||||
wpi::util::PixelFormat pixelFormat,
|
||||
int jpegQuality) const {
|
||||
if (!m_impl) {
|
||||
return nullptr;
|
||||
@@ -186,18 +187,18 @@ class Frame {
|
||||
|
||||
Image* GetNearestImage(int width, int height) const;
|
||||
Image* GetNearestImage(int width, int height,
|
||||
VideoMode::PixelFormat pixelFormat,
|
||||
wpi::util::PixelFormat pixelFormat,
|
||||
int jpegQuality = -1) const;
|
||||
|
||||
Image* Convert(Image* image, VideoMode::PixelFormat pixelFormat) {
|
||||
if (pixelFormat == VideoMode::kMJPEG) {
|
||||
Image* Convert(Image* image, wpi::util::PixelFormat pixelFormat) {
|
||||
if (pixelFormat == wpi::util::PixelFormat::kMJPEG) {
|
||||
return nullptr;
|
||||
}
|
||||
return ConvertImpl(image, pixelFormat, -1, 80);
|
||||
}
|
||||
Image* ConvertToMJPEG(Image* image, int requiredQuality,
|
||||
int defaultQuality = 80) {
|
||||
return ConvertImpl(image, VideoMode::kMJPEG, requiredQuality,
|
||||
return ConvertImpl(image, wpi::util::PixelFormat::kMJPEG, requiredQuality,
|
||||
defaultQuality);
|
||||
}
|
||||
Image* ConvertMJPEGToBGR(Image* image);
|
||||
@@ -216,28 +217,28 @@ class Frame {
|
||||
Image* ConvertY16ToGray(Image* image);
|
||||
Image* ConvertBGRToBGRA(Image* image);
|
||||
|
||||
Image* GetImage(int width, int height, VideoMode::PixelFormat pixelFormat) {
|
||||
if (pixelFormat == VideoMode::kMJPEG) {
|
||||
Image* GetImage(int width, int height, wpi::util::PixelFormat pixelFormat) {
|
||||
if (pixelFormat == wpi::util::PixelFormat::kMJPEG) {
|
||||
return nullptr;
|
||||
}
|
||||
return GetImageImpl(width, height, pixelFormat, -1, 80);
|
||||
}
|
||||
Image* GetImageMJPEG(int width, int height, int requiredQuality,
|
||||
int defaultQuality = 80) {
|
||||
return GetImageImpl(width, height, VideoMode::kMJPEG, requiredQuality,
|
||||
defaultQuality);
|
||||
return GetImageImpl(width, height, wpi::util::PixelFormat::kMJPEG,
|
||||
requiredQuality, defaultQuality);
|
||||
}
|
||||
|
||||
bool GetCv(cv::Mat& image, VideoMode::PixelFormat pixelFormat) {
|
||||
bool GetCv(cv::Mat& image, wpi::util::PixelFormat pixelFormat) {
|
||||
return GetCv(image, GetOriginalWidth(), GetOriginalHeight(), pixelFormat);
|
||||
}
|
||||
bool GetCv(cv::Mat& image, int width, int height,
|
||||
VideoMode::PixelFormat pixelFormat);
|
||||
wpi::util::PixelFormat pixelFormat);
|
||||
|
||||
private:
|
||||
Image* ConvertImpl(Image* image, VideoMode::PixelFormat pixelFormat,
|
||||
Image* ConvertImpl(Image* image, wpi::util::PixelFormat pixelFormat,
|
||||
int requiredJpegQuality, int defaultJpegQuality);
|
||||
Image* GetImageImpl(int width, int height, VideoMode::PixelFormat pixelFormat,
|
||||
Image* GetImageImpl(int width, int height, wpi::util::PixelFormat pixelFormat,
|
||||
int requiredJpegQuality, int defaultJpegQuality);
|
||||
void DecRef() {
|
||||
if (m_impl && --(m_impl->refcount) == 0) {
|
||||
|
||||
@@ -305,7 +305,7 @@ bool HttpCameraImpl::DeviceStreamFrame(wpi::util::raw_istream& is,
|
||||
// the data directly into it.
|
||||
unsigned int contentLength = v.value();
|
||||
auto image =
|
||||
AllocImage(VideoMode::PixelFormat::kMJPEG, 0, 0, contentLength);
|
||||
AllocImage(wpi::util::PixelFormat::kMJPEG, 0, 0, contentLength);
|
||||
is.read(image->data(), contentLength);
|
||||
if (!m_active || is.has_error()) {
|
||||
return false;
|
||||
@@ -325,7 +325,7 @@ bool HttpCameraImpl::DeviceStreamFrame(wpi::util::raw_istream& is,
|
||||
PutError("did not receive a JPEG image", wpi::util::Now());
|
||||
return false;
|
||||
}
|
||||
PutFrame(VideoMode::PixelFormat::kMJPEG, width, height, imageBuf,
|
||||
PutFrame(wpi::util::PixelFormat::kMJPEG, width, height, imageBuf,
|
||||
wpi::util::Now());
|
||||
}
|
||||
|
||||
@@ -333,9 +333,9 @@ bool HttpCameraImpl::DeviceStreamFrame(wpi::util::raw_istream& is,
|
||||
|
||||
// update video mode if not set
|
||||
std::scoped_lock lock(m_mutex);
|
||||
if (m_mode.pixelFormat != VideoMode::PixelFormat::kMJPEG ||
|
||||
if (m_mode.pixelFormat != wpi::util::PixelFormat::kMJPEG ||
|
||||
m_mode.width == 0 || m_mode.height == 0) {
|
||||
m_mode.pixelFormat = VideoMode::PixelFormat::kMJPEG;
|
||||
m_mode.pixelFormat = wpi::util::PixelFormat::kMJPEG;
|
||||
m_mode.width = width;
|
||||
m_mode.height = height;
|
||||
}
|
||||
@@ -474,9 +474,9 @@ bool HttpCameraImpl::CacheProperties(CS_Status* status) const {
|
||||
|
||||
// Pretty typical set of video modes
|
||||
m_videoModes.clear();
|
||||
m_videoModes.emplace_back(VideoMode::kMJPEG, 640, 480, 30);
|
||||
m_videoModes.emplace_back(VideoMode::kMJPEG, 320, 240, 30);
|
||||
m_videoModes.emplace_back(VideoMode::kMJPEG, 160, 120, 30);
|
||||
m_videoModes.emplace_back(wpi::util::PixelFormat::kMJPEG, 640, 480, 30);
|
||||
m_videoModes.emplace_back(wpi::util::PixelFormat::kMJPEG, 320, 240, 30);
|
||||
m_videoModes.emplace_back(wpi::util::PixelFormat::kMJPEG, 160, 120, 30);
|
||||
|
||||
m_properties_cached = true;
|
||||
return true;
|
||||
@@ -525,7 +525,7 @@ void HttpCameraImpl::SetExposureManual(int value, CS_Status* status) {
|
||||
}
|
||||
|
||||
bool HttpCameraImpl::SetVideoMode(const VideoMode& mode, CS_Status* status) {
|
||||
if (mode.pixelFormat != VideoMode::kMJPEG) {
|
||||
if (mode.pixelFormat != wpi::util::PixelFormat::kMJPEG) {
|
||||
return false;
|
||||
}
|
||||
std::scoped_lock lock(m_mutex);
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
#include <span>
|
||||
@@ -15,7 +14,8 @@
|
||||
#include <vector>
|
||||
|
||||
#include "SourceImpl.hpp"
|
||||
#include "wpi/cs/cscore_cpp.hpp"
|
||||
#include "wpi/cs/VideoMode.hpp"
|
||||
#include "wpi/cs/cscore_c.h"
|
||||
#include "wpi/net/HttpUtil.hpp"
|
||||
#include "wpi/util/StringMap.hpp"
|
||||
#include "wpi/util/condition_variable.hpp"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <opencv2/core/core.hpp>
|
||||
|
||||
#include "default_init_allocator.hpp"
|
||||
#include "wpi/cs/cscore_cpp.hpp"
|
||||
#include "wpi/util/PixelFormat.hpp"
|
||||
|
||||
namespace wpi::cs {
|
||||
|
||||
@@ -53,20 +53,20 @@ class Image {
|
||||
cv::Mat AsMat() {
|
||||
int type;
|
||||
switch (pixelFormat) {
|
||||
case VideoMode::kYUYV:
|
||||
case VideoMode::kRGB565:
|
||||
case VideoMode::kY16:
|
||||
case VideoMode::kUYVY:
|
||||
case wpi::util::PixelFormat::kYUYV:
|
||||
case wpi::util::PixelFormat::kRGB565:
|
||||
case wpi::util::PixelFormat::kY16:
|
||||
case wpi::util::PixelFormat::kUYVY:
|
||||
type = CV_8UC2;
|
||||
break;
|
||||
case VideoMode::kBGR:
|
||||
case wpi::util::PixelFormat::kBGR:
|
||||
type = CV_8UC3;
|
||||
break;
|
||||
case VideoMode::kBGRA:
|
||||
case wpi::util::PixelFormat::kBGRA:
|
||||
type = CV_8UC4;
|
||||
break;
|
||||
case VideoMode::kGray:
|
||||
case VideoMode::kMJPEG:
|
||||
case wpi::util::PixelFormat::kGray:
|
||||
case wpi::util::PixelFormat::kMJPEG:
|
||||
default:
|
||||
type = CV_8UC1;
|
||||
break;
|
||||
@@ -76,18 +76,18 @@ class Image {
|
||||
|
||||
int GetStride() const {
|
||||
switch (pixelFormat) {
|
||||
case VideoMode::kYUYV:
|
||||
case VideoMode::kRGB565:
|
||||
case VideoMode::kY16:
|
||||
case VideoMode::kUYVY:
|
||||
case wpi::util::PixelFormat::kYUYV:
|
||||
case wpi::util::PixelFormat::kRGB565:
|
||||
case wpi::util::PixelFormat::kY16:
|
||||
case wpi::util::PixelFormat::kUYVY:
|
||||
return 2 * width;
|
||||
case VideoMode::kBGR:
|
||||
case wpi::util::PixelFormat::kBGR:
|
||||
return 3 * width;
|
||||
case VideoMode::kBGRA:
|
||||
case wpi::util::PixelFormat::kBGRA:
|
||||
return 4 * width;
|
||||
case VideoMode::kGray:
|
||||
case wpi::util::PixelFormat::kGray:
|
||||
return width;
|
||||
case VideoMode::kMJPEG:
|
||||
case wpi::util::PixelFormat::kMJPEG:
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -98,15 +98,16 @@ class Image {
|
||||
bool Is(int width_, int height_) {
|
||||
return width == width_ && height == height_;
|
||||
}
|
||||
bool Is(int width_, int height_, VideoMode::PixelFormat pixelFormat_) {
|
||||
bool Is(int width_, int height_, wpi::util::PixelFormat pixelFormat_) {
|
||||
return width == width_ && height == height_ && pixelFormat == pixelFormat_;
|
||||
}
|
||||
bool Is(int width_, int height_, VideoMode::PixelFormat pixelFormat_,
|
||||
bool Is(int width_, int height_, wpi::util::PixelFormat pixelFormat_,
|
||||
int jpegQuality_) {
|
||||
// Consider +/-5 on JPEG quality to be "close enough"
|
||||
return width == width_ && height == height_ &&
|
||||
pixelFormat == pixelFormat_ &&
|
||||
(pixelFormat != VideoMode::kMJPEG || jpegQuality_ == -1 ||
|
||||
(pixelFormat != wpi::util::PixelFormat::kMJPEG ||
|
||||
jpegQuality_ == -1 ||
|
||||
(jpegQuality != -1 && std::abs(jpegQuality - jpegQuality_) <= 5));
|
||||
}
|
||||
bool IsLarger(int width_, int height_) {
|
||||
@@ -122,7 +123,7 @@ class Image {
|
||||
std::vector<uchar> m_data;
|
||||
|
||||
public:
|
||||
VideoMode::PixelFormat pixelFormat{VideoMode::kUnknown};
|
||||
wpi::util::PixelFormat pixelFormat{wpi::util::PixelFormat::kUnknown};
|
||||
int width{0};
|
||||
int height{0};
|
||||
int jpegQuality{-1};
|
||||
|
||||
@@ -445,28 +445,28 @@ void MjpegServerImpl::ConnThread::SendHTML(wpi::util::raw_ostream& os,
|
||||
for (auto mode : source.EnumerateVideoModes(&status)) {
|
||||
os << "<tr><td>";
|
||||
switch (mode.pixelFormat) {
|
||||
case VideoMode::kMJPEG:
|
||||
case wpi::util::PixelFormat::kMJPEG:
|
||||
os << "MJPEG";
|
||||
break;
|
||||
case VideoMode::kYUYV:
|
||||
case wpi::util::PixelFormat::kYUYV:
|
||||
os << "YUYV";
|
||||
break;
|
||||
case VideoMode::kRGB565:
|
||||
case wpi::util::PixelFormat::kRGB565:
|
||||
os << "RGB565";
|
||||
break;
|
||||
case VideoMode::kBGR:
|
||||
case wpi::util::PixelFormat::kBGR:
|
||||
os << "BGR";
|
||||
break;
|
||||
case VideoMode::kBGRA:
|
||||
case wpi::util::PixelFormat::kBGRA:
|
||||
os << "BGRA";
|
||||
break;
|
||||
case VideoMode::kGray:
|
||||
case wpi::util::PixelFormat::kGray:
|
||||
os << "gray";
|
||||
break;
|
||||
case VideoMode::kY16:
|
||||
case wpi::util::PixelFormat::kY16:
|
||||
os << "Y16";
|
||||
break;
|
||||
case VideoMode::kUYVY:
|
||||
case wpi::util::PixelFormat::kUYVY:
|
||||
os << "UYVY";
|
||||
break;
|
||||
default:
|
||||
@@ -565,25 +565,25 @@ void MjpegServerImpl::ConnThread::SendJSON(wpi::util::raw_ostream& os,
|
||||
os << '{';
|
||||
os << "\n\"pixelFormat\": \"";
|
||||
switch (mode.pixelFormat) {
|
||||
case VideoMode::kMJPEG:
|
||||
case wpi::util::PixelFormat::kMJPEG:
|
||||
os << "MJPEG";
|
||||
break;
|
||||
case VideoMode::kYUYV:
|
||||
case wpi::util::PixelFormat::kYUYV:
|
||||
os << "YUYV";
|
||||
break;
|
||||
case VideoMode::kRGB565:
|
||||
case wpi::util::PixelFormat::kRGB565:
|
||||
os << "RGB565";
|
||||
break;
|
||||
case VideoMode::kBGR:
|
||||
case wpi::util::PixelFormat::kBGR:
|
||||
os << "BGR";
|
||||
break;
|
||||
case VideoMode::kGray:
|
||||
case wpi::util::PixelFormat::kGray:
|
||||
os << "gray";
|
||||
break;
|
||||
case VideoMode::kY16:
|
||||
case wpi::util::PixelFormat::kY16:
|
||||
os << "Y16";
|
||||
break;
|
||||
case VideoMode::kUYVY:
|
||||
case wpi::util::PixelFormat::kUYVY:
|
||||
os << "UYVY";
|
||||
break;
|
||||
default:
|
||||
@@ -752,15 +752,15 @@ void MjpegServerImpl::ConnThread::SendStream(wpi::net::raw_socket_ostream& os) {
|
||||
bool addDHT = false;
|
||||
size_t locSOF = size;
|
||||
switch (image->pixelFormat) {
|
||||
case VideoMode::kMJPEG:
|
||||
case wpi::util::PixelFormat::kMJPEG:
|
||||
// Determine if we need to add DHT to it, and allocate enough space
|
||||
// for adding it if required.
|
||||
addDHT = JpegNeedsDHT(data, &size, &locSOF);
|
||||
break;
|
||||
case VideoMode::kUYVY:
|
||||
case VideoMode::kRGB565:
|
||||
case VideoMode::kYUYV:
|
||||
case VideoMode::kY16:
|
||||
case wpi::util::PixelFormat::kUYVY:
|
||||
case wpi::util::PixelFormat::kRGB565:
|
||||
case wpi::util::PixelFormat::kYUYV:
|
||||
case wpi::util::PixelFormat::kY16:
|
||||
default:
|
||||
// Bad frame; sleep for 10 ms so we don't consume all processor time.
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
|
||||
@@ -13,12 +13,7 @@
|
||||
|
||||
#include "SinkImpl.hpp"
|
||||
#include "wpi/net/NetworkAcceptor.hpp"
|
||||
#include "wpi/net/NetworkStream.hpp"
|
||||
#include "wpi/net/raw_socket_ostream.hpp"
|
||||
#include "wpi/util/SafeThread.hpp"
|
||||
#include "wpi/util/SmallVector.hpp"
|
||||
#include "wpi/util/raw_istream.hpp"
|
||||
#include "wpi/util/raw_ostream.hpp"
|
||||
|
||||
namespace wpi::cs {
|
||||
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
#include <utility>
|
||||
|
||||
#include "Handle.hpp"
|
||||
#include "wpi/cs/cscore_cpp.hpp"
|
||||
#include "wpi/cs/RawEvent.hpp"
|
||||
#include "wpi/cs/VideoMode.hpp"
|
||||
#include "wpi/util/CallbackManager.hpp"
|
||||
|
||||
namespace wpi::cs {
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "PropertyImpl.hpp"
|
||||
#include "wpi/cs/cscore_cpp.hpp"
|
||||
#include "wpi/cs/cscore_c.h"
|
||||
#include "wpi/util/StringMap.hpp"
|
||||
#include "wpi/util/json_fwd.hpp"
|
||||
#include "wpi/util/mutex.hpp"
|
||||
|
||||
@@ -100,7 +100,7 @@ uint64_t RawSinkImpl::GrabFrameImpl(WPI_RawFrame& rawFrame,
|
||||
auto width = rawFrame.width;
|
||||
auto height = rawFrame.height;
|
||||
auto pixelFormat =
|
||||
static_cast<VideoMode::PixelFormat>(rawFrame.pixelFormat);
|
||||
static_cast<wpi::util::PixelFormat>(rawFrame.pixelFormat);
|
||||
if (width <= 0 || height <= 0) {
|
||||
width = incomingFrame.GetOriginalWidth();
|
||||
height = incomingFrame.GetOriginalHeight();
|
||||
@@ -118,7 +118,7 @@ uint64_t RawSinkImpl::GrabFrameImpl(WPI_RawFrame& rawFrame,
|
||||
rawFrame.height = newImage->height;
|
||||
rawFrame.width = newImage->width;
|
||||
rawFrame.stride = newImage->GetStride();
|
||||
rawFrame.pixelFormat = newImage->pixelFormat;
|
||||
rawFrame.pixelFormat = static_cast<int>(newImage->pixelFormat);
|
||||
rawFrame.size = newImage->size();
|
||||
std::copy(newImage->data(), newImage->data() + rawFrame.size, rawFrame.data);
|
||||
rawFrame.timestamp = incomingFrame.GetTime();
|
||||
|
||||
@@ -13,8 +13,7 @@
|
||||
|
||||
#include "Frame.hpp"
|
||||
#include "SinkImpl.hpp"
|
||||
#include "wpi/cs/cscore_raw.h"
|
||||
#include "wpi/util/condition_variable.hpp"
|
||||
#include "wpi/util/RawFrame.h"
|
||||
|
||||
namespace wpi::cs {
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ RawSourceImpl::~RawSourceImpl() = default;
|
||||
void RawSourceImpl::PutFrame(const WPI_RawFrame& image) {
|
||||
auto currentTime = wpi::util::Now();
|
||||
std::string_view data_view{reinterpret_cast<char*>(image.data), image.size};
|
||||
SourceImpl::PutFrame(static_cast<VideoMode::PixelFormat>(image.pixelFormat),
|
||||
SourceImpl::PutFrame(static_cast<wpi::util::PixelFormat>(image.pixelFormat),
|
||||
image.width, image.height, data_view, currentTime);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,15 +5,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include "ConfigurableSourceImpl.hpp"
|
||||
#include "SourceImpl.hpp"
|
||||
#include "wpi/cs/cscore_raw.h"
|
||||
|
||||
namespace wpi::cs {
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "SourceImpl.hpp"
|
||||
#include "wpi/util/Logger.hpp"
|
||||
#include "wpi/util/json_fwd.hpp"
|
||||
#include "wpi/util/mutex.hpp"
|
||||
|
||||
namespace wpi::cs {
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "Log.hpp"
|
||||
#include "Notifier.hpp"
|
||||
#include "Telemetry.hpp"
|
||||
#include "wpi/util/PixelFormat.hpp"
|
||||
#include "wpi/util/StringExtras.hpp"
|
||||
#include "wpi/util/json.hpp"
|
||||
#include "wpi/util/timestamp.hpp"
|
||||
@@ -149,7 +150,7 @@ VideoMode SourceImpl::GetVideoMode(CS_Status* status) const {
|
||||
return m_mode;
|
||||
}
|
||||
|
||||
bool SourceImpl::SetPixelFormat(VideoMode::PixelFormat pixelFormat,
|
||||
bool SourceImpl::SetPixelFormat(wpi::util::PixelFormat pixelFormat,
|
||||
CS_Status* status) {
|
||||
auto mode = GetVideoMode(status);
|
||||
if (!mode) {
|
||||
@@ -199,21 +200,21 @@ bool SourceImpl::SetConfigJson(const wpi::util::json& config,
|
||||
try {
|
||||
auto str = config.at("pixel format").get<std::string>();
|
||||
if (wpi::util::equals_lower(str, "mjpeg")) {
|
||||
mode.pixelFormat = wpi::cs::VideoMode::kMJPEG;
|
||||
mode.pixelFormat = wpi::util::PixelFormat::kMJPEG;
|
||||
} else if (wpi::util::equals_lower(str, "yuyv")) {
|
||||
mode.pixelFormat = wpi::cs::VideoMode::kYUYV;
|
||||
mode.pixelFormat = wpi::util::PixelFormat::kYUYV;
|
||||
} else if (wpi::util::equals_lower(str, "rgb565")) {
|
||||
mode.pixelFormat = wpi::cs::VideoMode::kRGB565;
|
||||
mode.pixelFormat = wpi::util::PixelFormat::kRGB565;
|
||||
} else if (wpi::util::equals_lower(str, "bgr")) {
|
||||
mode.pixelFormat = wpi::cs::VideoMode::kBGR;
|
||||
mode.pixelFormat = wpi::util::PixelFormat::kBGR;
|
||||
} else if (wpi::util::equals_lower(str, "bgra")) {
|
||||
mode.pixelFormat = wpi::cs::VideoMode::kBGRA;
|
||||
mode.pixelFormat = wpi::util::PixelFormat::kBGRA;
|
||||
} else if (wpi::util::equals_lower(str, "gray")) {
|
||||
mode.pixelFormat = wpi::cs::VideoMode::kGray;
|
||||
mode.pixelFormat = wpi::util::PixelFormat::kGray;
|
||||
} else if (wpi::util::equals_lower(str, "y16")) {
|
||||
mode.pixelFormat = wpi::cs::VideoMode::kY16;
|
||||
mode.pixelFormat = wpi::util::PixelFormat::kY16;
|
||||
} else if (wpi::util::equals_lower(str, "uyvy")) {
|
||||
mode.pixelFormat = wpi::cs::VideoMode::kUYVY;
|
||||
mode.pixelFormat = wpi::util::PixelFormat::kUYVY;
|
||||
} else {
|
||||
SWARNING("SetConfigJson: could not understand pixel format value '{}'",
|
||||
str);
|
||||
@@ -251,19 +252,18 @@ bool SourceImpl::SetConfigJson(const wpi::util::json& config,
|
||||
}
|
||||
|
||||
// if all of video mode is set, use SetVideoMode, otherwise piecemeal it
|
||||
if (mode.pixelFormat != VideoMode::kUnknown && mode.width != 0 &&
|
||||
if (mode.pixelFormat != wpi::util::PixelFormat::kUnknown && mode.width != 0 &&
|
||||
mode.height != 0 && mode.fps != 0) {
|
||||
SINFO(
|
||||
"SetConfigJson: setting video mode to pixelFormat {}, width {}, height "
|
||||
"{}, fps {}",
|
||||
mode.pixelFormat, mode.width, mode.height, mode.fps);
|
||||
static_cast<int>(mode.pixelFormat), mode.width, mode.height, mode.fps);
|
||||
SetVideoMode(mode, status);
|
||||
} else {
|
||||
if (mode.pixelFormat != wpi::cs::VideoMode::kUnknown) {
|
||||
SINFO("SetConfigJson: setting pixelFormat {}", mode.pixelFormat);
|
||||
SetPixelFormat(
|
||||
static_cast<wpi::cs::VideoMode::PixelFormat>(mode.pixelFormat),
|
||||
status);
|
||||
if (mode.pixelFormat != wpi::util::PixelFormat::kUnknown) {
|
||||
SINFO("SetConfigJson: setting pixelFormat {}",
|
||||
static_cast<int>(mode.pixelFormat));
|
||||
SetPixelFormat(mode.pixelFormat, status);
|
||||
}
|
||||
if (mode.width != 0 && mode.height != 0) {
|
||||
SINFO("SetConfigJson: setting width {}, height {}", mode.width,
|
||||
@@ -362,28 +362,28 @@ wpi::util::json SourceImpl::GetConfigJsonObject(CS_Status* status) {
|
||||
// pixel format
|
||||
std::string_view pixelFormat;
|
||||
switch (m_mode.pixelFormat) {
|
||||
case VideoMode::kMJPEG:
|
||||
case wpi::util::PixelFormat::kMJPEG:
|
||||
pixelFormat = "mjpeg";
|
||||
break;
|
||||
case VideoMode::kYUYV:
|
||||
case wpi::util::PixelFormat::kYUYV:
|
||||
pixelFormat = "yuyv";
|
||||
break;
|
||||
case VideoMode::kRGB565:
|
||||
case wpi::util::PixelFormat::kRGB565:
|
||||
pixelFormat = "rgb565";
|
||||
break;
|
||||
case VideoMode::kBGR:
|
||||
case wpi::util::PixelFormat::kBGR:
|
||||
pixelFormat = "bgr";
|
||||
break;
|
||||
case VideoMode::kBGRA:
|
||||
case wpi::util::PixelFormat::kBGRA:
|
||||
pixelFormat = "bgra";
|
||||
break;
|
||||
case VideoMode::kGray:
|
||||
case wpi::util::PixelFormat::kGray:
|
||||
pixelFormat = "gray";
|
||||
break;
|
||||
case VideoMode::kY16:
|
||||
case wpi::util::PixelFormat::kY16:
|
||||
pixelFormat = "y16";
|
||||
break;
|
||||
case VideoMode::kUYVY:
|
||||
case wpi::util::PixelFormat::kUYVY:
|
||||
pixelFormat = "uyvy";
|
||||
break;
|
||||
default:
|
||||
@@ -429,7 +429,7 @@ std::vector<VideoMode> SourceImpl::EnumerateVideoModes(
|
||||
}
|
||||
|
||||
std::unique_ptr<Image> SourceImpl::AllocImage(
|
||||
VideoMode::PixelFormat pixelFormat, int width, int height, size_t size) {
|
||||
wpi::util::PixelFormat pixelFormat, int width, int height, size_t size) {
|
||||
std::unique_ptr<Image> image;
|
||||
{
|
||||
std::scoped_lock lock{m_poolMutex};
|
||||
@@ -464,10 +464,10 @@ std::unique_ptr<Image> SourceImpl::AllocImage(
|
||||
return image;
|
||||
}
|
||||
|
||||
void SourceImpl::PutFrame(VideoMode::PixelFormat pixelFormat, int width,
|
||||
void SourceImpl::PutFrame(wpi::util::PixelFormat pixelFormat, int width,
|
||||
int height, std::string_view data, Frame::Time time,
|
||||
WPI_TimestampSource timeSrc) {
|
||||
if (pixelFormat == VideoMode::PixelFormat::kBGRA) {
|
||||
if (pixelFormat == wpi::util::PixelFormat::kBGRA) {
|
||||
// Write BGRA as BGR to save a copy
|
||||
auto image =
|
||||
CreateImageFromBGRA(this, width, height, width * 4,
|
||||
|
||||
@@ -12,11 +12,12 @@
|
||||
#include <vector>
|
||||
|
||||
#include "Frame.hpp"
|
||||
#include "Handle.hpp"
|
||||
#include "Image.hpp"
|
||||
#include "PropertyContainer.hpp"
|
||||
#include "wpi/cs/cscore_cpp.hpp"
|
||||
#include "wpi/cs/VideoMode.hpp"
|
||||
#include "wpi/cs/cscore_c.h"
|
||||
#include "wpi/util/Logger.hpp"
|
||||
#include "wpi/util/PixelFormat.hpp"
|
||||
#include "wpi/util/RawFrame.h"
|
||||
#include "wpi/util/condition_variable.hpp"
|
||||
#include "wpi/util/json_fwd.hpp"
|
||||
@@ -119,7 +120,7 @@ class SourceImpl : public PropertyContainer {
|
||||
|
||||
// These have default implementations but can be overridden for custom
|
||||
// or optimized behavior.
|
||||
virtual bool SetPixelFormat(VideoMode::PixelFormat pixelFormat,
|
||||
virtual bool SetPixelFormat(wpi::util::PixelFormat pixelFormat,
|
||||
CS_Status* status);
|
||||
virtual bool SetResolution(int width, int height, CS_Status* status);
|
||||
virtual bool SetFPS(int fps, CS_Status* status);
|
||||
@@ -131,7 +132,7 @@ class SourceImpl : public PropertyContainer {
|
||||
|
||||
std::vector<VideoMode> EnumerateVideoModes(CS_Status* status) const;
|
||||
|
||||
std::unique_ptr<Image> AllocImage(VideoMode::PixelFormat pixelFormat,
|
||||
std::unique_ptr<Image> AllocImage(wpi::util::PixelFormat pixelFormat,
|
||||
int width, int height, size_t size);
|
||||
|
||||
protected:
|
||||
@@ -139,7 +140,7 @@ class SourceImpl : public PropertyContainer {
|
||||
void UpdatePropertyValue(int property, bool setString, int value,
|
||||
std::string_view valueStr) override;
|
||||
|
||||
void PutFrame(VideoMode::PixelFormat pixelFormat, int width, int height,
|
||||
void PutFrame(wpi::util::PixelFormat pixelFormat, int width, int height,
|
||||
std::string_view data, Frame::Time time,
|
||||
WPI_TimestampSource timeSrc = WPI_TIMESRC_FRAME_DEQUEUE);
|
||||
void PutFrame(std::unique_ptr<Image> image, Frame::Time time,
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "Notifier.hpp"
|
||||
#include "SourceImpl.hpp"
|
||||
#include "wpi/util/DenseMap.hpp"
|
||||
#include "wpi/util/timestamp.h"
|
||||
|
||||
using namespace wpi::cs;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "wpi/cs/cscore_cpp.hpp"
|
||||
#include "wpi/cs/cscore_c.h"
|
||||
#include "wpi/util/SafeThread.hpp"
|
||||
|
||||
namespace wpi::cs {
|
||||
|
||||
44
cscore/src/main/native/cpp/VideoSink.cpp
Normal file
44
cscore/src/main/native/cpp/VideoSink.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include "wpi/cs/VideoSink.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "wpi/util/json.hpp"
|
||||
|
||||
using namespace wpi::cs;
|
||||
|
||||
wpi::util::json VideoSink::GetConfigJsonObject() const {
|
||||
m_status = 0;
|
||||
return GetSinkConfigJsonObject(m_handle, &m_status);
|
||||
}
|
||||
|
||||
std::vector<VideoProperty> VideoSink::EnumerateProperties() const {
|
||||
wpi::util::SmallVector<CS_Property, 32> handles_buf;
|
||||
CS_Status status = 0;
|
||||
auto handles = EnumerateSinkProperties(m_handle, handles_buf, &status);
|
||||
|
||||
std::vector<VideoProperty> properties;
|
||||
properties.reserve(handles.size());
|
||||
for (CS_Property handle : handles) {
|
||||
properties.emplace_back(VideoProperty{handle});
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
std::vector<VideoSink> VideoSink::EnumerateSinks() {
|
||||
wpi::util::SmallVector<CS_Sink, 16> handles_buf;
|
||||
CS_Status status = 0;
|
||||
auto handles = ::wpi::cs::EnumerateSinkHandles(handles_buf, &status);
|
||||
|
||||
std::vector<VideoSink> sinks;
|
||||
sinks.reserve(handles.size());
|
||||
for (int handle : handles) {
|
||||
sinks.emplace_back(VideoSink{handle});
|
||||
}
|
||||
return sinks;
|
||||
}
|
||||
@@ -2,13 +2,13 @@
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include "wpi/cs/cscore_oo.hpp"
|
||||
#include "wpi/cs/VideoSource.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "wpi/cs/VideoSink.hpp"
|
||||
#include "wpi/util/json.hpp"
|
||||
|
||||
using namespace wpi::cs;
|
||||
@@ -18,11 +18,6 @@ wpi::util::json VideoSource::GetConfigJsonObject() const {
|
||||
return GetSourceConfigJsonObject(m_handle, &m_status);
|
||||
}
|
||||
|
||||
wpi::util::json VideoSink::GetConfigJsonObject() const {
|
||||
m_status = 0;
|
||||
return GetSinkConfigJsonObject(m_handle, &m_status);
|
||||
}
|
||||
|
||||
std::vector<VideoProperty> VideoSource::EnumerateProperties() const {
|
||||
wpi::util::SmallVector<CS_Property, 32> handles_buf;
|
||||
CS_Status status = 0;
|
||||
@@ -61,29 +56,3 @@ std::vector<VideoSource> VideoSource::EnumerateSources() {
|
||||
}
|
||||
return sources;
|
||||
}
|
||||
|
||||
std::vector<VideoProperty> VideoSink::EnumerateProperties() const {
|
||||
wpi::util::SmallVector<CS_Property, 32> handles_buf;
|
||||
CS_Status status = 0;
|
||||
auto handles = EnumerateSinkProperties(m_handle, handles_buf, &status);
|
||||
|
||||
std::vector<VideoProperty> properties;
|
||||
properties.reserve(handles.size());
|
||||
for (CS_Property handle : handles) {
|
||||
properties.emplace_back(VideoProperty{handle});
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
std::vector<VideoSink> VideoSink::EnumerateSinks() {
|
||||
wpi::util::SmallVector<CS_Sink, 16> handles_buf;
|
||||
CS_Status status = 0;
|
||||
auto handles = ::wpi::cs::EnumerateSinkHandles(handles_buf, &status);
|
||||
|
||||
std::vector<VideoSink> sinks;
|
||||
sinks.reserve(handles.size());
|
||||
for (int handle : handles) {
|
||||
sinks.emplace_back(VideoSink{handle});
|
||||
}
|
||||
return sinks;
|
||||
}
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "c_util.hpp"
|
||||
#include "wpi/cs/cscore_cpp.hpp"
|
||||
#include "wpi/util/MemAlloc.hpp"
|
||||
#include "wpi/util/PixelFormat.hpp"
|
||||
#include "wpi/util/SmallString.hpp"
|
||||
#include "wpi/util/string.hpp"
|
||||
|
||||
@@ -178,9 +179,9 @@ CS_Bool CS_SetSourceVideoModeDiscrete(CS_Source source,
|
||||
CS_Status* status) {
|
||||
return wpi::cs::SetSourceVideoMode(
|
||||
source,
|
||||
wpi::cs::VideoMode{static_cast<wpi::cs::VideoMode::PixelFormat>(
|
||||
static_cast<int>(pixelFormat)),
|
||||
width, height, fps},
|
||||
wpi::cs::VideoMode{
|
||||
static_cast<wpi::util::PixelFormat>(static_cast<int>(pixelFormat)),
|
||||
width, height, fps},
|
||||
status);
|
||||
}
|
||||
|
||||
@@ -189,8 +190,7 @@ CS_Bool CS_SetSourcePixelFormat(CS_Source source,
|
||||
CS_Status* status) {
|
||||
return wpi::cs::SetSourcePixelFormat(
|
||||
source,
|
||||
static_cast<wpi::cs::VideoMode::PixelFormat>(
|
||||
static_cast<int>(pixelFormat)),
|
||||
static_cast<wpi::util::PixelFormat>(static_cast<int>(pixelFormat)),
|
||||
status);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "SourceImpl.hpp"
|
||||
#include "Telemetry.hpp"
|
||||
#include "wpi/net/hostname.hpp"
|
||||
#include "wpi/util/PixelFormat.hpp"
|
||||
#include "wpi/util/SmallString.hpp"
|
||||
#include "wpi/util/json.hpp"
|
||||
|
||||
@@ -323,7 +324,7 @@ bool SetSourceVideoMode(CS_Source source, const VideoMode& mode,
|
||||
return data->source->SetVideoMode(mode, status);
|
||||
}
|
||||
|
||||
bool SetSourcePixelFormat(CS_Source source, VideoMode::PixelFormat pixelFormat,
|
||||
bool SetSourcePixelFormat(CS_Source source, wpi::util::PixelFormat pixelFormat,
|
||||
CS_Status* status) {
|
||||
auto data = Instance::GetInstance().GetSource(source);
|
||||
if (!data) {
|
||||
|
||||
@@ -10,9 +10,10 @@
|
||||
|
||||
#define WPI_RAWFRAME_JNI
|
||||
#include "org_wpilib_vision_camera_CameraServerJNI.h"
|
||||
#include "wpi/cs/cscore_raw.h"
|
||||
#include "wpi/cs/cscore_cpp.hpp"
|
||||
#include "wpi/cs/cscore_raw.hpp"
|
||||
#include "wpi/cs/cscore_runloop.hpp"
|
||||
#include "wpi/util/RawFrame.h"
|
||||
#include "wpi/util/RawFrame.hpp"
|
||||
#include "wpi/util/SmallString.hpp"
|
||||
#include "wpi/util/jni_util.hpp"
|
||||
|
||||
@@ -583,10 +584,9 @@ Java_org_wpilib_vision_camera_CameraServerJNI_createRawSource
|
||||
CS_Status status = 0;
|
||||
auto val = wpi::cs::CreateRawSource(
|
||||
JStringRef{env, name}.str(), isCv,
|
||||
wpi::cs::VideoMode{
|
||||
static_cast<wpi::cs::VideoMode::PixelFormat>(pixelFormat),
|
||||
static_cast<int>(width), static_cast<int>(height),
|
||||
static_cast<int>(fps)},
|
||||
wpi::cs::VideoMode{static_cast<wpi::util::PixelFormat>(pixelFormat),
|
||||
static_cast<int>(width), static_cast<int>(height),
|
||||
static_cast<int>(fps)},
|
||||
&status);
|
||||
CheckStatus(env, status);
|
||||
return val;
|
||||
@@ -771,9 +771,8 @@ Java_org_wpilib_vision_camera_CameraServerJNI_setSourceVideoMode
|
||||
CS_Status status = 0;
|
||||
auto val = wpi::cs::SetSourceVideoMode(
|
||||
source,
|
||||
wpi::cs::VideoMode(
|
||||
static_cast<wpi::cs::VideoMode::PixelFormat>(pixelFormat), width,
|
||||
height, fps),
|
||||
wpi::cs::VideoMode(static_cast<wpi::util::PixelFormat>(pixelFormat),
|
||||
width, height, fps),
|
||||
&status);
|
||||
CheckStatus(env, status);
|
||||
return val;
|
||||
@@ -790,8 +789,7 @@ Java_org_wpilib_vision_camera_CameraServerJNI_setSourcePixelFormat
|
||||
{
|
||||
CS_Status status = 0;
|
||||
auto val = wpi::cs::SetSourcePixelFormat(
|
||||
source, static_cast<wpi::cs::VideoMode::PixelFormat>(pixelFormat),
|
||||
&status);
|
||||
source, static_cast<wpi::util::PixelFormat>(pixelFormat), &status);
|
||||
CheckStatus(env, status);
|
||||
return val;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user