Core: Video log enhancements

This commit is contained in:
Vicki Pfau 2019-06-01 11:07:49 -07:00
parent b230b6e0f6
commit 3cce95b287
6 changed files with 62 additions and 28 deletions

View File

@ -104,6 +104,7 @@ void mVideoLoggerAttachChannel(struct mVideoLogger* logger, struct mVideoLogCont
struct mCore; struct mCore;
struct mVideoLogContext* mVideoLogContextCreate(struct mCore* core); struct mVideoLogContext* mVideoLogContextCreate(struct mCore* core);
void mVideoLogContextSetCompression(struct mVideoLogContext*, bool enable);
void mVideoLogContextSetOutput(struct mVideoLogContext*, struct VFile*); void mVideoLogContextSetOutput(struct mVideoLogContext*, struct VFile*);
void mVideoLogContextWriteHeader(struct mVideoLogContext*, struct mCore* core); void mVideoLogContextWriteHeader(struct mVideoLogContext*, struct mCore* core);

View File

@ -94,6 +94,7 @@ struct mVideoLogContext {
struct mVideoLogChannel channels[mVL_MAX_CHANNELS]; struct mVideoLogChannel channels[mVL_MAX_CHANNELS];
bool write; bool write;
bool compression;
uint32_t activeChannel; uint32_t activeChannel;
struct VFile* backing; struct VFile* backing;
}; };
@ -465,6 +466,12 @@ struct mVideoLogContext* mVideoLogContextCreate(struct mCore* core) {
context->initialStateSize = 0; context->initialStateSize = 0;
context->initialState = NULL; context->initialState = NULL;
#ifdef USE_ZLIB
context->compression = true;
#else
context->compression = false;
#endif
if (core) { if (core) {
context->initialStateSize = core->stateSize(core); context->initialStateSize = core->stateSize(core);
context->initialState = anonymousMemoryMap(context->initialStateSize); context->initialState = anonymousMemoryMap(context->initialStateSize);
@ -482,6 +489,10 @@ void mVideoLogContextSetOutput(struct mVideoLogContext* context, struct VFile* v
vf->seek(vf, 0, SEEK_SET); vf->seek(vf, 0, SEEK_SET);
} }
void mVideoLogContextSetCompression(struct mVideoLogContext* context, bool compression) {
context->compression = compression;
}
void mVideoLogContextWriteHeader(struct mVideoLogContext* context, struct mCore* core) { void mVideoLogContextWriteHeader(struct mVideoLogContext* context, struct mCore* core) {
struct mVideoLogHeader header = { { 0 } }; struct mVideoLogHeader header = { { 0 } };
memcpy(header.magic, mVL_MAGIC, sizeof(header.magic)); memcpy(header.magic, mVL_MAGIC, sizeof(header.magic));
@ -499,21 +510,24 @@ void mVideoLogContextWriteHeader(struct mVideoLogContext* context, struct mCore*
struct mVLBlockHeader chheader = { 0 }; struct mVLBlockHeader chheader = { 0 };
STORE_32LE(mVL_BLOCK_INITIAL_STATE, 0, &chheader.blockType); STORE_32LE(mVL_BLOCK_INITIAL_STATE, 0, &chheader.blockType);
#ifdef USE_ZLIB #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* vfm = VFileMemChunk(NULL, 0);
struct VFile* src = VFileFromConstMemory(context->initialState, context->initialStateSize); struct VFile* src = VFileFromConstMemory(context->initialState, context->initialStateSize);
_compress(vfm, src); _compress(vfm, src);
src->close(src); src->close(src);
STORE_32LE(vfm->size(vfm), 0, &chheader.length); STORE_32LE(vfm->size(vfm), 0, &chheader.length);
context->backing->write(context->backing, &chheader, sizeof(chheader)); context->backing->write(context->backing, &chheader, sizeof(chheader));
_copyVf(context->backing, vfm); _copyVf(context->backing, vfm);
vfm->close(vfm); vfm->close(vfm);
#else } 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);
#endif #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; size_t i;
@ -647,9 +661,10 @@ static void _flushBufferCompressed(struct mVideoLogContext* context) {
static void _flushBuffer(struct mVideoLogContext* context) { static void _flushBuffer(struct mVideoLogContext* context) {
#ifdef USE_ZLIB #ifdef USE_ZLIB
// TODO: Make optional if (context->compression) {
_flushBufferCompressed(context); _flushBufferCompressed(context);
return; return;
}
#endif #endif
struct CircleBuffer* buffer = &context->channels[context->activeChannel].buffer; struct CircleBuffer* buffer = &context->channels[context->activeChannel].buffer;

View File

@ -879,9 +879,11 @@ static void _GBCoreStartVideoLog(struct mCore* core, struct mVideoLogContext* co
static void _GBCoreEndVideoLog(struct mCore* core) { static void _GBCoreEndVideoLog(struct mCore* core) {
struct GBCore* gbcore = (struct GBCore*) core; struct GBCore* gbcore = (struct GBCore*) core;
struct GB* gb = core->board; struct GB* gb = core->board;
GBVideoProxyRendererUnshim(&gb->video, &gbcore->proxyRenderer); if (gbcore->proxyRenderer.logger) {
free(gbcore->proxyRenderer.logger); GBVideoProxyRendererUnshim(&gb->video, &gbcore->proxyRenderer);
gbcore->proxyRenderer.logger = NULL; free(gbcore->proxyRenderer.logger);
gbcore->proxyRenderer.logger = NULL;
}
} }
#endif #endif

View File

@ -990,9 +990,11 @@ static void _GBACoreStartVideoLog(struct mCore* core, struct mVideoLogContext* c
static void _GBACoreEndVideoLog(struct mCore* core) { static void _GBACoreEndVideoLog(struct mCore* core) {
struct GBACore* gbacore = (struct GBACore*) core; struct GBACore* gbacore = (struct GBACore*) core;
struct GBA* gba = core->board; struct GBA* gba = core->board;
GBAVideoProxyRendererUnshim(&gba->video, &gbacore->proxyRenderer); if (gbacore->proxyRenderer.logger) {
free(gbacore->proxyRenderer.logger); GBAVideoProxyRendererUnshim(&gba->video, &gbacore->proxyRenderer);
gbacore->proxyRenderer.logger = NULL; free(gbacore->proxyRenderer.logger);
gbacore->proxyRenderer.logger = NULL;
}
} }
#endif #endif

View File

@ -809,26 +809,39 @@ void CoreController::clearOverride() {
m_override.reset(); m_override.reset();
} }
void CoreController::startVideoLog(const QString& path) { void CoreController::startVideoLog(const QString& path, bool compression) {
if (m_vl) { if (m_vl) {
return; 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); Interrupter interrupter(this);
m_vl = mVideoLogContextCreate(m_threadContext.core); 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); mVideoLogContextSetOutput(m_vl, m_vlVf);
mVideoLogContextSetCompression(m_vl, compression);
mVideoLogContextWriteHeader(m_vl, m_threadContext.core); mVideoLogContextWriteHeader(m_vl, m_threadContext.core);
} }
void CoreController::endVideoLog() { void CoreController::endVideoLog(bool closeVf) {
if (!m_vl) { if (!m_vl) {
return; return;
} }
Interrupter interrupter(this); Interrupter interrupter(this);
mVideoLogContextDestroy(m_threadContext.core, m_vl); mVideoLogContextDestroy(m_threadContext.core, m_vl);
if (m_vlVf) { if (m_vlVf && closeVf) {
m_vlVf->close(m_vlVf); m_vlVf->close(m_vlVf);
m_vlVf = nullptr; m_vlVf = nullptr;
} }

View File

@ -161,8 +161,9 @@ public slots:
void clearOverride(); void clearOverride();
void startVideoLog(const QString& path); void startVideoLog(const QString& path, bool compression = true);
void endVideoLog(); void startVideoLog(VFile* vf, bool compression = true);
void endVideoLog(bool closeVf = true);
void setFramebufferHandle(int fb); void setFramebufferHandle(int fb);