mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Add AVRecorder movie mode
This commit is contained in:
parent
79b1a8fd63
commit
c65f4ff893
7 changed files with 76 additions and 3 deletions
|
|
@ -62,6 +62,7 @@
|
||||||
#include "deh_tables.h"
|
#include "deh_tables.h"
|
||||||
#include "m_perfstats.h"
|
#include "m_perfstats.h"
|
||||||
#include "k_specialstage.h"
|
#include "k_specialstage.h"
|
||||||
|
#include "m_avrecorder.h"
|
||||||
|
|
||||||
#ifdef HAVE_DISCORDRPC
|
#ifdef HAVE_DISCORDRPC
|
||||||
#include "discord.h"
|
#include "discord.h"
|
||||||
|
|
@ -903,6 +904,7 @@ void D_RegisterClientCommands(void)
|
||||||
CV_RegisterVar(&cv_moviemode);
|
CV_RegisterVar(&cv_moviemode);
|
||||||
CV_RegisterVar(&cv_movie_option);
|
CV_RegisterVar(&cv_movie_option);
|
||||||
CV_RegisterVar(&cv_movie_folder);
|
CV_RegisterVar(&cv_movie_folder);
|
||||||
|
M_AVRecorder_AddCommands();
|
||||||
// PNG variables
|
// PNG variables
|
||||||
CV_RegisterVar(&cv_zlib_level);
|
CV_RegisterVar(&cv_zlib_level);
|
||||||
CV_RegisterVar(&cv_zlib_memory);
|
CV_RegisterVar(&cv_zlib_memory);
|
||||||
|
|
|
||||||
|
|
@ -185,6 +185,18 @@ void M_AVRecorder_Close(void)
|
||||||
g_av_recorder.reset();
|
g_av_recorder.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* M_AVRecorder_GetFileExtension(void)
|
||||||
|
{
|
||||||
|
return AVRecorder::file_extension();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* M_AVRecorder_GetCurrentFormat(void)
|
||||||
|
{
|
||||||
|
SRB2_ASSERT(g_av_recorder != nullptr);
|
||||||
|
|
||||||
|
return g_av_recorder->format_name();
|
||||||
|
}
|
||||||
|
|
||||||
boolean M_AVRecorder_IsExpired(void)
|
boolean M_AVRecorder_IsExpired(void)
|
||||||
{
|
{
|
||||||
SRB2_ASSERT(g_av_recorder != nullptr);
|
SRB2_ASSERT(g_av_recorder != nullptr);
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ extern "C" {
|
||||||
|
|
||||||
void M_AVRecorder_AddCommands(void);
|
void M_AVRecorder_AddCommands(void);
|
||||||
|
|
||||||
|
const char *M_AVRecorder_GetFileExtension(void);
|
||||||
|
|
||||||
// True if successully opened.
|
// True if successully opened.
|
||||||
boolean M_AVRecorder_Open(const char *filename);
|
boolean M_AVRecorder_Open(const char *filename);
|
||||||
|
|
||||||
|
|
@ -26,6 +28,8 @@ void M_AVRecorder_Close(void);
|
||||||
// Check whether AVRecorder is still valid. Call M_AVRecorder_Close if expired.
|
// Check whether AVRecorder is still valid. Call M_AVRecorder_Close if expired.
|
||||||
boolean M_AVRecorder_IsExpired(void);
|
boolean M_AVRecorder_IsExpired(void);
|
||||||
|
|
||||||
|
const char *M_AVRecorder_GetCurrentFormat(void);
|
||||||
|
|
||||||
extern consvar_t
|
extern consvar_t
|
||||||
cv_movie_custom_resolution,
|
cv_movie_custom_resolution,
|
||||||
cv_movie_duration,
|
cv_movie_duration,
|
||||||
|
|
|
||||||
41
src/m_misc.c
41
src/m_misc.c
|
|
@ -44,6 +44,7 @@
|
||||||
#include "command.h" // cv_execversion
|
#include "command.h" // cv_execversion
|
||||||
|
|
||||||
#include "m_anigif.h"
|
#include "m_anigif.h"
|
||||||
|
#include "m_avrecorder.h"
|
||||||
|
|
||||||
// So that the screenshot menu auto-updates...
|
// So that the screenshot menu auto-updates...
|
||||||
#include "k_menu.h"
|
#include "k_menu.h"
|
||||||
|
|
@ -113,8 +114,8 @@ consvar_t cv_screenshot_folder = CVAR_INIT ("screenshot_folder", "", CV_SAVE, NU
|
||||||
|
|
||||||
consvar_t cv_screenshot_colorprofile = CVAR_INIT ("screenshot_colorprofile", "Yes", CV_SAVE, CV_YesNo, NULL);
|
consvar_t cv_screenshot_colorprofile = CVAR_INIT ("screenshot_colorprofile", "Yes", CV_SAVE, CV_YesNo, NULL);
|
||||||
|
|
||||||
static CV_PossibleValue_t moviemode_cons_t[] = {{MM_GIF, "GIF"}, {MM_APNG, "aPNG"}, {MM_SCREENSHOT, "Screenshots"}, {0, NULL}};
|
static CV_PossibleValue_t moviemode_cons_t[] = {{MM_GIF, "GIF"}, {MM_APNG, "aPNG"}, {MM_SCREENSHOT, "Screenshots"}, {MM_AVRECORDER, "WebM"}, {0, NULL}};
|
||||||
consvar_t cv_moviemode = CVAR_INIT ("moviemode_mode", "GIF", CV_SAVE|CV_CALL, moviemode_cons_t, Moviemode_mode_Onchange);
|
consvar_t cv_moviemode = CVAR_INIT ("moviemode_mode", "WebM", CV_SAVE|CV_CALL, moviemode_cons_t, Moviemode_mode_Onchange);
|
||||||
|
|
||||||
consvar_t cv_movie_option = CVAR_INIT ("movie_option", "Default", CV_SAVE|CV_CALL, screenshot_cons_t, Moviemode_option_Onchange);
|
consvar_t cv_movie_option = CVAR_INIT ("movie_option", "Default", CV_SAVE|CV_CALL, screenshot_cons_t, Moviemode_option_Onchange);
|
||||||
consvar_t cv_movie_folder = CVAR_INIT ("movie_folder", "", CV_SAVE, NULL, NULL);
|
consvar_t cv_movie_folder = CVAR_INIT ("movie_folder", "", CV_SAVE, NULL, NULL);
|
||||||
|
|
@ -1295,6 +1296,25 @@ static inline moviemode_t M_StartMovieGIF(const char *pathname)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static inline moviemode_t M_StartMovieAVRecorder(const char *pathname)
|
||||||
|
{
|
||||||
|
const char *ext = M_AVRecorder_GetFileExtension();
|
||||||
|
const char *freename;
|
||||||
|
|
||||||
|
if (!(freename = Newsnapshotfile(pathname, ext)))
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_ERROR, "Couldn't create %s file: no slots open in %s\n", ext, pathname);
|
||||||
|
return MM_OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!M_AVRecorder_Open(va(pandf,pathname,freename)))
|
||||||
|
{
|
||||||
|
return MM_OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MM_AVRECORDER;
|
||||||
|
}
|
||||||
|
|
||||||
void M_StartMovie(void)
|
void M_StartMovie(void)
|
||||||
{
|
{
|
||||||
#if NUMSCREENS > 2
|
#if NUMSCREENS > 2
|
||||||
|
|
@ -1332,6 +1352,9 @@ void M_StartMovie(void)
|
||||||
case MM_SCREENSHOT:
|
case MM_SCREENSHOT:
|
||||||
moviemode = MM_SCREENSHOT;
|
moviemode = MM_SCREENSHOT;
|
||||||
break;
|
break;
|
||||||
|
case MM_AVRECORDER:
|
||||||
|
moviemode = M_StartMovieAVRecorder(pathname);
|
||||||
|
break;
|
||||||
default: //???
|
default: //???
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1342,6 +1365,8 @@ void M_StartMovie(void)
|
||||||
CONS_Printf(M_GetText("Movie mode enabled (%s).\n"), "GIF");
|
CONS_Printf(M_GetText("Movie mode enabled (%s).\n"), "GIF");
|
||||||
else if (moviemode == MM_SCREENSHOT)
|
else if (moviemode == MM_SCREENSHOT)
|
||||||
CONS_Printf(M_GetText("Movie mode enabled (%s).\n"), "screenshots");
|
CONS_Printf(M_GetText("Movie mode enabled (%s).\n"), "screenshots");
|
||||||
|
else if (moviemode == MM_AVRECORDER)
|
||||||
|
CONS_Printf(M_GetText("Movie mode enabled (%s).\n"), M_AVRecorder_GetCurrentFormat());
|
||||||
|
|
||||||
//singletics = (moviemode != MM_OFF);
|
//singletics = (moviemode != MM_OFF);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1353,6 +1378,15 @@ void M_SaveFrame(void)
|
||||||
// paranoia: should be unnecessary without singletics
|
// paranoia: should be unnecessary without singletics
|
||||||
static tic_t oldtic = 0;
|
static tic_t oldtic = 0;
|
||||||
|
|
||||||
|
if (moviemode == MM_AVRECORDER)
|
||||||
|
{
|
||||||
|
if (M_AVRecorder_IsExpired())
|
||||||
|
{
|
||||||
|
M_StopMovie();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (oldtic == I_GetTime())
|
if (oldtic == I_GetTime())
|
||||||
return;
|
return;
|
||||||
else
|
else
|
||||||
|
|
@ -1440,6 +1474,9 @@ void M_StopMovie(void)
|
||||||
#endif
|
#endif
|
||||||
case MM_SCREENSHOT:
|
case MM_SCREENSHOT:
|
||||||
break;
|
break;
|
||||||
|
case MM_AVRECORDER:
|
||||||
|
M_AVRecorder_Close();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,8 @@ typedef enum {
|
||||||
MM_OFF = 0,
|
MM_OFF = 0,
|
||||||
MM_APNG,
|
MM_APNG,
|
||||||
MM_GIF,
|
MM_GIF,
|
||||||
MM_SCREENSHOT
|
MM_SCREENSHOT,
|
||||||
|
MM_AVRECORDER,
|
||||||
} moviemode_t;
|
} moviemode_t;
|
||||||
extern moviemode_t moviemode;
|
extern moviemode_t moviemode;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -170,6 +170,11 @@ void Impl::worker()
|
||||||
valid_ = false;
|
valid_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* AVRecorder::file_extension()
|
||||||
|
{
|
||||||
|
return "webm";
|
||||||
|
}
|
||||||
|
|
||||||
AVRecorder::AVRecorder(const Config config) : impl_(std::make_unique<Impl>(config))
|
AVRecorder::AVRecorder(const Config config) : impl_(std::make_unique<Impl>(config))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -186,6 +191,11 @@ AVRecorder::~AVRecorder()
|
||||||
std::thread([_ = std::move(impl_)] {}).detach();
|
std::thread([_ = std::move(impl_)] {}).detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* AVRecorder::format_name() const
|
||||||
|
{
|
||||||
|
return impl_->container_->name();
|
||||||
|
}
|
||||||
|
|
||||||
void AVRecorder::push_audio_samples(audio_buffer_t buffer)
|
void AVRecorder::push_audio_samples(audio_buffer_t buffer)
|
||||||
{
|
{
|
||||||
const auto _ = impl_->queue_guard();
|
const auto _ = impl_->queue_guard();
|
||||||
|
|
|
||||||
|
|
@ -57,11 +57,18 @@ public:
|
||||||
std::optional<Video> video;
|
std::optional<Video> video;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Returns the canonical file extension minus the dot.
|
||||||
|
// E.g. "webm" (not ".webm").
|
||||||
|
static const char* file_extension();
|
||||||
|
|
||||||
AVRecorder(Config config);
|
AVRecorder(Config config);
|
||||||
~AVRecorder();
|
~AVRecorder();
|
||||||
|
|
||||||
void push_audio_samples(audio_buffer_t buffer);
|
void push_audio_samples(audio_buffer_t buffer);
|
||||||
|
|
||||||
|
// Proper name of the container format.
|
||||||
|
const char* format_name() const;
|
||||||
|
|
||||||
// True if this instance has terminated. Continuing to use
|
// True if this instance has terminated. Continuing to use
|
||||||
// this interface is useless and the object should be
|
// this interface is useless and the object should be
|
||||||
// destructed immediately.
|
// destructed immediately.
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue