add MP4Encoder class and test timelapse exporting

This commit is contained in:
2019-10-31 23:22:09 +01:00
parent 8e94d6b401
commit 9eecf60219
11 changed files with 283 additions and 47 deletions

View File

@@ -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);
}
}