Skip to content

Commit

Permalink
RSDK-4370 Expand GST pipeline generator to handle libcamera source (#7)
Browse files Browse the repository at this point in the history
* support libcamera gst pipeline
  • Loading branch information
seanavery authored Oct 19, 2023
1 parent 95158b9 commit a59475f
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 45 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ link_directories(
)

# Main executable
add_executable(${PROJECT_NAME} main.cpp csi_camera.cpp)
add_executable(${PROJECT_NAME} main.cpp csi_camera.cpp utils.cpp)

target_link_libraries(${PROJECT_NAME}
${GSTREAMER_LIBRARIES}
Expand Down
23 changes: 16 additions & 7 deletions constraints.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,25 @@
#define GST_GET_STATE_TIMEOUT 1
#define GST_CHANGE_STATE_TIMEOUT 5

// Camera
#define DEFAULT_INPUT_SOURCE "nvarguscamerasrc"
// Pipeline
#define DEFAULT_INPUT_SOURCE "libcamerasrc"
#define DEFAULT_INPUT_SENSOR "0"
#define DEFAULT_INPUT_FORMAT "video/x-raw(memory:NVMM)"
#define DEFAULT_INPUT_FORMAT "video/x-raw"
#define DEFAULT_INPUT_WIDTH 1920
#define DEFAULT_INPUT_HEIGHT 1080
#define DEFAULT_INPUT_FRAMERATE 30
#define DEFAULT_INPUT_FLIP_METHOD "0"
#define DEFAULT_OUTPUT_FORMAT "video/x-raw"
#define DEFAULT_OUTPUT_WIDTH 960
#define DEFAULT_OUTPUT_HEIGHT 540
#define DEFAULT_VIDEO_CONVERTER "videoconvert"
#define DEFAULT_OUTPUT_ENCODER "nvjpegenc"
#define DEFAULT_OUTPUT_MIMETYPE "image/jpeg"

// Jetson
#define JETSON_INPUT_SOURCE "nvarguscamerasrc"
#define JETSON_INPUT_FORMAT "video/x-raw(memory:NVMM)"
#define JETSON_VIDEO_CONVERTER "nvvidconv"
#define JETSON_OUTPUT_ENCODER "nvjpegenc"

// Pi
#define PI_INPUT_SOURCE "libcamerasrc"
#define PI_INPUT_FORMAT "video/x-raw"
#define PI_VIDEO_CONVERTER "videoconvert"
#define PI_OUTPUT_ENCODER "jpegenc"
24 changes: 12 additions & 12 deletions csi_camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@

#include "constraints.h"
#include "csi_camera.h"
#include "utils.h"

using namespace viam::sdk;

CSICamera::CSICamera(const std::string name, const AttributeMap attrs) : Camera(std::move(name)) {
device_type device = get_device_type();
std::cout << "Device type: " << device.name << std::endl;
device = get_device_type();
std::cout << "Creating CSICamera with name: " << name << std::endl;
std::cout << "Device type: " << device.name << std::endl;
init(attrs);
}

Expand Down Expand Up @@ -288,19 +287,20 @@ std::vector<unsigned char> CSICamera::get_csi_image() {
}

std::string CSICamera::create_pipeline() const {
std::ostringstream oss;
auto device_params = get_device_params(device);
std::string input_sensor = (device.value == device_type::jetson) ? (" sensor-id="+video_path) : "";

oss << DEFAULT_INPUT_SOURCE << " sensor_id=" << video_path
<< " ! " << DEFAULT_INPUT_FORMAT
std::ostringstream oss;
oss << device_params.input_source
<< input_sensor
<< " ! " << device_params.input_format
<< ",width=" << std::to_string(width_px)
<< ",height=" << std::to_string(height_px)
<< ",framerate=" << std::to_string(frame_rate)
<< "/1 ! nvvidconv flip-method=" << DEFAULT_INPUT_FLIP_METHOD
<< " ! " << DEFAULT_OUTPUT_FORMAT
<< ",width=" << std::to_string(DEFAULT_OUTPUT_WIDTH)
<< ",height=" << std::to_string(DEFAULT_OUTPUT_HEIGHT)
<< " ! " << DEFAULT_OUTPUT_ENCODER
<< " ! " << DEFAULT_OUTPUT_MIMETYPE
<< "/1 ! " << device_params.video_converter
<< " ! " << device_params.output_encoder
<< " ! " << "image/jpeg"
<< " ! queue"
<< " ! appsink name=appsink0 max-buffers=1";

return oss.str();
Expand Down
5 changes: 5 additions & 0 deletions csi_camera.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@
#include <viam/sdk/components/camera/camera.hpp>
#include <viam/api/component/camera/v1/camera.grpc.pb.h>

#include "utils.h"

using namespace viam::sdk;

class CSICamera : public Camera {
private:
// Device
device_type device;

// Camera
bool debug;
int width_px = 0;
Expand Down
1 change: 1 addition & 0 deletions test/test_csi_camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <viam/sdk/components/camera/camera.hpp>

#include "../csi_camera.cpp"
#include "../utils.cpp"
#include "../constraints.h"

using namespace viam::sdk;
Expand Down
4 changes: 4 additions & 0 deletions test/test_pi_pipeline.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
gst-launch-1.0 libcamerasrc \
! 'video/x-raw,width=1920,height=1080,framerate=30/1' \
! videoconvert \
! jpegenc ! image/jpeg ! appsink name=appsink0 max-buffers=1
55 changes: 55 additions & 0 deletions utils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include <fstream>
#include <algorithm>

#include "utils.h"

device_type get_device_type() {
std::ifstream device_name(DEVICE_PATH);
if (device_name.is_open()) {
std::string line;
while (std::getline(device_name, line)) {
std::string lowercase_line = line;
std::transform(lowercase_line.begin(), lowercase_line.end(), lowercase_line.begin(), ::tolower);
// Check for specific terms in a case-insensitive manner
if (lowercase_line.find("nvidia") != std::string::npos &&
(lowercase_line.find("orin") != std::string::npos ||
lowercase_line.find("nano") != std::string::npos ||
lowercase_line.find("agx") != std::string::npos ||
lowercase_line.find("jetson") != std::string::npos)) {
return device_type(device_type::jetson, "Jetson");
} else if (lowercase_line.find("raspberry") != std::string::npos &&
lowercase_line.find("pi") != std::string::npos) {
return device_type(device_type::pi, "Raspberry Pi");
}
}
device_name.close();
}

return device_type(device_type::unknown, "unkwnown");
}

device_params get_device_params(device_type device) {
switch (device.value) {
case device_type::jetson:
return device_params {
.input_source = JETSON_INPUT_SOURCE,
.input_format = JETSON_INPUT_FORMAT,
.video_converter = JETSON_VIDEO_CONVERTER,
.output_encoder = JETSON_OUTPUT_ENCODER
};
case device_type::pi:
return device_params {
.input_source = PI_INPUT_SOURCE,
.input_format = PI_INPUT_FORMAT,
.video_converter = PI_VIDEO_CONVERTER,
.output_encoder = PI_OUTPUT_ENCODER
};
default:
return device_params {
.input_source = DEFAULT_INPUT_SOURCE,
.input_format = DEFAULT_INPUT_FORMAT,
.video_converter = DEFAULT_VIDEO_CONVERTER,
.output_encoder = DEFAULT_OUTPUT_ENCODER
};
}
}
36 changes: 11 additions & 25 deletions utils.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#pragma once

#include <iostream>
#include <string>
#include <fstream>

#include "constraints.h"

#define DEVICE_PATH "/proc/device-tree/model"

Expand All @@ -15,30 +15,16 @@ struct device_type {
type value;
std::string name;

device_type() : value(unknown), name("unknown") {} // Default constructor
device_type(type value, std::string name) : value(value), name(name) {}
};

device_type get_device_type() {
std::ifstream device_name(DEVICE_PATH);
if (device_name.is_open()) {
std::string line;
while (std::getline(device_name, line)) {
std::string lowercase_line = line;
std::transform(lowercase_line.begin(), lowercase_line.end(), lowercase_line.begin(), ::tolower);
// Check for specific terms in a case-insensitive manner
if (lowercase_line.find("nvidia") != std::string::npos &&
(lowercase_line.find("orin") != std::string::npos ||
lowercase_line.find("nano") != std::string::npos ||
lowercase_line.find("agx") != std::string::npos ||
lowercase_line.find("jetson") != std::string::npos)) {
return device_type(device_type::jetson, "Jetson");
} else if (lowercase_line.find("raspberry") != std::string::npos &&
lowercase_line.find("pi") != std::string::npos) {
return device_type(device_type::pi, "Raspberry Pi");
}
}
device_name.close();
}
struct device_params {
std::string input_source;
std::string input_format;
std::string video_converter;
std::string output_encoder;
};

return device_type(device_type::unknown, "unkwnown");
}
device_type get_device_type();
device_params get_device_params(device_type device);

0 comments on commit a59475f

Please sign in to comment.