diff --git a/include/mgba/feature/video-logger.h b/include/mgba/feature/video-logger.h index d33e83155..2acd9c87f 100644 --- a/include/mgba/feature/video-logger.h +++ b/include/mgba/feature/video-logger.h @@ -104,6 +104,7 @@ void mVideoLoggerAttachChannel(struct mVideoLogger* logger, struct mVideoLogCont struct mCore; struct mVideoLogContext* mVideoLogContextCreate(struct mCore* core); +void mVideoLogContextSetCompression(struct mVideoLogContext*, bool enable); void mVideoLogContextSetOutput(struct mVideoLogContext*, struct VFile*); void mVideoLogContextWriteHeader(struct mVideoLogContext*, struct mCore* core); diff --git a/src/feature/video-logger.c b/src/feature/video-logger.c index be1c7b3f7..9e208f9f1 100644 --- a/src/feature/video-logger.c +++ b/src/feature/video-logger.c @@ -94,6 +94,7 @@ struct mVideoLogContext { struct mVideoLogChannel channels[mVL_MAX_CHANNELS]; bool write; + bool compression; uint32_t activeChannel; struct VFile* backing; }; @@ -465,6 +466,12 @@ struct mVideoLogContext* mVideoLogContextCreate(struct mCore* core) { context->initialStateSize = 0; context->initialState = NULL; +#ifdef USE_ZLIB + context->compression = true; +#else + context->compression = false; +#endif + if (core) { context->initialStateSize = core->stateSize(core); context->initialState = anonymousMemoryMap(context->initialStateSize); @@ -482,6 +489,10 @@ void mVideoLogContextSetOutput(struct mVideoLogContext* context, struct VFile* v vf->seek(vf, 0, SEEK_SET); } +void mVideoLogContextSetCompression(struct mVideoLogContext* context, bool compression) { + context->compression = compression; +} + void mVideoLogContextWriteHeader(struct mVideoLogContext* context, struct mCore* core) { struct mVideoLogHeader header = { { 0 } }; memcpy(header.magic, mVL_MAGIC, sizeof(header.magic)); @@ -499,21 +510,24 @@ void mVideoLogContextWriteHeader(struct mVideoLogContext* context, struct mCore* struct mVLBlockHeader chheader = { 0 }; STORE_32LE(mVL_BLOCK_INITIAL_STATE, 0, &chheader.blockType); #ifdef USE_ZLIB - STORE_32LE(mVL_FLAG_BLOCK_COMPRESSED, 0, &chheader.flags); + if (context->compression) { + STORE_32LE(mVL_FLAG_BLOCK_COMPRESSED, 0, &chheader.flags); - struct VFile* vfm = VFileMemChunk(NULL, 0); - struct VFile* src = VFileFromConstMemory(context->initialState, context->initialStateSize); - _compress(vfm, src); - src->close(src); - STORE_32LE(vfm->size(vfm), 0, &chheader.length); - context->backing->write(context->backing, &chheader, sizeof(chheader)); - _copyVf(context->backing, vfm); - vfm->close(vfm); -#else - STORE_32LE(context->initialStateSize, 0, &chheader.length); - context->backing->write(context->backing, &chheader, sizeof(chheader)); - context->backing->write(context->backing, context->initialState, context->initialStateSize); + struct VFile* vfm = VFileMemChunk(NULL, 0); + struct VFile* src = VFileFromConstMemory(context->initialState, context->initialStateSize); + _compress(vfm, src); + src->close(src); + STORE_32LE(vfm->size(vfm), 0, &chheader.length); + context->backing->write(context->backing, &chheader, sizeof(chheader)); + _copyVf(context->backing, vfm); + vfm->close(vfm); + } else #endif + { + STORE_32LE(context->initialStateSize, 0, &chheader.length); + context->backing->write(context->backing, &chheader, sizeof(chheader)); + context->backing->write(context->backing, context->initialState, context->initialStateSize); + } } size_t i; @@ -647,9 +661,10 @@ static void _flushBufferCompressed(struct mVideoLogContext* context) { static void _flushBuffer(struct mVideoLogContext* context) { #ifdef USE_ZLIB - // TODO: Make optional - _flushBufferCompressed(context); - return; + if (context->compression) { + _flushBufferCompressed(context); + return; + } #endif struct CircleBuffer* buffer = &context->channels[context->activeChannel].buffer; diff --git a/src/gb/core.c b/src/gb/core.c index 264f29bf1..9c00519a0 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -879,9 +879,11 @@ static void _GBCoreStartVideoLog(struct mCore* core, struct mVideoLogContext* co static void _GBCoreEndVideoLog(struct mCore* core) { struct GBCore* gbcore = (struct GBCore*) core; struct GB* gb = core->board; - GBVideoProxyRendererUnshim(&gb->video, &gbcore->proxyRenderer); - free(gbcore->proxyRenderer.logger); - gbcore->proxyRenderer.logger = NULL; + if (gbcore->proxyRenderer.logger) { + GBVideoProxyRendererUnshim(&gb->video, &gbcore->proxyRenderer); + free(gbcore->proxyRenderer.logger); + gbcore->proxyRenderer.logger = NULL; + } } #endif diff --git a/src/gba/core.c b/src/gba/core.c index 53925cc52..bf3a7ecfd 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -990,9 +990,11 @@ static void _GBACoreStartVideoLog(struct mCore* core, struct mVideoLogContext* c static void _GBACoreEndVideoLog(struct mCore* core) { struct GBACore* gbacore = (struct GBACore*) core; struct GBA* gba = core->board; - GBAVideoProxyRendererUnshim(&gba->video, &gbacore->proxyRenderer); - free(gbacore->proxyRenderer.logger); - gbacore->proxyRenderer.logger = NULL; + if (gbacore->proxyRenderer.logger) { + GBAVideoProxyRendererUnshim(&gba->video, &gbacore->proxyRenderer); + free(gbacore->proxyRenderer.logger); + gbacore->proxyRenderer.logger = NULL; + } } #endif diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index e1d4bc7ea..fb59baf5c 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -809,26 +809,39 @@ void CoreController::clearOverride() { m_override.reset(); } -void CoreController::startVideoLog(const QString& path) { +void CoreController::startVideoLog(const QString& path, bool compression) { if (m_vl) { return; } + VFile* vf = VFileDevice::open(path, O_WRONLY | O_CREAT | O_TRUNC); + if (!vf) { + return; + } + startVideoLog(vf); +} + +void CoreController::startVideoLog(VFile* vf, bool compression) { + if (m_vl || !vf) { + return; + } + Interrupter interrupter(this); m_vl = mVideoLogContextCreate(m_threadContext.core); - m_vlVf = VFileDevice::open(path, O_WRONLY | O_CREAT | O_TRUNC); + m_vlVf = vf; mVideoLogContextSetOutput(m_vl, m_vlVf); + mVideoLogContextSetCompression(m_vl, compression); mVideoLogContextWriteHeader(m_vl, m_threadContext.core); } -void CoreController::endVideoLog() { +void CoreController::endVideoLog(bool closeVf) { if (!m_vl) { return; } Interrupter interrupter(this); mVideoLogContextDestroy(m_threadContext.core, m_vl); - if (m_vlVf) { + if (m_vlVf && closeVf) { m_vlVf->close(m_vlVf); m_vlVf = nullptr; } diff --git a/src/platform/qt/CoreController.h b/src/platform/qt/CoreController.h index ac1e327ba..b6f9d7ecf 100644 --- a/src/platform/qt/CoreController.h +++ b/src/platform/qt/CoreController.h @@ -161,8 +161,9 @@ public slots: void clearOverride(); - void startVideoLog(const QString& path); - void endVideoLog(); + void startVideoLog(const QString& path, bool compression = true); + void startVideoLog(VFile* vf, bool compression = true); + void endVideoLog(bool closeVf = true); void setFramebufferHandle(int fb);