|
|
@@ -0,0 +1,169 @@
|
|
|
+#include "image_player_impl.h"
|
|
|
+#include "core/imgui_utility.hpp"
|
|
|
+
|
|
|
+void image_player::impl::create_decoder() {
|
|
|
+ switch (chose_decoder_type) {
|
|
|
+ case DECODER_NVDEC: {
|
|
|
+ auto dec_conf = decoder_nvdec::create_config{
|
|
|
+ .img_name = conf.img_name, .stream = conf.stream
|
|
|
+ };
|
|
|
+ assert(dec_nvdec == nullptr);
|
|
|
+ dec_nvdec = std::make_unique<decoder_nvdec>(dec_conf);
|
|
|
+ assert(dec_nvdec != nullptr);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ default: {
|
|
|
+ RET_ERROR;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void image_player::impl::create_receiver() {
|
|
|
+ if (enable_aux_thread) {
|
|
|
+ assert(aux_ctx != nullptr);
|
|
|
+ recv_ctx = aux_ctx.get();
|
|
|
+ } else {
|
|
|
+ recv_ctx = ctx;
|
|
|
+ }
|
|
|
+
|
|
|
+ assert(receiver == nullptr);
|
|
|
+ switch (chose_receiver_type) {
|
|
|
+ case RECEIVER_UDP_FEC: {
|
|
|
+ auto recv_conf = receiver_udp_fec::create_config();
|
|
|
+ recv_conf.server_addr = recv_server_addr;
|
|
|
+ recv_conf.server_port = recv_server_port;
|
|
|
+ recv_conf.ctx = recv_ctx;
|
|
|
+ recv_conf.cb_func = [this](auto frame) { frame_callback(frame); };
|
|
|
+ recv_conf.enable_log = recv_enable_log;
|
|
|
+ receiver = receiver_udp_fec::create(recv_conf);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ default: {
|
|
|
+ RET_ERROR;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ assert(receiver != nullptr);
|
|
|
+}
|
|
|
+
|
|
|
+void image_player::impl::frame_callback(const frame_info &frame) {
|
|
|
+ if (enable_aux_thread) {
|
|
|
+ assert(frame_queue != nullptr);
|
|
|
+ frame_queue->push(frame, frame.idr);
|
|
|
+ } else {
|
|
|
+ decode_image(frame);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void image_player::impl::decode_image(const frame_info &frame) {
|
|
|
+ switch (chose_decoder_type) {
|
|
|
+ case DECODER_NVDEC: {
|
|
|
+ dec_nvdec->decode(frame);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ default: {
|
|
|
+ RET_ERROR;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void image_player::impl::start() {
|
|
|
+ if (enable_aux_thread) {
|
|
|
+ assert(aux_ctx == nullptr);
|
|
|
+ aux_ctx = std::make_unique<io_context>();
|
|
|
+
|
|
|
+ auto queue_conf = frame_queue_type::create_config();
|
|
|
+ queue_conf.ctx = ctx;
|
|
|
+ queue_conf.tid = std::this_thread::get_id();
|
|
|
+ queue_conf.cb_func = [this](auto frame) { decode_image(frame); };
|
|
|
+ assert(frame_queue == nullptr);
|
|
|
+ frame_queue = frame_queue_type::create(queue_conf);
|
|
|
+ }
|
|
|
+
|
|
|
+ create_decoder();
|
|
|
+ create_receiver();
|
|
|
+
|
|
|
+ if (enable_aux_thread) {
|
|
|
+ aux_thread = std::make_unique<std::thread>([this] {
|
|
|
+ auto blocker = boost::asio::make_work_guard(*aux_ctx);
|
|
|
+ aux_ctx->run();
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ assert(!is_running);
|
|
|
+ is_running = true;
|
|
|
+}
|
|
|
+
|
|
|
+void image_player::impl::stop() {
|
|
|
+ if (enable_aux_thread) {
|
|
|
+ aux_ctx->stop();
|
|
|
+ aux_thread->join();
|
|
|
+ aux_thread = nullptr;
|
|
|
+ }
|
|
|
+
|
|
|
+ dec_nvdec = nullptr;
|
|
|
+ receiver = nullptr;
|
|
|
+ aux_ctx = nullptr;
|
|
|
+
|
|
|
+ assert(is_running);
|
|
|
+ is_running = false;
|
|
|
+}
|
|
|
+
|
|
|
+void image_player::impl::show_config() {
|
|
|
+ auto guard = imgui_disable_guard(is_running);
|
|
|
+
|
|
|
+ ImGui::SeparatorText("Sender Configs");
|
|
|
+ ImGui::InputText("Server IP", recv_server_addr, addr_max_length);
|
|
|
+ ImGui::InputScalar("Server Port", ImGuiDataType_U16, &recv_server_port);
|
|
|
+ // chose receive method
|
|
|
+ if (ImGui::RadioButton("TCP", chose_receiver_type == RECEIVER_TCP)) {
|
|
|
+ chose_receiver_type = RECEIVER_TCP;
|
|
|
+ }
|
|
|
+ if (chose_decoder_type != DECODER_NVDEC) {
|
|
|
+ ImGui::SameLine();
|
|
|
+ if (ImGui::RadioButton("UDP", chose_receiver_type == RECEIVER_UDP)) {
|
|
|
+ chose_receiver_type = RECEIVER_UDP;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ImGui::SameLine();
|
|
|
+ if (ImGui::RadioButton("UDP (FEC)", chose_receiver_type == RECEIVER_UDP_FEC)) {
|
|
|
+ chose_receiver_type = RECEIVER_UDP_FEC;
|
|
|
+ }
|
|
|
+ ImGui::Checkbox("Enable Log", &recv_enable_log);
|
|
|
+
|
|
|
+ ImGui::SeparatorText("Decoder Configs");
|
|
|
+ // chose decoding method
|
|
|
+ if (ImGui::RadioButton("NvDec", chose_decoder_type == DECODER_NVDEC)) {
|
|
|
+ chose_decoder_type = DECODER_NVDEC;
|
|
|
+ if (chose_receiver_type == RECEIVER_UDP) {
|
|
|
+ chose_receiver_type = RECEIVER_TCP;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ImGui::SameLine();
|
|
|
+ if (ImGui::RadioButton("nvJPEG", chose_decoder_type == DECODER_JPEG)) {
|
|
|
+ chose_decoder_type = DECODER_JPEG;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void image_player::impl::show() {
|
|
|
+ ImGui::SeparatorText("Actions");
|
|
|
+ if (!is_running) {
|
|
|
+ if (ImGui::Button("Start")) {
|
|
|
+ post(*ctx, [this] { start(); });
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (ImGui::Button("Close")) {
|
|
|
+ post(*ctx, [this] { stop(); });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ show_config();
|
|
|
+}
|
|
|
+
|
|
|
+image_player::image_player(create_config conf)
|
|
|
+ : pimpl(std::make_unique<impl>(conf)) {
|
|
|
+}
|
|
|
+
|
|
|
+image_player::~image_player() = default;
|
|
|
+
|
|
|
+void image_player::show() {
|
|
|
+ pimpl->show();
|
|
|
+}
|