1. Add IFDEFs for video recording
2. Options for video recording were hardcoded in engine,
now they are hardcoded in frontend and passed to engine thru command line
(later it will be possible to change them in frontend)
--- a/QTfrontend/game.cpp Fri Jun 08 02:41:14 2012 +0400
+++ b/QTfrontend/game.cpp Fri Jun 08 02:52:35 2012 +0400
@@ -333,6 +333,8 @@
arguments << QString::number(config->translateQuality());
arguments << QString::number(config->stereoMode());
arguments << tr("en.txt");
+ arguments << "30"; // framerate num
+ arguments << "1"; // framerate den
return arguments;
}
--- a/QTfrontend/net/recorder.cpp Fri Jun 08 02:41:14 2012 +0400
+++ b/QTfrontend/net/recorder.cpp Fri Jun 08 02:52:35 2012 +0400
@@ -87,7 +87,15 @@
arguments << QString::number(config->translateQuality());
arguments << QString::number(config->stereoMode());
arguments << HWGame::tr("en.txt");
+ arguments << "30"; // framerate num
+ arguments << "1"; // framerate den
arguments << prefix;
+ arguments << "mp4";
+ arguments << "mpeg4"; // arguments << "libx264";
+ arguments << "5"; // video quality
+ arguments << "medium";
+ arguments << "libmp3lame";
+ arguments << "5"; // audio quality
return arguments;
}
--- a/hedgewars/ArgParsers.inc Fri Jun 08 02:41:14 2012 +0400
+++ b/hedgewars/ArgParsers.inc Fri Jun 08 02:52:35 2012 +0400
@@ -61,13 +61,28 @@
else
cStereoMode:= TStereoMode(max(0, min(ord(high(TStereoMode)), tmp-6)));
cLocaleFName:= ParamStr(17);
- if ParamCount > 17 then
- begin
- cRecPrefix:= ParamStr(18);
- GameType:= gmtRecord;
- end;
+{$IFDEF USE_VIDEO_RECORDING}
+ cVideoFramerateNum:= StrToInt(ParamStr(18));
+ cVideoFramerateDen:= StrToInt(ParamStr(19));
+{$ENDIF}
end;
+{$IFDEF USE_VIDEO_RECORDING}
+procedure internalStartVideoRecordingWithParameters();
+begin
+ internalStartGameWithParameters();
+ GameType:= gmtRecord;
+ cRecPrefix:= ParamStr(20);
+ cAVFormat:= ParamStr(21);
+ cVideoCodec:= ParamStr(22);
+ cVideoQuality:= StrToInt(ParamStr(23));
+ cVideoPreset:= ParamStr(24);
+ cAudioCodec:= ParamStr(25);
+ // cRecordAudio:= cAudioCodec <> 'no';
+ cAudioQuality:= StrToInt(ParamStr(26));
+end;
+{$ENDIF}
+
procedure setVideo(screenWidth: LongInt; screenHeight: LongInt; bitsStr: LongInt);
begin
cScreenWidth:= screenWidth;
--- a/hedgewars/avwrapper.c Fri Jun 08 02:41:14 2012 +0400
+++ b/hedgewars/avwrapper.c Fri Jun 08 02:52:35 2012 +0400
@@ -16,8 +16,11 @@
static AVCodecContext* g_pAudio;
static AVCodecContext* g_pVideo;
-static int g_Width, g_Height, g_Framerate;
+static int g_Width, g_Height;
static int g_Frequency, g_Channels;
+static int g_VQuality, g_AQuality;
+static AVRational g_Framerate;
+static const char* g_pPreset;
static FILE* g_pSoundFile;
static int16_t* g_pSamples;
@@ -77,7 +80,7 @@
AddFileLogRaw(Buffer);
}
-static void AddAudioStream(enum CodecID codec_id)
+static void AddAudioStream()
{
#if LIBAVCODEC_VERSION_MAJOR >= 54
g_pAStream = avformat_new_stream(g_pContainer, g_pACodec);
@@ -89,15 +92,24 @@
g_pAStream->id = 1;
g_pAudio = g_pAStream->codec;
+
avcodec_get_context_defaults3(g_pAudio, g_pACodec);
- g_pAudio->codec_id = codec_id;
+ g_pAudio->codec_id = g_pACodec->id;
// put parameters
g_pAudio->sample_fmt = AV_SAMPLE_FMT_S16;
- // pContext->bit_rate = 128000;
g_pAudio->sample_rate = g_Frequency;
g_pAudio->channels = g_Channels;
+ // set quality
+ if (g_AQuality > 100)
+ g_pAudio->bit_rate = g_AQuality;
+ else
+ {
+ g_pAudio->flags |= CODEC_FLAG_QSCALE;
+ g_pAudio->global_quality = g_AQuality*FF_QP2LAMBDA;
+ }
+
// some formats want stream headers to be separate
if (g_pFormat->flags & AVFMT_GLOBALHEADER)
g_pAudio->flags |= CODEC_FLAG_GLOBAL_HEADER;
@@ -123,6 +135,9 @@
// returns non-zero if there is more sound
static int WriteAudioFrame()
{
+ if (!g_pAStream)
+ return 0;
+
AVPacket Packet = { 0 };
av_init_packet(&Packet);
@@ -166,7 +181,7 @@
}
// add a video output stream
-static void AddVideoStream(enum CodecID codec_id)
+static void AddVideoStream()
{
#if LIBAVCODEC_VERSION_MAJOR >= 54
g_pVStream = avformat_new_stream(g_pContainer, g_pVCodec);
@@ -177,8 +192,9 @@
FatalError("Could not allocate video stream");
g_pVideo = g_pVStream->codec;
- avcodec_get_context_defaults3( g_pVideo, g_pVCodec );
- g_pVideo->codec_id = codec_id;
+
+ avcodec_get_context_defaults3(g_pVideo, g_pVCodec);
+ g_pVideo->codec_id = g_pVCodec->id;
// put parameters
// resolution must be a multiple of two
@@ -188,29 +204,28 @@
of which frame timestamps are represented. for fixed-fps content,
timebase should be 1/framerate and timestamp increments should be
identically 1. */
- g_pVideo->time_base.den = g_Framerate;
- g_pVideo->time_base.num = 1;
+ g_pVideo->time_base.den = g_Framerate.num;
+ g_pVideo->time_base.num = g_Framerate.den;
//g_pVideo->gop_size = 12; /* emit one intra frame every twelve frames at most */
g_pVideo->pix_fmt = PIX_FMT_YUV420P;
+ // set quality
+ if (g_VQuality > 100)
+ g_pVideo->bit_rate = g_VQuality;
+ else
+ {
+ g_pVideo->flags |= CODEC_FLAG_QSCALE;
+ g_pVideo->global_quality = g_VQuality*FF_QP2LAMBDA;
+ }
+
+ AVDictionary* pDict = NULL;
+ if (strcmp(g_pVCodec->name, "libx264") == 0)
+ av_dict_set(&pDict, "preset", g_pPreset, 0);
+
// some formats want stream headers to be separate
if (g_pFormat->flags & AVFMT_GLOBALHEADER)
g_pVideo->flags |= CODEC_FLAG_GLOBAL_HEADER;
- AVDictionary* pDict = NULL;
- if (codec_id == CODEC_ID_H264)
- {
- // av_dict_set(&pDict, "tune", "animation", 0);
- // av_dict_set(&pDict, "preset", "veryslow", 0);
- av_dict_set(&pDict, "crf", "20", 0);
- }
- else
- {
- g_pVideo->flags |= CODEC_FLAG_QSCALE;
- // g_pVideo->bit_rate = g_Width*g_Height*g_Framerate/4;
- g_pVideo->global_quality = 15*FF_QP2LAMBDA;
- }
-
// open the codec
if (avcodec_open2(g_pVideo, g_pVCodec, &pDict) < 0)
FatalError("Could not open video codec %s", g_pVCodec->long_name);
@@ -237,6 +252,9 @@
AudioTime = (double)g_pAStream->pts.val*g_pAStream->time_base.num/g_pAStream->time_base.den;
while (AudioTime < VideoTime && WriteAudioFrame());
}
+
+ if (!g_pVStream)
+ return 0;
AVPacket Packet;
av_init_packet(&Packet);
@@ -300,111 +318,73 @@
WriteFrame(g_pVFrame);
}
-void AVWrapper_GetList()
-{
- // initialize libav and register all codecs and formats
- av_register_all();
-
-#if 0
- AVOutputFormat* pFormat = NULL;
- while (pFormat = av_oformat_next(pFormat))
- {
- Log("%s; %s; %s;\n", pFormat->name, pFormat->long_name, pFormat->mime_type);
-
- AVCodec* pCodec = NULL;
- while (pCodec = av_codec_next(pCodec))
- {
- if (!av_codec_is_encoder(pCodec))
- continue;
- if (avformat_query_codec(pFormat, pCodec->id, FF_COMPLIANCE_NORMAL) != 1)
- continue;
- if (pCodec->type = AVMEDIA_TYPE_VIDEO)
- {
- if (pCodec->supported_framerate != NULL)
- continue;
- Log(" Video: %s; %s;\n", pCodec->name, pCodec->long_name);
- }
- if (pCodec->type = AVMEDIA_TYPE_AUDIO)
- {
- /* if (pCodec->supported_samplerates == NULL)
- continue;
- int i;
- for(i = 0; i <)
- supported_samplerates*/
- Log(" Audio: %s; %s;\n", pCodec->name, pCodec->long_name);
- }
- }
- /* struct AVCodecTag** pTags = pCur->codec_tag;
- int i;
- for (i = 0; ; i++)
- {
- enum CodecID id = av_codec_get_id(pTags, i);
- if (id == CODEC_ID_NONE)
- break;
- AVCodec* pCodec = avcodec_find_encoder(id);
- Log(" %i: %s; %s;\n", id, pCodec->name, pCodec->long_name);
- }*/
- }
-#endif
-}
-
-void AVWrapper_Init(void (*pAddFileLogRaw)(const char*), const char* pFilename, const char* pSoundFile, int Width, int Height, int Framerate, int Frequency, int Channels)
+void AVWrapper_Init(
+ void (*pAddFileLogRaw)(const char*),
+ const char* pFilename,
+ const char* pSoundFile,
+ const char* pFormatName,
+ const char* pVCodecName,
+ const char* pACodecName,
+ const char* pVPreset,
+ int Width, int Height,
+ int FramerateNum, int FramerateDen,
+ int Frequency, int Channels,
+ int VQuality, int AQuality)
{
AddFileLogRaw = pAddFileLogRaw;
av_log_set_callback( &LogCallback );
g_Width = Width;
g_Height = Height;
- g_Framerate = Framerate;
+ g_Framerate.num = FramerateNum;
+ g_Framerate.den = FramerateDen;
g_Frequency = Frequency;
g_Channels = Channels;
+ g_VQuality = VQuality;
+ g_AQuality = AQuality;
+ g_pPreset = pVPreset;
// initialize libav and register all codecs and formats
av_register_all();
-
- AVWrapper_GetList();
- // allocate the output media context
-#if LIBAVCODEC_VERSION_MAJOR >= 54
- avformat_alloc_output_context2(&g_pContainer, NULL, "mp4", pFilename);
-#else
- g_pFormat = av_guess_format(NULL, pFilename, NULL);
+ // find format
+ g_pFormat = av_guess_format(pFormatName, NULL, NULL);
if (!g_pFormat)
- FatalError("guess_format");
+ FatalError("Format \"%s\" was not found", pFormatName);
// allocate the output media context
g_pContainer = avformat_alloc_context();
- if (g_pContainer)
- {
- g_pContainer->oformat = g_pFormat;
- snprintf(g_pContainer->filename, sizeof(g_pContainer->filename), "%s", pFilename);
- }
-#endif
if (!g_pContainer)
FatalError("Could not allocate output context");
- g_pFormat = g_pContainer->oformat;
+ g_pContainer->oformat = g_pFormat;
- enum CodecID VideoCodecID = g_pFormat->video_codec;//CODEC_ID_H264;
- enum CodecID AudioCodecID = g_pFormat->audio_codec;
+ // append extesnion to filename
+ snprintf(g_pContainer->filename, sizeof(g_pContainer->filename),
+ "%s.%*s",
+ pFilename,
+ strcspn(g_pFormat->extensions, ","), g_pFormat->extensions);
+ // find codecs
+ g_pVCodec = avcodec_find_encoder_by_name(pVCodecName);
+ g_pACodec = avcodec_find_encoder_by_name(pACodecName);
+
+ // add audio and video stream to container
g_pVStream = NULL;
g_pAStream = NULL;
- if (VideoCodecID != CODEC_ID_NONE)
- {
- g_pVCodec = avcodec_find_encoder(VideoCodecID);
- if (!g_pVCodec)
- FatalError("Video codec not found");
- AddVideoStream(VideoCodecID);
- }
+
+ if (g_pVCodec)
+ AddVideoStream();
+ else
+ Log("Video codec \"%s\" was not found; video will be ignored.\n", pVCodecName);
- if (AudioCodecID != CODEC_ID_NONE)
- {
- g_pACodec = avcodec_find_encoder(AudioCodecID);
- if (!g_pACodec)
- FatalError("Audio codec not found");
- AddAudioStream(AudioCodecID);
- }
+ if (g_pACodec)
+ AddAudioStream();
+ else
+ Log("Audio codec \"%s\" was not found; audio will be ignored.\n", pACodecName);
+
+ if (!g_pAStream && !g_pVStream)
+ FatalError("No video, no audio, aborting...");
if (g_pAStream)
{
@@ -414,17 +394,18 @@
}
// write format info to log
- av_dump_format(g_pContainer, 0, pFilename, 1);
+ av_dump_format(g_pContainer, 0, g_pContainer->filename, 1);
// open the output file, if needed
if (!(g_pFormat->flags & AVFMT_NOFILE))
{
- if (avio_open(&g_pContainer->pb, pFilename, AVIO_FLAG_WRITE) < 0)
+ if (avio_open(&g_pContainer->pb, g_pContainer->filename, AVIO_FLAG_WRITE) < 0)
FatalError("Could not open output file (%s)", pFilename);
}
// write the stream header, if any
avformat_write_header(g_pContainer, NULL);
+
g_pVFrame->pts = -1;
}
@@ -439,32 +420,27 @@
// write the trailer, if any.
av_write_trailer(g_pContainer);
- // close each codec
- if( g_pVStream )
+ // close the output file
+ if (!(g_pFormat->flags & AVFMT_NOFILE))
+ avio_close(g_pContainer->pb);
+
+ // free everything
+ if (g_pVStream)
{
- avcodec_close(g_pVStream->codec);
+ avcodec_close(g_pVideo);
+ av_free(g_pVideo);
+ av_free(g_pVStream);
av_free(g_pVFrame);
}
- if( g_pAStream )
+ if (g_pAStream)
{
- avcodec_close(g_pAStream->codec);
+ avcodec_close(g_pAudio);
+ av_free(g_pAudio);
+ av_free(g_pAStream);
av_free(g_pAFrame);
av_free(g_pSamples);
fclose(g_pSoundFile);
}
- // free the streams
- int i;
- for (i = 0; i < g_pContainer->nb_streams; i++)
- {
- av_freep(&g_pContainer->streams[i]->codec);
- av_freep(&g_pContainer->streams[i]);
- }
-
- // close the output file
- if (!(g_pFormat->flags & AVFMT_NOFILE))
- avio_close(g_pContainer->pb);
-
- // free the stream
av_free(g_pContainer);
}
--- a/hedgewars/hwengine.pas Fri Jun 08 02:41:14 2012 +0400
+++ b/hedgewars/hwengine.pas Fri Jun 08 02:52:35 2012 +0400
@@ -31,7 +31,8 @@
uses SDLh, uMisc, uConsole, uGame, uConsts, uLand, uAmmos, uVisualGears, uGears, uStore, uWorld, uInputHandler, uSound,
uScript, uTeams, uStats, uIO, uLocale, uChat, uAI, uAIMisc, uRandom, uLandTexture, uCollisions,
- SysUtils, uTypes, uVariables, uCommands, uUtils, uCaptions, uDebug, uCommandHandlers, uLandPainted, uVideoRec
+ SysUtils, uTypes, uVariables, uCommands, uUtils, uCaptions, uDebug, uCommandHandlers, uLandPainted
+ {$IFDEF USE_VIDEO_RECORDING}, uVideoRec {$ENDIF}
{$IFDEF SDL13}, uTouch{$ENDIF}{$IFDEF ANDROID}, GLUnit{$ENDIF};
{$IFDEF HWLIBRARY}
@@ -101,8 +102,10 @@
SwapBuffers;
+{$IFDEF USE_VIDEO_RECORDING}
if flagPrerecording then
SaveCameraPosition;
+{$ENDIF}
if flagMakeCapture then
begin
@@ -264,7 +267,7 @@
end;
end;
-////////////////
+{$IFDEF USE_VIDEO_RECORDING}
procedure RecorderMainLoop;
var CurrTime, PrevTime: LongInt;
begin
@@ -289,6 +292,7 @@
end;
StopVideoRecording();
end;
+{$ENDIF}
///////////////
procedure Game{$IFDEF HWLIBRARY}(gameArgs: PPChar); cdecl; export{$ENDIF};
@@ -572,11 +576,14 @@
else
if (ParamCount = 3) and ((ParamStr(3) = '--stats-only') or (ParamStr(3) = 'landpreview')) then
internalSetGameTypeLandPreviewFromParameters()
+ else if ParamCount = cDefaultParamNum then
+ internalStartGameWithParameters()
+{$IFDEF USE_VIDEO_RECORDING}
+ else if ParamCount = cVideorecParamNum then
+ internalStartVideoRecordingWithParameters()
+{$ENDIF}
else
- if (ParamCount = cDefaultParamNum) or (ParamCount = cDefaultParamNum+1) then
- internalStartGameWithParameters()
- else
- playReplayFileWithParameters();
+ playReplayFileWithParameters();
end;
////////////////////////////////////////////////////////////////////////////////
--- a/hedgewars/options.inc Fri Jun 08 02:41:14 2012 +0400
+++ b/hedgewars/options.inc Fri Jun 08 02:52:35 2012 +0400
@@ -67,6 +67,7 @@
{$IFNDEF MOBILE}
{$DEFINE USE_AM_NUMCOLUMN}
+ {$DEFINE USE_VIDEO_RECORDING}
{$ENDIF}
{$DEFINE USE_LUA_SCRIPT}
--- a/hedgewars/uCommandHandlers.pas Fri Jun 08 02:41:14 2012 +0400
+++ b/hedgewars/uCommandHandlers.pas Fri Jun 08 02:52:35 2012 +0400
@@ -26,7 +26,8 @@
procedure freeModule;
implementation
-uses SysUtils, uCommands, uTypes, uVariables, uIO, uDebug, uConsts, uScript, uUtils, SDLh, uRandom, uCaptions, uVideoRec;
+uses uCommands, uTypes, uVariables, uIO, uDebug, uConsts, uScript, uUtils, SDLh, uRandom, uCaptions
+ {$IFDEF USE_VIDEO_RECORDING}, uVideoRec {$ENDIF};
var prevGState: TGameState = gsConfirm;
@@ -532,10 +533,12 @@
procedure chRecord(var s: shortstring);
begin
s:= s; // avoid compiler hint
+{$IFDEF USE_VIDEO_RECORDING}
if flagPrerecording then
- StopPreRecording
+ StopPreRecording()
else
- BeginPreRecording(FormatDateTime('YYYY-MM-DD_HH-mm-ss', Now()));
+ BeginPreRecording();
+{$ENDIF}
end;
procedure chSetMap(var s: shortstring);
--- a/hedgewars/uConsts.pas Fri Jun 08 02:41:14 2012 +0400
+++ b/hedgewars/uConsts.pas Fri Jun 08 02:52:35 2012 +0400
@@ -27,7 +27,12 @@
const
sfMax = 1000;
+{$IFNDEF USE_VIDEO_RECORDING}
cDefaultParamNum = 17;
+{$ELSE}
+ cDefaultParamNum = 19;
+ cVideorecParamNum = cDefaultParamNum + 7;
+{$ENDIF}
// message constants
errmsgCreateSurface = 'Error creating SDL surface';
--- a/hedgewars/uStore.pas Fri Jun 08 02:41:14 2012 +0400
+++ b/hedgewars/uStore.pas Fri Jun 08 02:52:35 2012 +0400
@@ -47,7 +47,7 @@
implementation
uses uMisc, uConsole, uMobile, uVariables, uUtils, uTextures, uRender, uRenderUtils, uCommands,
- uDebug{$IFDEF USE_CONTEXT_RESTORE}, uWorld{$ENDIF}, glut;
+ uDebug{$IFDEF USE_CONTEXT_RESTORE}, uWorld{$ENDIF} {$IFDEF USE_VIDEO_RECORDING}, glut {$ENDIF};
//type TGPUVendor = (gvUnknown, gvNVIDIA, gvATI, gvIntel, gvApple);
@@ -439,6 +439,7 @@
IMG_Quit();
end;
+{$IF NOT DEFINED(S3D_DISABLED) OR DEFINED(USE_VIDEO_RECORDING)}
procedure CreateFramebuffer(var frame, depth, tex: GLuint);
begin
glGenFramebuffersEXT(1, @frame);
@@ -461,6 +462,7 @@
glDeleteRenderbuffersEXT(1, @depth);
glDeleteFramebuffersEXT(1, @frame);
end;
+{$ENDIF}
procedure StoreRelease(reload: boolean);
var ii: TSprite;
@@ -535,8 +537,10 @@
end;
end;
end;
+{$IFDEF USE_VIDEO_RECORDING}
if defaultFrame <> 0 then
DeleteFramebuffer(defaultFrame, depthv, texv);
+{$ENDIF}
{$IFNDEF S3D_DISABLED}
if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) or (cStereoMode = smAFR) then
begin
@@ -707,9 +711,10 @@
AddFileLog(' \----- Extensions: ');
AddFileLogRaw(glGetString(GL_EXTENSIONS));
AddFileLog('');
- //TODO: don't have the Extensions line trimmed but slipt it into multiple lines
+ //TODO: slipt Extensions line into multiple lines
defaultFrame:= 0;
+{$IFDEF USE_VIDEO_RECORDING}
if GameType = gmtRecord then
begin
if AuxBufNum > 0 then
@@ -731,6 +736,7 @@
AddFileLog('Warning: off-screen rendering is not supported; using back buffer but it may not work.');
end;
end;
+{$ENDIF}
{$IFNDEF S3D_DISABLED}
if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) or (cStereoMode = smAFR) then
--- a/hedgewars/uUtils.pas Fri Jun 08 02:41:14 2012 +0400
+++ b/hedgewars/uUtils.pas Fri Jun 08 02:52:35 2012 +0400
@@ -82,8 +82,10 @@
{$IFDEF DEBUGFILE}
var f: textfile;
+{$IFDEF USE_VIDEO_RECORDING}
logMutex: TRTLCriticalSection; // mutex for debug file
{$ENDIF}
+{$ENDIF}
var CharArray: array[byte] of Char;
procedure SplitBySpace(var a,b: shortstring);
@@ -305,22 +307,30 @@
begin
s:= s;
{$IFDEF DEBUGFILE}
+{$IFDEF USE_VIDEO_RECORDING}
EnterCriticalSection(logMutex);
+{$ENDIF}
writeln(f, inttostr(GameTicks) + ': ' + s);
flush(f);
+{$IFDEF USE_VIDEO_RECORDING}
LeaveCriticalSection(logMutex);
{$ENDIF}
+{$ENDIF}
end;
procedure AddFileLogRaw(s: pchar); cdecl;
begin
s:= s;
{$IFDEF DEBUGFILE}
+{$IFDEF USE_VIDEO_RECORDING}
EnterCriticalSection(logMutex);
+{$ENDIF}
write(f, s);
flush(f);
+{$IFDEF USE_VIDEO_RECORDING}
LeaveCriticalSection(logMutex);
{$ENDIF}
+{$ENDIF}
end;
function CheckCJKFont(s: ansistring; font: THWFont): THWFont;
@@ -414,7 +424,9 @@
logfileBase:= 'game'
else
logfileBase:= 'preview';
+{$IFDEF USE_VIDEO_RECORDING}
InitCriticalSection(logMutex);
+{$ENDIF}
{$I-}
{$IFDEF MOBILE}
{$IFDEF IPHONEOS} Assign(f,'../Documents/hw-' + logfileBase + '.log'); {$ENDIF}
@@ -451,8 +463,10 @@
writeln(f, 'halt at ' + inttostr(GameTicks) + ' ticks. TurnTimeLeft = ' + inttostr(TurnTimeLeft));
flush(f);
close(f);
+{$IFDEF USE_VIDEO_RECORDING}
DoneCriticalSection(logMutex);
{$ENDIF}
+{$ENDIF}
end;
end.
--- a/hedgewars/uVariables.pas Fri Jun 08 02:41:14 2012 +0400
+++ b/hedgewars/uVariables.pas Fri Jun 08 02:52:35 2012 +0400
@@ -52,7 +52,17 @@
cReadyDelay : Longword = 5000;
cStereoMode : TStereoMode = smNone;
cOnlyStats : boolean = False;
- cRecPrefix : shortstring = '';
+{$IFDEF USE_VIDEO_RECORDING}
+ cRecPrefix : shortstring;
+ cAVFormat : shortstring;
+ cVideoCodec : shortstring;
+ cVideoFramerateNum : Int64;
+ cVideoFramerateDen : Int64;
+ cVideoQuality : LongInt;
+ cVideoPreset : shortstring;
+ cAudioCodec : shortstring;
+ cAudioQuality : LongInt;
+{$ENDIF}
//////////////////////////
cMapName : shortstring = '';
--- a/hedgewars/uVideoRec.pas Fri Jun 08 02:41:14 2012 +0400
+++ b/hedgewars/uVideoRec.pas Fri Jun 08 02:52:35 2012 +0400
@@ -36,7 +36,7 @@
procedure EncodeFrame;
procedure StopVideoRecording;
-function BeginPreRecording(filePrefix: shortstring): Boolean;
+procedure BeginPreRecording;
procedure StopPreRecording;
procedure SaveCameraPosition;
@@ -53,11 +53,17 @@
type TAddFileLogRaw = procedure (s: pchar); cdecl;
{$IFDEF WIN32}
-procedure AVWrapper_Init(AddLog: TAddFileLogRaw; filename, soundFile: PChar; width, height, framerate, frequency, channels: LongInt); cdecl; external AVWrapperLibName;
+procedure AVWrapper_Init(
+ AddLog: TAddFileLogRaw;
+ filename, soundFile, format, vcodec, acodec, preset: PChar;
+ width, height, framerateNum, framerateDen, frequency, channels, vquality, aquality: LongInt); cdecl; external AVWrapperLibName;
procedure AVWrapper_Close; cdecl; external AVWrapperLibName;
procedure AVWrapper_WriteFrame( pY, pCb, pCr: PByte ); cdecl; external AVWrapperLibName;
{$ELSE}
-procedure AVWrapper_Init(AddLog: TAddFileLogRaw; filename, soundFile: PChar; width, height, framerate, frequency, channels: LongInt); cdecl; external;
+procedure AVWrapper_Init(
+ AddLog: TAddFileLogRaw;
+ filename, soundFile, format, vcodec, acodec, preset: PChar;
+ width, height, framerateNum, framerateDen, frequency, channels, vquality, aquality: LongInt); cdecl; external;
procedure AVWrapper_Close; cdecl; external;
procedure AVWrapper_WriteFrame( pY, pCb, pCr: PByte ); cdecl; external;
{$ENDIF}
@@ -72,7 +78,6 @@
numPixels: LongInt;
- framerate: Int64 = 30;
firstTick, nframes: Int64;
cameraFilePath, soundFilePath: shortstring;
@@ -98,9 +103,14 @@
ReadLn(cameraFile, frequency, channels);
{$IOCHECKS ON}
- filename:= UserPathPrefix + '/Videos/' + cRecPrefix + '.mp4' + #0;
+ filename:= UserPathPrefix + '/Videos/' + cRecPrefix + #0;
soundFilePath:= UserPathPrefix + '/Videos/' + cRecPrefix + '.hwsound' + #0;
- AVWrapper_Init(@AddFileLogRaw, @filename[1], @soundFilePath[1], cScreenWidth, cScreenHeight, framerate, frequency, channels);
+ cAVFormat+= #0;
+ cAudioCodec+= #0;
+ cVideoCodec+= #0;
+ cVideoPreset+= #0;
+ AVWrapper_Init(@AddFileLogRaw, @filename[1], @soundFilePath[1], @cAVFormat[1], @cVideoCodec[1], @cAudioCodec[1], @cVideoPreset[1],
+ cScreenWidth, cScreenHeight, cVideoFramerateNum, cVideoFramerateDen, frequency, channels, cAudioQuality, cVideoQuality);
YCbCr_Planes[0]:= GetMem(numPixels);
YCbCr_Planes[1]:= GetMem(numPixels div 4);
@@ -194,21 +204,23 @@
{$IOCHECKS ON}
end;
-function BeginPreRecording(filePrefix: shortstring): Boolean;
+procedure BeginPreRecording;
var format: word;
- filename: shortstring;
+ filePrefix, filename: shortstring;
begin
AddFileLog('BeginPreRecording');
-
+
nframes:= 0;
firstTick:= SDL_GetTicks();
+ filePrefix:= FormatDateTime('YYYY-MM-DD_HH-mm-ss', Now());
+
Mix_QuerySpec(@frequency, @format, @channels);
if format <> $8010 then
begin
// TODO: support any audio format
AddFileLog('Error: Unexpected audio format ' + IntToStr(format));
- exit(false);
+ exit;
end;
{$IOCHECKS OFF}
@@ -218,7 +230,7 @@
if IOResult <> 0 then
begin
AddFileLog('Error: Could not write to ' + filename);
- exit(false);
+ exit;
end;
filename:= UserPathPrefix + '/Videos/' + filePrefix + '.txtout';
@@ -227,7 +239,7 @@
if IOResult <> 0 then
begin
AddFileLog('Error: Could not write to ' + filename);
- exit(false);
+ exit;
end;
{$IOCHECKS ON}
WriteLn(cameraFile, inttostr(frequency) + ' ' + inttostr(channels));
@@ -236,7 +248,6 @@
Mix_SetPostMix(@RecordPostMix, nil);
flagPrerecording:= true;
- BeginPreRecording:= true;
end;
procedure StopPreRecording;
@@ -256,7 +267,7 @@
var Ticks: LongInt;
begin
Ticks:= SDL_GetTicks();
- while (Ticks - firstTick)*framerate > nframes*1000 do
+ while (Ticks - firstTick)*cVideoFramerateNum > nframes*cVideoFramerateDen*1000 do
begin
WriteLn(cameraFile, inttostr(GameTicks) + ' ' + inttostr(WorldDx) + ' ' + inttostr(WorldDy) + ' ' + inttostr(Round(zoom*10000)));
inc(nframes);
--- a/hedgewars/uWorld.pas Fri Jun 08 02:41:14 2012 +0400
+++ b/hedgewars/uWorld.pas Fri Jun 08 02:52:35 2012 +0400
@@ -1574,7 +1574,8 @@
end
end;
-// rec
+{$IFDEF USE_VIDEO_RECORDING}
+// during video prerecording draw red blinking circle and text 'rec'
if flagPrerecording then
begin
if recTexture = nil then
@@ -1598,6 +1599,7 @@
Tint($FF, $FF, $FF, $FF);
glEnable(GL_TEXTURE_2D);
end;
+{$ENDIF}
SetScale(zoom);