add MP4Encoder class and test timelapse exporting
This commit is contained in:
47
src/app.cpp
47
src/app.cpp
@@ -4,6 +4,7 @@
|
||||
#include "node_icon.h"
|
||||
#include "node_dialog_open.h"
|
||||
#include "node_progress_bar.h"
|
||||
#include "mp4enc.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <Foundation/Foundation.h>
|
||||
@@ -616,14 +617,15 @@ void App::draw(float dt)
|
||||
{
|
||||
static float rec_timer = 0.f;
|
||||
rec_timer += dt;
|
||||
if (rec_timer > 1.f && canvas->m_canvas->m_dirty_stroke)
|
||||
if (rec_timer > 0.3f && canvas->m_canvas->m_dirty_stroke)
|
||||
{
|
||||
canvas->m_canvas->m_dirty_stroke = false;
|
||||
|
||||
LOG("rec tick");
|
||||
rec_timer = 0.f;
|
||||
|
||||
auto data = new uint8_t[(int)width * (int)height * 4];
|
||||
auto img = std::make_unique<Image>();
|
||||
img->create(width, height);
|
||||
#if __IOS__
|
||||
[ios_view->glview bindDrawable];
|
||||
#else
|
||||
@@ -636,10 +638,10 @@ void App::draw(float dt)
|
||||
if (dfbo != rfbo)
|
||||
LOG("DIFFERENT FB");
|
||||
|
||||
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, img->m_data.get());
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(rec_mutex);
|
||||
rec_frames.emplace_back(data);
|
||||
rec_frames.emplace_back(std::move(img));
|
||||
rec_cv.notify_all();
|
||||
}
|
||||
update_rec_frames();
|
||||
@@ -805,11 +807,14 @@ void App::rec_export(std::string path)
|
||||
pb->m_progress->SetWidthP(0);
|
||||
pb->m_title->set_text("Exporting MP4 movie");
|
||||
|
||||
/*
|
||||
#if defined(__IOS__) || defined(__OSX__)
|
||||
export_mp4(rec_path, width, height, rec_count, ^(float) {
|
||||
pb->m_progress->SetWidthP((float)progress / tot * 100.f);
|
||||
});
|
||||
#endif
|
||||
*/
|
||||
m_encoder->write_mp4(data_path + "/export.mp4");
|
||||
|
||||
pb->destroy();
|
||||
}
|
||||
@@ -818,8 +823,14 @@ void App::rec_loop()
|
||||
{
|
||||
BT_SetTerminate();
|
||||
rec_running = true;
|
||||
if (!m_encoder)
|
||||
{
|
||||
m_encoder = std::make_unique<MP4Encoder>();
|
||||
m_encoder->init(512, 512, 30, 500 << 10);
|
||||
}
|
||||
while(rec_running)
|
||||
{
|
||||
std::unique_ptr<Image> frame;
|
||||
std::unique_lock<std::mutex> lock(rec_mutex);
|
||||
rec_cv.wait(lock);
|
||||
if (!rec_running)
|
||||
@@ -828,32 +839,14 @@ void App::rec_loop()
|
||||
{
|
||||
if (rec_frames.front())
|
||||
{
|
||||
auto inverted = std::make_unique<uint8_t[]>(width*height*4);
|
||||
for (int y = height - 1, y1 = 0; y >= 0; y--, y1++)
|
||||
{
|
||||
uint8_t* dst = &inverted[y * width * 4];
|
||||
uint8_t* src = &rec_frames.front()[y1 * width * 4];
|
||||
std::copy_n(src, (int)width * 4, dst);
|
||||
}
|
||||
char path[256];
|
||||
snprintf(path, sizeof(path), "%s/%04d.jpg", rec_path.c_str(), rec_count);
|
||||
LOG("writing %s", path);
|
||||
jpge::params params;
|
||||
params.m_quality = 75;
|
||||
bool saved = jpge::compress_image_to_jpeg_file(path, width, height, 4, inverted.get(), params);
|
||||
if (!saved)
|
||||
{
|
||||
LOG("error writing the frame");
|
||||
rec_running = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
rec_count++;
|
||||
redraw = true;
|
||||
}
|
||||
rec_count++;
|
||||
frame = std::move(rec_frames.front());
|
||||
}
|
||||
rec_frames.pop_front();
|
||||
}
|
||||
lock.unlock();
|
||||
if (frame)
|
||||
m_encoder->encode(*frame);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user