53 type TAddFileLogRaw = procedure (s: pchar); cdecl; |
53 type TAddFileLogRaw = procedure (s: pchar); cdecl; |
54 |
54 |
55 {$IFDEF WIN32} |
55 {$IFDEF WIN32} |
56 procedure AVWrapper_Init( |
56 procedure AVWrapper_Init( |
57 AddLog: TAddFileLogRaw; |
57 AddLog: TAddFileLogRaw; |
58 filename, soundFile, format, vcodec, acodec, preset: PChar; |
58 filename, finalFilename, soundFile, format, vcodec, acodec, preset: PChar; |
59 width, height, framerateNum, framerateDen, frequency, channels, vquality, aquality: LongInt); cdecl; external AVWrapperLibName; |
59 width, height, framerateNum, framerateDen, frequency, channels, vquality, aquality: LongInt); cdecl; external AVWrapperLibName; |
60 procedure AVWrapper_Close; cdecl; external AVWrapperLibName; |
60 procedure AVWrapper_Close; cdecl; external AVWrapperLibName; |
61 procedure AVWrapper_WriteFrame( pY, pCb, pCr: PByte ); cdecl; external AVWrapperLibName; |
61 procedure AVWrapper_WriteFrame( pY, pCb, pCr: PByte ); cdecl; external AVWrapperLibName; |
62 {$ELSE} |
62 {$ELSE} |
63 procedure AVWrapper_Init( |
63 procedure AVWrapper_Init( |
64 AddLog: TAddFileLogRaw; |
64 AddLog: TAddFileLogRaw; |
65 filename, soundFile, format, vcodec, acodec, preset: PChar; |
65 filename, finalFilename, soundFile, format, vcodec, acodec, preset: PChar; |
66 width, height, framerateNum, framerateDen, frequency, channels, vquality, aquality: LongInt); cdecl; external; |
66 width, height, framerateNum, framerateDen, frequency, channels, vquality, aquality: LongInt); cdecl; external; |
67 procedure AVWrapper_Close; cdecl; external; |
67 procedure AVWrapper_Close; cdecl; external; |
68 procedure AVWrapper_WriteFrame( pY, pCb, pCr: PByte ); cdecl; external; |
68 procedure AVWrapper_WriteFrame( pY, pCb, pCr: PByte ); cdecl; external; |
69 {$ENDIF} |
69 {$ENDIF} |
70 |
70 |
73 |
73 |
74 frequency, channels: LongInt; |
74 frequency, channels: LongInt; |
75 |
75 |
76 cameraFile: TextFile; |
76 cameraFile: TextFile; |
77 audioFile: File; |
77 audioFile: File; |
78 |
78 |
79 numPixels: LongInt; |
79 numPixels: LongInt; |
80 |
80 |
81 firstTick, nframes: Int64; |
81 firstTick, nframes: Int64; |
82 |
82 |
83 cameraFilePath, soundFilePath: shortstring; |
83 cameraFilePath, soundFilePath: shortstring; |
84 |
84 |
85 function BeginVideoRecording: Boolean; |
85 function BeginVideoRecording: Boolean; |
86 var filename: shortstring; |
86 var filename, finalFilename: shortstring; |
87 begin |
87 begin |
88 AddFileLog('BeginVideoRecording'); |
88 AddFileLog('BeginVideoRecording'); |
89 |
89 |
90 numPixels:= cScreenWidth*cScreenHeight; |
90 numPixels:= cScreenWidth*cScreenHeight; |
91 |
91 |
92 {$IOCHECKS OFF} |
92 {$IOCHECKS OFF} |
93 // open file with prerecorded camera positions |
93 // open file with prerecorded camera positions |
94 cameraFilePath:= UserPathPrefix + '/Videos/' + cRecPrefix + '.txtin'; |
94 cameraFilePath:= UserPathPrefix + '/VideoTemp/' + cRecPrefix + '.txtin'; |
95 Assign(cameraFile, cameraFilePath); |
95 Assign(cameraFile, cameraFilePath); |
96 Reset(cameraFile); |
96 Reset(cameraFile); |
97 if IOResult <> 0 then |
97 if IOResult <> 0 then |
98 begin |
98 begin |
99 AddFileLog('Error: Could not read from ' + cameraFilePath); |
99 AddFileLog('Error: Could not read from ' + cameraFilePath); |
101 end; |
101 end; |
102 |
102 |
103 ReadLn(cameraFile, frequency, channels); |
103 ReadLn(cameraFile, frequency, channels); |
104 {$IOCHECKS ON} |
104 {$IOCHECKS ON} |
105 |
105 |
106 filename:= UserPathPrefix + '/Videos/' + cRecPrefix + #0; |
106 filename:= UserPathPrefix + '/VideoTemp/' + cRecPrefix + #0; |
107 soundFilePath:= UserPathPrefix + '/Videos/' + cRecPrefix + '.hwsound' + #0; |
107 finalFilename:= UserPathPrefix + '/Videos/' + cRecPrefix + #0; |
|
108 soundFilePath:= UserPathPrefix + '/VideoTemp/' + cRecPrefix + '.sw' + #0; |
108 cAVFormat+= #0; |
109 cAVFormat+= #0; |
109 cAudioCodec+= #0; |
110 cAudioCodec+= #0; |
110 cVideoCodec+= #0; |
111 cVideoCodec+= #0; |
111 cVideoPreset+= #0; |
112 cVideoPreset+= #0; |
112 AVWrapper_Init(@AddFileLogRaw, @filename[1], @soundFilePath[1], @cAVFormat[1], @cVideoCodec[1], @cAudioCodec[1], @cVideoPreset[1], |
113 AVWrapper_Init(@AddFileLogRaw, @filename[1], @finalFilename[1], @soundFilePath[1], @cAVFormat[1], @cVideoCodec[1], @cAudioCodec[1], @cVideoPreset[1], |
113 cScreenWidth, cScreenHeight, cVideoFramerateNum, cVideoFramerateDen, frequency, channels, cAudioQuality, cVideoQuality); |
114 cScreenWidth, cScreenHeight, cVideoFramerateNum, cVideoFramerateDen, frequency, channels, cAudioQuality, cVideoQuality); |
114 |
115 |
115 YCbCr_Planes[0]:= GetMem(numPixels); |
116 YCbCr_Planes[0]:= GetMem(numPixels); |
116 YCbCr_Planes[1]:= GetMem(numPixels div 4); |
117 YCbCr_Planes[1]:= GetMem(numPixels div 4); |
117 YCbCr_Planes[2]:= GetMem(numPixels div 4); |
118 YCbCr_Planes[2]:= GetMem(numPixels div 4); |
174 end; |
175 end; |
175 |
176 |
176 AVWrapper_WriteFrame(YCbCr_Planes[0], YCbCr_Planes[1], YCbCr_Planes[2]); |
177 AVWrapper_WriteFrame(YCbCr_Planes[0], YCbCr_Planes[1], YCbCr_Planes[2]); |
177 end; |
178 end; |
178 |
179 |
|
180 // returns new game ticks |
179 function LoadNextCameraPosition: LongInt; |
181 function LoadNextCameraPosition: LongInt; |
180 var NextTime: LongInt; |
182 var NextTime: LongInt; |
181 NextZoom: LongInt; |
183 NextZoom: LongInt; |
182 NextWorldDx, NextWorldDy: LongInt; |
184 NextWorldDx, NextWorldDy: LongInt; |
183 begin |
185 begin |
184 {$IOCHECKS OFF} |
186 {$IOCHECKS OFF} |
185 if eof(cameraFile) then |
187 if eof(cameraFile) then |
186 exit(-1); |
188 exit(-1); |
187 ReadLn(cameraFile, NextTime, NextWorldDx, NextWorldDy, NextZoom); |
189 ReadLn(cameraFile, NextTime, NextWorldDx, NextWorldDy, NextZoom); |
188 {$IOCHECKS ON} |
190 {$IOCHECKS ON} |
189 if NextTime = 0 then |
|
190 exit(-1); |
|
191 WorldDx:= NextWorldDx; |
191 WorldDx:= NextWorldDx; |
192 WorldDy:= NextWorldDy; |
192 WorldDy:= NextWorldDy + cScreenHeight div 2; |
193 zoom:= NextZoom/10000; |
193 zoom:= NextZoom/10000*cScreenWidth; |
194 ZoomValue:= NextZoom/10000; |
194 ZoomValue:= zoom; |
195 LoadNextCameraPosition:= NextTime; |
195 LoadNextCameraPosition:= NextTime; |
196 end; |
196 end; |
197 |
197 |
198 // this procedure may be called from different thread |
198 // Callback which records sound. |
|
199 // This procedure may be called from different thread. |
199 procedure RecordPostMix(udata: pointer; stream: PByte; len: LongInt); cdecl; |
200 procedure RecordPostMix(udata: pointer; stream: PByte; len: LongInt); cdecl; |
200 begin |
201 begin |
201 udata:= udata; |
202 udata:= udata; // avoid warning |
202 {$IOCHECKS OFF} |
203 {$IOCHECKS OFF} |
203 BlockWrite(audioFile, stream^, len); |
204 BlockWrite(audioFile, stream^, len); |
204 {$IOCHECKS ON} |
205 {$IOCHECKS ON} |
205 end; |
206 end; |
206 |
207 |
207 procedure BeginPreRecording; |
208 procedure BeginPreRecording; |
208 var format: word; |
209 var format: word; |
209 filePrefix, filename: shortstring; |
210 filePrefix, filename: shortstring; |
210 begin |
211 begin |
211 AddFileLog('BeginPreRecording'); |
212 AddFileLog('BeginPreRecording'); |
212 |
213 |
213 nframes:= 0; |
214 nframes:= 0; |
214 firstTick:= SDL_GetTicks(); |
215 firstTick:= SDL_GetTicks(); |
215 |
216 |
216 filePrefix:= FormatDateTime('YYYY-MM-DD_HH-mm-ss', Now()); |
217 filePrefix:= FormatDateTime('YYYY-MM-DD_HH-mm-ss', Now()); |
217 |
218 |
222 AddFileLog('Error: Unexpected audio format ' + IntToStr(format)); |
223 AddFileLog('Error: Unexpected audio format ' + IntToStr(format)); |
223 exit; |
224 exit; |
224 end; |
225 end; |
225 |
226 |
226 {$IOCHECKS OFF} |
227 {$IOCHECKS OFF} |
227 filename:= UserPathPrefix + '/Videos/' + filePrefix + '.hwsound'; |
228 // create sound file |
|
229 filename:= UserPathPrefix + '/VideoTemp/' + filePrefix + '.sw'; |
228 Assign(audioFile, filename); |
230 Assign(audioFile, filename); |
229 Rewrite(audioFile, 1); |
231 Rewrite(audioFile, 1); |
230 if IOResult <> 0 then |
232 if IOResult <> 0 then |
231 begin |
233 begin |
232 AddFileLog('Error: Could not write to ' + filename); |
234 AddFileLog('Error: Could not write to ' + filename); |
233 exit; |
235 exit; |
234 end; |
236 end; |
235 |
237 |
236 filename:= UserPathPrefix + '/Videos/' + filePrefix + '.txtout'; |
238 // create file with camera positions |
|
239 filename:= UserPathPrefix + '/VideoTemp/' + filePrefix + '.txtout'; |
237 Assign(cameraFile, filename); |
240 Assign(cameraFile, filename); |
238 Rewrite(cameraFile); |
241 Rewrite(cameraFile); |
239 if IOResult <> 0 then |
242 if IOResult <> 0 then |
240 begin |
243 begin |
241 AddFileLog('Error: Could not write to ' + filename); |
244 AddFileLog('Error: Could not write to ' + filename); |