hedgewars/uVideoRec.pas
changeset 7235 baa69bd025d9
parent 7198 5debd5fe526e
child 7280 fd707afbc3a2
equal deleted inserted replaced
7231:f484455dd055 7235:baa69bd025d9
    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);
   267 var Ticks: LongInt;
   270 var Ticks: LongInt;
   268 begin
   271 begin
   269     Ticks:= SDL_GetTicks();
   272     Ticks:= SDL_GetTicks();
   270     while (Ticks - firstTick)*cVideoFramerateNum > nframes*cVideoFramerateDen*1000 do
   273     while (Ticks - firstTick)*cVideoFramerateNum > nframes*cVideoFramerateDen*1000 do
   271     begin
   274     begin
   272         WriteLn(cameraFile, inttostr(GameTicks) + ' ' + inttostr(WorldDx) + ' ' + inttostr(WorldDy) + ' ' + inttostr(Round(zoom*10000)));
   275         WriteLn(cameraFile, inttostr(GameTicks) + ' ' + inttostr(WorldDx) + ' ' + inttostr(WorldDy - cScreenHeight div 2) + ' ' + inttostr(Round(zoom*10000/cScreenWidth)));
   273         inc(nframes);
   276         inc(nframes);
   274     end;
   277     end;
   275 end;
   278 end;
   276 
   279 
   277 procedure freeModule;
   280 procedure freeModule;