Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rpicam_still: Add RGB/BGR 48bpp support #599

Merged
merged 2 commits into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/rpicam-apps-style-checker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
runs-on: [ self-hosted ]

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
clean: true
Expand Down
14 changes: 7 additions & 7 deletions .github/workflows/rpicam-apps-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
build_type: [ release, debug ]

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 1
clean: true
Expand All @@ -39,7 +39,7 @@ jobs:
run: tar -cvf build-artifacts-${{matrix.compiler}}-${{matrix.build_type}}.tar -C ${{github.workspace}}/build .

- name: Upload build files
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: build-artifacts-${{matrix.compiler}}-${{matrix.build_type}}
path: build-artifacts-${{matrix.compiler}}-${{matrix.build_type}}.tar
Expand All @@ -50,7 +50,7 @@ jobs:
runs-on: [ self-hosted ]

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 1
clean: true
Expand All @@ -67,7 +67,7 @@ jobs:
run: tar -cvf build-artifacts-gcc-lite.tar -C ${{github.workspace}}/build .

- name: Upload build files
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: build-artifacts-gcc-lite
path: build-artifacts-gcc-lite.tar
Expand All @@ -83,7 +83,7 @@ jobs:
camera: [ imx219, imx477, imx708, pi5-imx708-imx477 ]

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 1
clean: true
Expand All @@ -92,7 +92,7 @@ jobs:
run: mkdir -p ${{github.workspace}}/test_output

- name: Download build
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: build-artifacts-gcc-release
path: ${{github.workspace}}
Expand All @@ -112,7 +112,7 @@ jobs:

- name: Upload test output
if: ${{ failure() }}
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: test-artifacts-${{matrix.camera}}
path: ${{github.workspace}}/test_output/
Expand Down
18 changes: 9 additions & 9 deletions .github/workflows/rpicam-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
run: tar -cvf build-artifacts-libcamera.tar -C ${{env.LIBCAMERA_SRC_DIR}} .

- name: Upload build files
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: build-artifacts-libcamera
path: build-artifacts-libcamera.tar
Expand All @@ -54,7 +54,7 @@ jobs:
needs: build-libcamera

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 1
clean: true
Expand All @@ -63,7 +63,7 @@ jobs:
run: rm -rf ${{env.LIBCAMERA_SRC_DIR}} && mkdir -p ${{env.LIBCAMERA_SRC_DIR}}

- name: Download libcamera artifact
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: build-artifacts-libcamera
path: ${{github.workspace}}
Expand All @@ -83,7 +83,7 @@ jobs:
run: tar -cvf build-artifacts-rpicam-apps.tar -C ${{github.workspace}}/build .

- name: Upload build files
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: build-artifacts-rpicam-apps
path: build-artifacts-rpicam-apps.tar
Expand All @@ -99,7 +99,7 @@ jobs:
camera: [ imx219, imx477, imx708, pi5-imx708-imx477 ]

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 1
clean: true
Expand All @@ -108,7 +108,7 @@ jobs:
run: mkdir -p ${{github.workspace}}/test_output

- name: Download rpicam-apps build
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: build-artifacts-rpicam-apps
path: ${{github.workspace}}
Expand All @@ -120,7 +120,7 @@ jobs:
run: rm -rf ${{env.LIBCAMERA_SRC_DIR}} && mkdir -p ${{env.LIBCAMERA_SRC_DIR}}

- name: Download libcamera artifact
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: build-artifacts-libcamera
path: ${{github.workspace}}
Expand All @@ -140,7 +140,7 @@ jobs:

- name: Upload test output
if: ${{failure()}}
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: test-artifacts-${{matrix.camera}}
path: ${{github.workspace}}/test_output/
Expand Down Expand Up @@ -183,7 +183,7 @@ jobs:
run: rm -rf ${{env.LIBCAMERA_SRC_DIR}} && mkdir -p ${{env.LIBCAMERA_SRC_DIR}}

