Files
panopainter/src/legacy_recording_services.cpp

184 lines
5.0 KiB
C++

#include "pch.h"
#include "legacy_recording_services.h"
#include "app.h"
#include "canvas.h"
#include "app_core/app_status.h"
#include "legacy_app_dialog_services.h"
#include "legacy_ui_overlay_services.h"
#include "node_progress_bar.h"
namespace pp::panopainter {
void update_legacy_recording_frame_label(App& app);
namespace {
pp::app::RecordingWorkerIterationPlan make_recording_worker_iteration_plan(App& app)
{
auto* legacy_canvas = Canvas::I;
auto* canvas_document = app.canvas ? app.canvas->m_canvas.get() : nullptr;
auto* encoder = legacy_canvas ? legacy_canvas->m_encoder.get() : nullptr;
return pp::app::plan_recording_worker_iteration(
app.rec_running,
encoder != nullptr,
legacy_canvas != nullptr && canvas_document != nullptr);
}
void encode_recording_frame(
App& app,
const pp::app::RecordingWorkerIterationPlan& plan,
Canvas* legacy_canvas,
Canvas* canvas_document,
CanvasEncoder* encoder)
{
if (plan.clear_dirty_stroke)
canvas_document->m_dirty_stroke = false;
PBO equirect = legacy_canvas->m_layers_merge.gen_equirect_pbo(encoder->frame_size());
std::this_thread::yield();
ImageRef img;
img.create(equirect.width, equirect.height, equirect.map());
encoder->encode(img);
equirect.unmap();
LOG("rec frame encoded");
if (plan.update_frame_label)
update_legacy_recording_frame_label(app);
}
} // namespace
void update_legacy_recording_frame_label(App& app)
{
if (auto txt = app.layout[app.main_id]->find<NodeText>("txt-rec"))
{
const auto label = pp::app::make_recording_frame_label(
app.rec_running,
Canvas::I->m_encoder != nullptr,
Canvas::I->m_encoder ? Canvas::I->m_encoder->frames_count() : 0);
txt->set_text(label.text.c_str());
}
}
namespace {
class LegacyRecordingServices final : public pp::app::RecordingServices {
public:
explicit LegacyRecordingServices(App& app) noexcept
: app_(app)
{
}
void start_thread() override
{
update_legacy_recording_frame_label(app_);
app_.rec_thread = std::jthread(&App::rec_loop, &app_);
}
void stop_thread() override
{
app_.rec_thread.request_stop();
app_.rec_running = false;
app_.rec_cv.notify_all();
if (app_.rec_thread.joinable())
app_.rec_thread.join();
update_legacy_recording_frame_label(app_);
}
void delete_recorded_files() override
{
app_.clear_platform_recorded_files(app_.rec_path);
}
void set_frame_count(int frame_count) override
{
app_.rec_count = frame_count;
}
void update_frame_label() override
{
update_legacy_recording_frame_label(app_);
}
void begin_export(int progress_total) override
{
pp::app::RecordingExportPlan plan;
plan.progress_total = progress_total;
progress_ = pp::panopainter::create_legacy_app_progress_dialog(
app_,
pp::app::plan_recording_export_progress_dialog(plan)).get();
}
void write_mp4(std::string_view path) override
{
Canvas::I->m_encoder->write_mp4(std::string(path));
}
void end_export() override
{
if (progress_)
pp::panopainter::close_legacy_dialog_node(*progress_);
progress_ = nullptr;
}
private:
App& app_;
NodeProgressBar* progress_ = nullptr;
};
} // namespace
bool process_legacy_recording_worker_iteration(App& app)
{
std::unique_lock<std::mutex> lock(app.rec_mutex);
app.rec_cv.wait(lock);
const auto plan = make_recording_worker_iteration_plan(app);
if (!plan.continue_running)
return false;
auto* legacy_canvas = Canvas::I;
auto* canvas_document = app.canvas ? app.canvas->m_canvas.get() : nullptr;
auto* encoder = legacy_canvas ? legacy_canvas->m_encoder.get() : nullptr;
if (plan.encode_frame && legacy_canvas && canvas_document && encoder)
encode_recording_frame(app, plan, legacy_canvas, canvas_document, encoder);
return true;
}
pp::foundation::Status execute_legacy_recording_start_action(
App& app,
pp::app::RecordingStartAction action)
{
LegacyRecordingServices services(app);
return pp::app::execute_recording_start_action(action, services);
}
pp::foundation::Status execute_legacy_recording_stop_action(
App& app,
pp::app::RecordingStopAction action)
{
LegacyRecordingServices services(app);
return pp::app::execute_recording_stop_action(action, services);
}
pp::foundation::Status execute_legacy_recording_clear_plan(
App& app,
const pp::app::RecordingClearPlan& plan)
{
LegacyRecordingServices services(app);
return pp::app::execute_recording_clear_plan(plan, services);
}
pp::foundation::Status execute_legacy_recording_export_plan(
App& app,
const pp::app::RecordingExportPlan& plan,
std::string_view path)
{
LegacyRecordingServices services(app);
return pp::app::execute_recording_export_plan(plan, services, path);
}
} // namespace pp::panopainter