OrangePi3588Media/plugins/publish/publish_node.cpp

87 lines
2.8 KiB
C++

#include <atomic>
#include <chrono>
#include <iostream>
#include <thread>
#include "node.h"
namespace rk3588 {
class PublishNode : public INode {
public:
std::string Id() const override { return id_; }
std::string Type() const override { return "publish"; }
bool Init(const SimpleJson& config, const NodeContext& ctx) override {
id_ = config.ValueOr<std::string>("id", "publish");
input_queue_ = ctx.input_queue;
codec_ = config.ValueOr<std::string>("codec", "h264");
fps_ = config.ValueOr<int>("fps", 25);
gop_ = config.ValueOr<int>("gop", 50);
bitrate_kbps_ = config.ValueOr<int>("bitrate_kbps", 4000);
// Outputs array optional; log first entry if present.
const SimpleJson* outputs = config.Find("outputs");
if (outputs && outputs->IsArray() && !outputs->AsArray().empty()) {
const auto& first = outputs->AsArray().front();
if (first.IsObject()) {
port_ = first.ValueOr<int>("port", 8554);
path_ = first.ValueOr<std::string>("path", "/live/cam1");
}
}
if (!input_queue_) {
std::cerr << "[publish] no input queue for node " << id_ << "\n";
return false;
}
return true;
}
bool Start() override {
if (!input_queue_) return false;
running_.store(true);
worker_ = std::thread(&PublishNode::Loop, this);
std::cout << "[publish] start codec=" << codec_ << " fps=" << fps_ << " gop=" << gop_
<< " bitrate=" << bitrate_kbps_ << "kbps target rtsp://0.0.0.0:" << port_
<< path_ << "\n";
return true;
}
void Stop() override {
running_.store(false);
if (input_queue_) input_queue_->Stop();
if (worker_.joinable()) worker_.join();
}
private:
void Loop() {
using namespace std::chrono;
FramePtr frame;
while (running_.load()) {
if (!input_queue_->Pop(frame, milliseconds(200))) {
continue;
}
++encoded_frames_;
if (encoded_frames_ % 100 == 0 && frame) {
std::cout << "[publish] encoded frame " << frame->frame_id
<< " queue=" << input_queue_->Size()
<< " drops=" << input_queue_->DroppedCount() << "\n";
}
}
}
std::string id_;
std::string codec_ = "h264";
int fps_ = 25;
int gop_ = 50;
int bitrate_kbps_ = 4000;
int port_ = 8554;
std::string path_ = "/live/cam1";
std::atomic<bool> running_{false};
std::shared_ptr<SpscQueue<FramePtr>> input_queue_;
std::thread worker_;
uint64_t encoded_frames_ = 0;
};
REGISTER_NODE(PublishNode, "publish");
} // namespace rk3588