st-2110-20 pipeline API MTL node in
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include <exception>
|
||||
|
||||
#include <mxl/flow.h>
|
||||
#include <mxl/time.h>
|
||||
|
||||
#include "NodeBase.hpp"
|
||||
#include "ST2110Receiver.hpp"
|
||||
#include "V210.hpp"
|
||||
|
||||
namespace dmf {
|
||||
|
||||
class ST2110In : public NodeBase {
|
||||
void run() override {
|
||||
ST2110ReceiverConfig cfg;
|
||||
try {
|
||||
cfg = parse_st2110_receiver_config(config());
|
||||
} catch (const std::exception& e) {
|
||||
log("config error: %s", e.what());
|
||||
return;
|
||||
}
|
||||
|
||||
log("SMPTE 2110-20 RX %s:%u from %s on %s local=%s %dx%d @ %d/%d",
|
||||
cfg.mcast_ip.c_str(), cfg.udp_port, cfg.source_ip.c_str(), cfg.ifname.c_str(),
|
||||
cfg.local_ip.c_str(), cfg.width, cfg.height, cfg.fps_num, cfg.fps_den);
|
||||
|
||||
try {
|
||||
MTLContext mtl(cfg);
|
||||
ST20RxSession rx(mtl.get(), mtl.port_name(), cfg);
|
||||
MXLVideoWriter writer(instance(), cfg, node_id());
|
||||
|
||||
const mxlRational video_rate = {cfg.fps_num, cfg.fps_den};
|
||||
const uint32_t video_stride = writer.config().discrete.sliceSizes[0];
|
||||
const uint32_t uyvy_stride = static_cast<uint32_t>(cfg.width * 2);
|
||||
uint64_t frames_written = 0;
|
||||
|
||||
while (g_running.load(std::memory_order_relaxed)) {
|
||||
st_frame* frame = st20p_rx_get_frame(rx.get());
|
||||
if (!frame) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!st_is_frame_complete(frame->status)) {
|
||||
st20p_rx_put_frame(rx.get(), frame);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (frame->fmt != ST_FRAME_FMT_UYVY) {
|
||||
log("unexpected MTL frame fmt=%d; expected UYVY", frame->fmt);
|
||||
st20p_rx_put_frame(rx.get(), frame);
|
||||
continue;
|
||||
}
|
||||
|
||||
mxlGrainInfo grain{};
|
||||
uint8_t* video_buf = nullptr;
|
||||
const uint64_t video_index = mxlGetCurrentIndex(&video_rate);
|
||||
mxlStatus st = mxlFlowWriterOpenGrain(writer.get(), video_index, &grain, &video_buf);
|
||||
if (st != MXL_STATUS_OK) {
|
||||
log("mxlFlowWriterOpenGrain failed (%s) index=%llu", mxl_status_str(st),
|
||||
static_cast<unsigned long long>(video_index));
|
||||
st20p_rx_put_frame(rx.get(), frame);
|
||||
continue;
|
||||
}
|
||||
|
||||
v210::UYVYtoV210(static_cast<const uint8_t*>(frame->addr[0]), video_buf,
|
||||
cfg.width, cfg.height, uyvy_stride, video_stride);
|
||||
grain.flags = 0;
|
||||
grain.validSlices = grain.totalSlices;
|
||||
mxlFlowWriterCommitGrain(writer.get(), &grain);
|
||||
st20p_rx_put_frame(rx.get(), frame);
|
||||
|
||||
frames_written++;
|
||||
if (frames_written % 100 == 0) {
|
||||
log("received %llu frames", static_cast<unsigned long long>(frames_written));
|
||||
}
|
||||
}
|
||||
|
||||
log("stopped after %llu frames", static_cast<unsigned long long>(frames_written));
|
||||
} catch (const std::exception& e) {
|
||||
log("error: %s", e.what());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dmf
|
||||
|
||||
int main() {
|
||||
dmf::ST2110In node;
|
||||
return node.execute();
|
||||
}
|
||||
Reference in New Issue
Block a user