- name: Download libcamera artifact
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: build-artifacts-libcamera
path: ${{github.workspace}}
Expand Down
4 changes: 3 additions & 1 deletion apps/rpicam_still.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,10 @@ static void event_loop(RPiCamStillApp &app)
bool output = !options->output.empty() || options->datetime || options->timestamp; // output requested?
bool keypress = options->keypress || options->signal; // "signal" mode is much like "keypress" mode
unsigned int still_flags = RPiCamApp::FLAG_STILL_NONE;
if (options->encoding == "rgb" || options->encoding == "png")
if (options->encoding == "rgb24" || options->encoding == "png")
still_flags |= RPiCamApp::FLAG_STILL_BGR;
if (options->encoding == "rgb48")
still_flags |= RPiCamApp::FLAG_STILL_BGR48;
else if (options->encoding == "bmp")
still_flags |= RPiCamApp::FLAG_STILL_RGB;
if (options->raw)
Expand Down
4 changes: 4 additions & 0 deletions core/rpicam_app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,10 @@ void RPiCamApp::ConfigureStill(unsigned int flags)
configuration_->at(0).pixelFormat = libcamera::formats::BGR888;
else if (flags & FLAG_STILL_RGB)
configuration_->at(0).pixelFormat = libcamera::formats::RGB888;
else if (flags & FLAG_STILL_BGR48)
configuration_->at(0).pixelFormat = libcamera::formats::BGR161616;
else if (flags & FLAG_STILL_RGB48)
configuration_->at(0).pixelFormat = libcamera::formats::RGB161616;
else
configuration_->at(0).pixelFormat = libcamera::formats::YUV420;
if ((flags & FLAG_STILL_BUFFER_MASK) == FLAG_STILL_DOUBLE_BUFFER)
Expand Down
14 changes: 8 additions & 6 deletions core/rpicam_app.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,14 @@ class RPiCamApp

// Some flags that can be used to give hints to the camera configuration.
static constexpr unsigned int FLAG_STILL_NONE = 0;
static constexpr unsigned int FLAG_STILL_BGR = 1; // supply BGR images, not YUV
static constexpr unsigned int FLAG_STILL_RGB = 2; // supply RGB images, not YUV
static constexpr unsigned int FLAG_STILL_RAW = 4; // request raw image stream
static constexpr unsigned int FLAG_STILL_DOUBLE_BUFFER = 8; // double-buffer stream
static constexpr unsigned int FLAG_STILL_TRIPLE_BUFFER = 16; // triple-buffer stream
static constexpr unsigned int FLAG_STILL_BUFFER_MASK = 24; // mask for buffer flags
static constexpr unsigned int FLAG_STILL_BGR = 1; // supply BGR 24bpp images, not YUV
static constexpr unsigned int FLAG_STILL_BGR48 = 2; // supply BGR 48bpp images, not YUV
static constexpr unsigned int FLAG_STILL_RGB = 4; // supply RGB images, not YUV
static constexpr unsigned int FLAG_STILL_RGB48 = 8; // supply RGB 48bpp images, not YUV
static constexpr unsigned int FLAG_STILL_RAW = 16; // request raw image stream
static constexpr unsigned int FLAG_STILL_DOUBLE_BUFFER = 32; // double-buffer stream
static constexpr unsigned int FLAG_STILL_TRIPLE_BUFFER = 64; // triple-buffer stream
static constexpr unsigned int FLAG_STILL_BUFFER_MASK = 96; // mask for buffer flags

