Skip to content

Commit

Permalink
Refactored use of av_device_format
Browse files Browse the repository at this point in the history
  • Loading branch information
boitumeloruf authored and flynneva committed Nov 4, 2023
1 parent 49d0a21 commit 2c57145
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 39 deletions.
26 changes: 26 additions & 0 deletions include/usb_cam/formats/av_pixel_format_helper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
#define USB_CAM__FORMATS__AV_PX_FMT_HELPER_HPP_

#include <unordered_map>
#include <algorithm>
#include <string>

extern "C" {
#define __STDC_CONSTANT_MACROS // Required for libavutil
Expand All @@ -45,6 +47,7 @@ namespace usb_cam
namespace formats
{

/// Map to associate string of pixel format name to actual pixel format enum
const std::unordered_map<std::string, AVPixelFormat> STR_2_AVPIXFMT = {
{stringify(AV_PIX_FMT_NONE), AV_PIX_FMT_NONE},
{stringify(AV_PIX_FMT_YUV420P), AV_PIX_FMT_YUV420P}, ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Expand Down Expand Up @@ -335,6 +338,29 @@ const std::unordered_map<std::string, AVPixelFormat> STR_2_AVPIXFMT = {
{stringify(AV_PIX_FMT_NB), AV_PIX_FMT_NB}, ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions
};

/// @brief Get AVPixelFormat from string. This string should correspond to the AVPixelFormat name.
/// The name can either be given with or without the 'AV_PIX_FMT_' prefix.
/// @param str AVPixelFormat name
/// @return Pixel format enum corresponding to a given name
inline AVPixelFormat get_av_pixel_format_from_string (const std::string& str)
{
std::string upperCaseStr = str;
std::transform(upperCaseStr.begin(), upperCaseStr.end(), upperCaseStr.begin(), ::toupper);

std::string fullFmtStr;
if(upperCaseStr.rfind("AV_PIX_FMT_", 0) == std::string::npos)
{
// passed string does not start with 'AV_PIX_FMT_'
fullFmtStr = "AV_PIX_FMT_" + upperCaseStr;
}
else
{
fullFmtStr = upperCaseStr;
}

return STR_2_AVPIXFMT.find(fullFmtStr)->second;
}

} // namespace formats
} // namespace usb_cam

Expand Down
54 changes: 17 additions & 37 deletions include/usb_cam/usb_cam.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,14 +273,12 @@ class UsbCam
return m_supported_formats;
}

/// @brief Get pixel format from string. Required to have logic within UsbCam object
/// @brief Set pixel format from parameter list. Required to have logic within UsbCam object
/// in case pixel format class requires additional information for conversion function
/// (e.g. number of pixels, width, height, etc.)
/// @param pixFmtStr name of supported format (see `usb_cam/supported_formats.hpp`)
/// @param avDevFmtStr name of av device format (only used for mjpeg stream)
/// @param parameters list of parameters from which the pixel format is to be set
/// @return pixel format structure corresponding to a given name
inline std::shared_ptr<pixel_format_base> set_pixel_format_from_string(const std::string & pixFmtStr,
const std::string & avDevFmtStr)
inline std::shared_ptr<pixel_format_base> set_pixel_format(const parameters_t & parameters)
{
using usb_cam::formats::RGB8;
using usb_cam::formats::YUYV;
Expand All @@ -293,57 +291,39 @@ class UsbCam
using usb_cam::formats::MJPEG2RGB;
using usb_cam::formats::M4202RGB;

if (pixFmtStr == "rgb8") {
if (parameters.pixel_format_name == "rgb8") {
m_image.pixel_format = std::make_shared<RGB8>();
} else if (pixFmtStr == "yuyv") {
} else if (parameters.pixel_format_name == "yuyv") {
m_image.pixel_format = std::make_shared<YUYV>();
} else if (pixFmtStr == "yuyv2rgb") {
} else if (parameters.pixel_format_name == "yuyv2rgb") {
// number of pixels required for conversion method
m_image.pixel_format = std::make_shared<YUYV2RGB>(m_image.number_of_pixels);
} else if (pixFmtStr == "uyvy") {
} else if (parameters.pixel_format_name == "uyvy") {
m_image.pixel_format = std::make_shared<UYVY>();
} else if (pixFmtStr == "uyvy2rgb") {
} else if (parameters.pixel_format_name == "uyvy2rgb") {
// number of pixels required for conversion method
m_image.pixel_format = std::make_shared<UYVY2RGB>(m_image.number_of_pixels);
} else if (pixFmtStr == "mjpeg2rgb") {
} else if (parameters.pixel_format_name == "mjpeg2rgb") {
m_image.pixel_format = std::make_shared<MJPEG2RGB>(
m_image.width, m_image.height, get_av_pixel_format_from_string(avDevFmtStr));
} else if (pixFmtStr == "m4202rgb") {
m_image.width, m_image.height,
formats::get_av_pixel_format_from_string(parameters.av_device_format));
} else if (parameters.pixel_format_name == "m4202rgb") {
m_image.pixel_format = std::make_shared<M4202RGB>(
m_image.width, m_image.height);
} else if (pixFmtStr == "mono8") {
} else if (parameters.pixel_format_name == "mono8") {
m_image.pixel_format = std::make_shared<MONO8>();
} else if (pixFmtStr == "mono16") {
} else if (parameters.pixel_format_name == "mono16") {
m_image.pixel_format = std::make_shared<MONO16>();
} else if (pixFmtStr == "y102mono8") {
} else if (parameters.pixel_format_name == "y102mono8") {
m_image.pixel_format = std::make_shared<Y102MONO8>(m_image.number_of_pixels);
} else {
throw std::invalid_argument("Unsupported pixel format specified: " + pixFmtStr);
throw std::invalid_argument("Unsupported pixel format specified: " +
parameters.pixel_format_name);
}

return m_image.pixel_format;
}

inline AVPixelFormat get_av_pixel_format_from_string (const std::string& str)
{
std::string upperCaseStr = str;
std::transform(upperCaseStr.begin(), upperCaseStr.end(), upperCaseStr.begin(), ::toupper);

std::string fullFmtStr;
if(upperCaseStr.rfind("AV_PIX_FMT_", 0) == std::string::npos)
{
// passed string does not start with 'AV_PIX_FMT_'
fullFmtStr = "AV_PIX_FMT_" + upperCaseStr;
}
else
{
fullFmtStr = upperCaseStr;
}

return usb_cam::formats::STR_2_AVPIXFMT.find(fullFmtStr)->second;
}


private:
void init_read();
void init_mmap();
Expand Down
3 changes: 1 addition & 2 deletions src/usb_cam.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -521,8 +521,7 @@ void UsbCam::configure(
m_image.set_number_of_pixels();

// Do this before calling set_bytes_per_line and set_size_in_bytes
m_image.pixel_format = set_pixel_format_from_string(parameters.pixel_format_name,
parameters.av_device_format);
m_image.pixel_format = set_pixel_format(parameters);
m_image.set_bytes_per_line();
m_image.set_size_in_bytes();
m_framerate = parameters.framerate;
Expand Down

0 comments on commit 2c57145

Please sign in to comment.