add gst decoder

This commit is contained in:
Joe Dong
2023-08-27 16:14:34 +08:00
parent 7647f37622
commit 8480674a5d
7 changed files with 160 additions and 10 deletions
+97
View File
@@ -0,0 +1,97 @@
#include "orbbec_camera/gst_decoder.h"
#include <rclcpp/rclcpp.hpp>
#include <gst/app/gstappsrc.h>
#include <gst/app/gstappsink.h>
namespace orbbec_camera {
std::string hwDecoderToString(HWDecoder hw_decoder) {
switch (hw_decoder) {
case HWDecoder::ROCKCHIP_MPP:
return "mppjpegdec";
case HWDecoder::NV_JPEG_DEC:
return "nvjpegdec";
case HWDecoder::AMLOGIC_CODEC:
return "amlvenc";
default:
return "unknown";
}
}
GstreamerMjpegDecoder::GstreamerMjpegDecoder(int width, int height, HWDecoder hw_decoder)
: MjpegDecoder(width, height),
hw_decoder_(hwDecoderToString(hw_decoder)),
buffer_size_(width * height * 3) {
buffer_pool_ = gst_buffer_pool_new();
GstStructure* config = gst_buffer_pool_get_config(buffer_pool_);
gst_buffer_pool_config_set_params(config, NULL, buffer_size_, 0, 0);
if (hw_decoder_ == "unknown") {
RCLCPP_ERROR_STREAM(rclcpp::get_logger("gstreamer_mjpeg_decoder"), "hw decoder is unknown");
throw std::runtime_error("hw decoder is unknown");
}
if (!gst_buffer_pool_set_config(buffer_pool_, config)) {
RCLCPP_ERROR_STREAM(rclcpp::get_logger("gstreamer_mjpeg_decoder"),
"gst buffer pool set config error");
throw std::runtime_error("gst buffer pool set config error");
}
if (gst_buffer_pool_set_active(buffer_pool_, TRUE) != TRUE) {
RCLCPP_ERROR_STREAM(rclcpp::get_logger("gstreamer_mjpeg_decoder"),
"gst buffer pool set active error");
throw std::runtime_error("gst buffer pool set active error");
}
std::string pipeline_str = "appsrc name=src is-live=true do-timestamp=true ! " + hw_decoder_ +
" ! videoconvert ! video/x-raw,format=RGB ! appsink name=sink";
pipeline_ = gst_parse_launch(pipeline_str.c_str(), NULL);
if (!pipeline_) {
RCLCPP_ERROR_STREAM(rclcpp::get_logger("gstreamer_mjpeg_decoder"), "gst parse launch error");
throw std::runtime_error("gst parse launch error");
}
appsrc_ = gst_bin_get_by_name(GST_BIN(pipeline_), "appsrc0");
appsink_ = gst_bin_get_by_name(GST_BIN(pipeline_), "appsink0");
}
GstreamerMjpegDecoder::~GstreamerMjpegDecoder() {
if (pipeline_) {
gst_element_set_state(pipeline_, GST_STATE_NULL);
gst_object_unref(pipeline_);
pipeline_ = nullptr;
}
if (buffer_pool_) {
gst_buffer_pool_set_active(buffer_pool_, FALSE);
g_object_unref(buffer_pool_);
}
}
bool GstreamerMjpegDecoder::decode(const std::shared_ptr<ob::ColorFrame>& frame, uint8_t* dest) {
GstBuffer* buffer = NULL;
GstMapInfo map;
if (gst_buffer_pool_acquire_buffer(buffer_pool_, &buffer, NULL) != GST_FLOW_OK) {
RCLCPP_ERROR_STREAM(rclcpp::get_logger("gstreamer_mjpeg_decoder"),
"gst buffer pool acquire buffer error");
return false;
}
gst_buffer_map(buffer, &map, GST_MAP_WRITE);
memcpy(map.data, frame->data(), frame->dataSize());
gst_buffer_unmap(buffer, &map); // Unmap the buffer after copying
gst_app_src_push_buffer(GST_APP_SRC(appsrc_), buffer);
GstSample* sample = gst_app_sink_pull_sample(GST_APP_SINK(appsink_));
if (sample) {
GstBuffer* outBuffer = gst_sample_get_buffer(sample);
GstMapInfo mapInfo;
gst_buffer_map(outBuffer, &mapInfo, GST_MAP_READ);
// Copy data to destination buffer
memcpy(dest, mapInfo.data, mapInfo.size);
gst_buffer_unmap(outBuffer, &mapInfo);
gst_sample_unref(sample);
return true;
} else {
RCLCPP_ERROR_STREAM(rclcpp::get_logger("gstreamer_mjpeg_decoder"), "Failed to decode frame");
return false;
}
}
} // namespace orbbec_camera
+2 -9
View File
@@ -2,14 +2,7 @@
#include <orbbec_camera/mjpeg_decoder.h>
namespace orbbec_camera {
MjpegDecoder::MjpegDecoder(int width, int height) : width_(width), height_(height) {
rgb_buffer_ = new uint8_t[width_ * height_ * 3];
}
MjpegDecoder::~MjpegDecoder() {
if (rgb_buffer_) {
delete[] rgb_buffer_;
rgb_buffer_ = nullptr;
}
}
MjpegDecoder::MjpegDecoder(int width, int height) : width_(width), height_(height) {}
MjpegDecoder::~MjpegDecoder() {}
} // namespace orbbec_camera
+4
View File
@@ -5,6 +5,7 @@
namespace orbbec_camera {
RKMjpegDecoder::RKMjpegDecoder(int width, int height) : MjpegDecoder(width, height) {
rgb_buffer_ = new uint8_t[width_ * height_ * 3];
MPP_RET ret = mpp_create(&mpp_ctx_, &mpp_api_);
if (ret != MPP_OK) {
RCLCPP_ERROR_STREAM(rclcpp::get_logger("rk_mpp_decoder"), "mpp_create failed, ret = " << ret);
@@ -100,6 +101,9 @@ RKMjpegDecoder::~RKMjpegDecoder() {
mpp_destroy(mpp_ctx_);
mpp_ctx_ = nullptr;
}
if(rgb_buffer_){
delete[] rgb_buffer_;
}
}
bool RKMjpegDecoder::mppFrame2RGB(const MppFrame frame, uint8_t *data) {