static constexpr unsigned int FLAG_VIDEO_NONE = 0;
static constexpr unsigned int FLAG_VIDEO_RAW = 1; // request raw image stream
Expand Down
8 changes: 5 additions & 3 deletions core/still_options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ struct StillOptions : public Options
("thumb", value<std::string>(&thumb)->default_value("320:240:70"),
"Set thumbnail parameters as width:height:quality, or none")
("encoding,e", value<std::string>(&encoding)->default_value("jpg"),
"Set the desired output encoding, either jpg, png, rgb, bmp or yuv420")
"Set the desired output encoding, either jpg, png, rgb/rgb24, rgb48, bmp or yuv420")
("raw,r", value<bool>(&raw)->default_value(false)->implicit_value(true),
"Also save raw file in DNG format")
("latest", value<std::string>(&latest),
Expand Down Expand Up @@ -88,8 +88,10 @@ struct StillOptions : public Options
encoding = "jpg";
else if (strcasecmp(encoding.c_str(), "yuv420") == 0)
encoding = "yuv420";
else if (strcasecmp(encoding.c_str(), "rgb") == 0)
encoding = "rgb";
else if (strcasecmp(encoding.c_str(), "rgb") == 0 || strcasecmp(encoding.c_str(), "rgb24") == 0)
encoding = "rgb24";
else if (strcasecmp(encoding.c_str(), "rgb48") == 0)
encoding = "rgb48";
else if (strcasecmp(encoding.c_str(), "png") == 0)
encoding = "png";
else if (strcasecmp(encoding.c_str(), "bmp") == 0)
Expand Down
10 changes: 7 additions & 3 deletions image/yuv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,17 +115,20 @@ static void yuyv_save(std::vector<libcamera::Span<uint8_t>> const &mem, StreamIn
static void rgb_save(std::vector<libcamera::Span<uint8_t>> const &mem, StreamInfo const &info,
std::string const &filename, StillOptions const *options)
{
if (options->encoding != "rgb")
if (options->encoding != "rgb24" && options->encoding != "rgb48")
throw std::runtime_error("encoding should be set to rgb");
FILE *fp = filename == "-" ? stdout : fopen(filename.c_str(), "w");
if (!fp)
throw std::runtime_error("failed to open file " + filename);
try
{
uint8_t *ptr = (uint8_t *)mem[0].data();
unsigned int wr_stride = 3 * info.width;
if (options->encoding == "rgb48")
wr_stride *= 2;
for (unsigned int j = 0; j < info.height; j++, ptr += info.stride)
{
if (fwrite(ptr, 3 * info.width, 1, fp) != 1)
if (fwrite(ptr, wr_stride, 1, fp) != 1)
throw std::runtime_error("failed to write file " + filename);
}
if (fp != stdout)
Expand All @@ -146,7 +149,8 @@ void yuv_save(std::vector<libcamera::Span<uint8_t>> const &mem, StreamInfo const
yuyv_save(mem, info, filename, options);
else if (info.pixel_format == libcamera::formats::YUV420)
yuv420_save(mem, info, filename, options);
else if (info.pixel_format == libcamera::formats::BGR888 || info.pixel_format == libcamera::formats::RGB888)
else if (info.pixel_format == libcamera::formats::BGR888 || info.pixel_format == libcamera::formats::RGB888 ||
info.pixel_format == libcamera::formats::BGR161616 || info.pixel_format == libcamera::formats::RGB161616)
rgb_save(mem, info, filename, options);
else
throw std::runtime_error("unrecognised YUV/RGB save format");
Expand Down
11 changes: 11 additions & 0 deletions utils/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,12 @@ def check_metadata_txt(file, preamble):


def test_still(exe_dir, output_dir):
platform = get_platform()
executable = os.path.join(exe_dir, 'rpicam-still')
output_jpg = os.path.join(output_dir, 'test.jpg')
output_png = os.path.join(output_dir, 'test.png')
output_bmp = os.path.join(output_dir, 'test.bmp')
output_rgb48 = os.path.join(output_dir, 'test.rgb')
output_dng = os.path.join(output_dir, 'test.dng')
output_metadata = os.path.join(output_dir, 'metadata.json')
output_metadata_txt = os.path.join(output_dir, 'metadata.txt')
Expand Down Expand Up @@ -256,6 +258,15 @@ def test_still(exe_dir, output_dir):
check_time(time_taken, 1.2, 10, "test_still: bmp test")
check_size(output_png, 1024, "test_still: bmp test")

if platform == 'pisp':
# "rgb48 test". Writes a 16bpp RGB raw image.
print(" 48bpp test")
retcode, time_taken = run_executable(
[executable, '-t', '1000', '-e', 'rgb48', '-o', output_rgb48], logfile)
check_retcode(retcode, "test_still: rgb48 test")
check_time(time_taken, 1.2, 10, "test_still: rgb48 test")
check_size(output_rgb48, 1024 * 1024, "test_still: rgb48 test")

# "dng test". Write a dng along with the jpg.
print(" dng test")
retcode, time_taken = run_executable(
Expand Down