Files
moonlight-common-c/src/RecorderCallbacks.c
2023-10-06 23:17:25 -05:00

103 lines
2.5 KiB
C

#ifdef _WIN32
// Don't warn for fopen() usage
#define _CRT_SECURE_NO_WARNINGS 1
#endif
#include "Limelight-internal.h"
static FILE* videoFile;
static FILE* audioFile;
static DECODER_RENDERER_CALLBACKS realDrCallbacks;
static AUDIO_RENDERER_CALLBACKS realArCallbacks;
static int recDrSetup(int videoFormat, int width, int height, int redrawRate, void* context, int drFlags)
{
const char* path = context;
if (path != NULL) {
videoFile = fopen(path, "wb");
if (videoFile == NULL) {
return -1;
}
}
else {
Limelog("Video recording will not be enabled - file path not specified in drContext!\n");
}
return realDrCallbacks.setup(videoFormat, width, height, redrawRate, NULL, drFlags);
}
static void recDrCleanup(void)
{
if (videoFile != NULL) {
fclose(videoFile);
videoFile = NULL;
}
realDrCallbacks.cleanup();
}
static int recDrSubmitDecodeUnit(PDECODE_UNIT decodeUnit)
{
if (videoFile != NULL) {
PLENTRY entry = decodeUnit->bufferList;
while (entry != NULL) {
fwrite(entry->data, 1, entry->length, videoFile);
entry = entry->next;
}
}
return realDrCallbacks.submitDecodeUnit(decodeUnit);
}
static int recArInit(int audioConfiguration, POPUS_MULTISTREAM_CONFIGURATION opusConfig, void* context, int arFlags)
{
const char* path = context;
if (path != NULL) {
audioFile = fopen(path, "wb");
if (audioFile == NULL) {
return -1;
}
}
else {
Limelog("Audio recording will not be enabled - file path not specified in arContext!\n");
}
return realArCallbacks.init(audioConfiguration, opusConfig, NULL, arFlags);
}
static void recArCleanup(void)
{
if (audioFile != NULL) {
fclose(audioFile);
audioFile = NULL;
}
realArCallbacks.cleanup();
}
static void recArDecodeAndPlaySample(char* sampleData, int sampleLength)
{
if (audioFile != NULL) {
fwrite(sampleData, 1, sampleLength, audioFile);
}
realArCallbacks.decodeAndPlaySample(sampleData, sampleLength);
}
void setRecorderCallbacks(PDECODER_RENDERER_CALLBACKS drCallbacks, PAUDIO_RENDERER_CALLBACKS arCallbacks)
{
realDrCallbacks = *drCallbacks;
realArCallbacks = *arCallbacks;
drCallbacks->setup = recDrSetup;
drCallbacks->cleanup = recDrCleanup;
drCallbacks->submitDecodeUnit = recDrSubmitDecodeUnit;
arCallbacks->init = recArInit;
arCallbacks->cleanup = recArCleanup;
arCallbacks->decodeAndPlaySample = recArDecodeAndPlaySample;
}