Remove C4Video, StdVideo

Video recording and playback only worked on Windows, and recording only
handled video, not game audio. As such, it was of fairly limited use,
and there's lots of software available these days that handle both.
shapetextures
Nicolas Hake 2015-12-27 23:00:08 +01:00
parent 7475b89bd2
commit d737dc1b05
14 changed files with 0 additions and 878 deletions

View File

@ -493,15 +493,11 @@ set(OC_CLONK_SOURCES
src/platform/C4TimeMilliseconds.h
src/platform/C4StdInProc.cpp
src/platform/C4StdInProc.h
src/platform/C4Video.cpp
src/platform/C4Video.h
src/platform/C4Window.h
src/platform/C4windowswrapper.h
src/platform/PlatformAbstraction.cpp
src/platform/PlatformAbstraction.h
src/platform/StdSync.h
src/platform/StdVideo.cpp
src/platform/StdVideo.h
src/player/C4Player.cpp
src/player/C4Player.h
src/player/C4PlayerList.cpp
@ -1333,20 +1329,6 @@ if(USE_COCOA)
TARGET_LINK_LIBRARIES(openclonk-server "-framework Cocoa")
endif()
if (WIN32)
# CMake is too incompetent to check whether these libraries can be linked to
# So just pretend that everything is fine
FINDLIB(VFW32_LIBRARIES vfw32)
FINDLIB(wavifil32_LIBRARIES wavifil32)
if (VFW32_LIBRARIES)
target_link_libraries(openclonk vfw32)
target_link_libraries(openclonk-server vfw32)
set(HAVE_VFW32 TRUE)
elseif(wavifil32_LIBRARIES)
target_link_libraries(openclonk wavifil32 msvfw32)
target_link_libraries(openclonk-server wavifil32 msvfw32)
set(HAVE_VFW32 TRUE)
endif()
target_link_libraries(openclonk ws2_32)
target_link_libraries(openclonk-server ws2_32)
target_link_libraries(c4group ws2_32)

View File

@ -91,8 +91,6 @@
/* Define to 1 if you have the `__mingw_vasprintf' function. */
#cmakedefine HAVE___MINGW_VASPRINTF 1
#cmakedefine HAVE_VFW32
/* Define to 1 if you have the <X11/extensions/Xrandr.h> header file. */
#cmakedefine HAVE_X11_EXTENSIONS_XRANDR_H 1

View File

@ -99,7 +99,6 @@ void C4ConfigGraphics::CompileFunc(StdCompiler *pComp)
pComp->Value(mkNamingAdapt(ShowStartupMessages, "ShowStartupMessages", 1 ,false, true));
pComp->Value(mkNamingAdapt(HighResLandscape, "HighResLandscape", 1 ,false, true));
pComp->Value(mkNamingAdapt(VerboseObjectLoading, "VerboseObjectLoading", 0 ));
pComp->Value(mkNamingAdapt(VideoModule, "VideoModule", 0 ,false, true));
pComp->Value(mkNamingAdapt(MenuTransparency, "MenuTransparency", 1 ,false, true));
pComp->Value(mkNamingAdapt(UpperBoard, "UpperBoard", 1 ,false, true));
pComp->Value(mkNamingAdapt(ShowClock, "ShowClock", 0 ,false, true));

View File

@ -97,7 +97,6 @@ public:
int32_t ShowStartupMessages;
int32_t VerboseObjectLoading;
int32_t HighResLandscape;
int32_t VideoModule;
int32_t MenuTransparency;
int32_t UpperBoard;
int32_t ShowClock;

View File

@ -2942,11 +2942,6 @@ bool C4Game::InitKeyboard()
KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_F7, KEYS_Control), "DbgShowActionToggle", KEYSCOPE_Generic, new C4KeyCB <C4GraphicsSystem>(GraphicsSystem, &C4GraphicsSystem::ToggleShowAction)));
KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_F8, KEYS_Control), "DbgShow8BitSurface", KEYSCOPE_Generic, new C4KeyCB <C4GraphicsSystem>(GraphicsSystem, &C4GraphicsSystem::ToggleShow8BitSurface)));
// video recording - improve...
KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_ADD, KEYS_Alt), "VideoEnlarge", KEYSCOPE_Generic, new C4KeyCB <C4Video> (GraphicsSystem.Video, &C4Video::Enlarge)));
KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_SUBTRACT, KEYS_Alt), "VideoReduce", KEYSCOPE_Generic, new C4KeyCB <C4Video> (GraphicsSystem.Video, &C4Video::Reduce)));
KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_MULTIPLY, KEYS_Alt), "VideoToggle", KEYSCOPE_Generic, new C4KeyCB <C4Video> (GraphicsSystem.Video, &C4Video::Toggle)));
// playback speed - improve...
KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_ADD, KEYS_Shift), "GameSpeedUp", KEYSCOPE_Generic, new C4KeyCB <C4Game> (*this, &C4Game::SpeedUp)));
KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_SUBTRACT, KEYS_Shift), "GameSlowDown", KEYSCOPE_Generic, new C4KeyCB <C4Game> (*this, &C4Game::SlowDown)));

View File

@ -46,9 +46,6 @@ C4GraphicsSystem::~C4GraphicsSystem()
bool C4GraphicsSystem::Init()
{
// Init video module
if (Config.Graphics.VideoModule)
Video.Init(FullScreen.pSurface);
// Success
return true;
}
@ -61,8 +58,6 @@ void C4GraphicsSystem::Clear()
if (pLoaderScreen) { delete pLoaderScreen; pLoaderScreen=NULL; }
// Close viewports
::Viewports.Clear();
// Clear video system
Video.Clear();
// No debug stuff
DeactivateDebugOutput();
}
@ -147,10 +142,6 @@ void C4GraphicsSystem::Execute()
::pGUI->Render(false);
}
// Video record & status (fullsrceen)
if (!Application.isEditor)
Video.Execute();
// done
FinishDrawing();
}
@ -171,7 +162,6 @@ void C4GraphicsSystem::Default()
ShowHelp=false;
FlashMessageText[0]=0;
FlashMessageTime=0; FlashMessageX=FlashMessageY=0;
Video.Default();
pLoaderScreen=NULL;
}

View File

@ -22,7 +22,6 @@
#include <C4MessageBoard.h>
#include <C4UpperBoard.h>
#include <C4Video.h>
#include <memory>
@ -44,7 +43,6 @@ public:
int Show8BitSurface; // 0 normal, 1 foreground mats, 2 background mats
bool ShowLights;
bool ShowMenuInfo;
C4Video Video;
C4LoaderScreen *pLoaderScreen;
void Default();
void Clear();

View File

@ -355,10 +355,6 @@ void C4Viewport::Execute()
pDraw->PrepareRendering(w->pSurface);
// Draw
Draw(cgo, true);
// Video record & status (developer mode, first player viewport)
if (Application.isEditor)
if (Player==0 && (this==::Viewports.GetViewport((int32_t) 0)))
::GraphicsSystem.Video.Execute();
// Blit output
BlitOutput();
}

View File

@ -123,7 +123,6 @@ public:
friend class C4ViewportWindow;
friend class C4ViewportList;
friend class C4GraphicsSystem;
friend class C4Video;
};
class C4ViewportList {

View File

@ -147,7 +147,6 @@
#define C4GUI_TabCaptionScrollTime 500 // 0.5 seconds
// Z-ordering of dialogs
#define C4GUI_Z_VIDEO +3 // video dialog obstructing all
#define C4GUI_Z_CHAT +2 // chat input dialog more important than other input dialogs
#define C4GUI_Z_INPUT +1 // input dialogs on top of others
#define C4GUI_Z_DEFAULT 0 // normal placement on top of viewports

View File

@ -1,302 +0,0 @@
/*
* OpenClonk, http://www.openclonk.org
*
* Copyright (c) 1998-2000, Matthes Bender
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
* Copyright (c) 2009-2013, The OpenClonk Team and contributors
*
* Distributed under the terms of the ISC license; see accompanying file
* "COPYING" for details.
*
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
* See accompanying file "TRADEMARK" for details.
*
* To redistribute this file separately, substitute the full license texts
* for the above references.
*/
/* Captures uncompressed AVI from game view */
#include <C4Include.h>
#include <C4Video.h>
#include <C4Viewport.h>
#include <C4Config.h>
#include <C4Application.h>
#include <C4Game.h>
#include <C4Player.h>
#include <C4GraphicsResource.h>
#include <C4GraphicsSystem.h>
#include <C4PlayerList.h>
#ifdef _WIN32
#include <StdVideo.h>
#endif
C4Video::C4Video()
{
Default();
}
C4Video::~C4Video()
{
Clear();
}
void C4Video::Default()
{
Active=false;
pAviFile=NULL;
pAviStream=NULL;
AviFrame=0;
AspectRatio=1.333;
X=0; Y=0;
Width=768; Height=576;
Buffer=NULL;
BufferSize=0;
InfoSize=0;
Recording=false;
Surface=NULL;
ShowFlash=0;
}
void C4Video::Clear()
{
Stop();
}
void C4Video::Init(C4Surface * sfcSource, int iWidth, int iHeight)
{
// Activate
Active=true;
// Set source surface
Surface=sfcSource;
// Set video size
Width=iWidth; Height=iHeight;
AspectRatio = (double) iWidth / (double) iHeight;
}
bool C4Video::Enlarge()
{
if (!Config.Graphics.VideoModule) return false;
Resize(+16);
return true;
}
bool C4Video::Reduce()
{
if (!Config.Graphics.VideoModule) return false;
Resize(-16);
return true;
}
void C4Video::Execute() // Record frame, draw status
{
#ifdef _WIN32
// Not active
if (!Active) return;
// Flash time
if (ShowFlash) ShowFlash--;
// Record
if (Recording) RecordFrame();
// Draw
Draw();
#endif
}
bool C4Video::Toggle()
{
if (!Config.Graphics.VideoModule) return false;
if (!Recording) return(Start());
return(Stop());
}
bool C4Video::Stop()
{
#ifdef _WIN32
// Recording: close file
if (Recording) AVICloseOutput(&pAviFile,&pAviStream);
// Recording flag
Recording = false;
// Clear buffer
if (Buffer) delete [] Buffer; Buffer=NULL;
#endif
// Done
return true;
}
bool C4Video::Start()
{
// Determine new filename
char szFilename[_MAX_PATH+1]; int iIndex=0;
do { sprintf(szFilename,"Video%03d.avi",iIndex++); }
while (ItemExists(szFilename));
// Start recording
return(Start(szFilename));
}
bool C4Video::Start(const char *szFilename)
{
#ifdef _WIN32
// Stop any recording
Stop();
// Open output file
if (!AVIOpenOutput(szFilename,&pAviFile,&pAviStream,Width,Height))
{
Log("AVIOpenOutput failure");
AVICloseOutput(&pAviFile,&pAviStream);
return false;
}
// Create video buffer
AviFrame=0;
InfoSize = sizeof(BITMAPINFOHEADER);
if (Config.Graphics.BitDepth == 8)
InfoSize += sizeof(RGBQUAD)*256;
BufferSize = InfoSize + DWordAligned(Width)*Height * Config.Graphics.BitDepth/8;
Buffer = new BYTE[BufferSize];
// Set bitmap info
BITMAPINFO *pInfo = (BITMAPINFO*) Buffer;
ZeroMem((BYTE*)pInfo,sizeof(BITMAPINFOHEADER));
pInfo->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
pInfo->bmiHeader.biPlanes=1;
pInfo->bmiHeader.biWidth=Width;
pInfo->bmiHeader.biHeight=Height;
pInfo->bmiHeader.biBitCount=Config.Graphics.BitDepth;
pInfo->bmiHeader.biCompression=0;
pInfo->bmiHeader.biSizeImage = DWordAligned(Width)*Height * Config.Graphics.BitDepth/8;
// Recording flag
Recording=true;
#endif //_WIN32
// Success
return true;
}
void C4Video::Resize(int iChange)
{
// Not while recording
if (Recording) return;
// Resize
Width = Clamp( Width+iChange, 56, 800 );
Height = Clamp( (int) ((double)Width/AspectRatio), 40, 600 );
// Adjust position
AdjustPosition();
// Show flash
ShowFlash=50;
}
void C4Video::Draw(C4TargetFacet &cgo)
{
// Not active
if (!Active) return;
// No show
if (!ShowFlash) return;
// Draw frame
pDraw->DrawFrameDw(cgo.Surface, X+cgo.X,Y+cgo.Y,
X+cgo.X+Width-1,Y+cgo.Y+Height-1,
Recording ? C4RGB(0xca, 0, 0) : C4RGB(0xff, 0xff, 0xff));
// Draw status
StdStrBuf str;
if (Recording) str.Format("%dx%d Frame %d",Width,Height,AviFrame);
else str.Format("%dx%d",Width,Height);
pDraw->TextOut(str.getData(), ::GraphicsResource.FontRegular, 1.0,cgo.Surface,cgo.X+X+4,cgo.Y+Y+3,Recording ? 0xfaFF0000 : 0xfaFFFFFF);
}
bool C4Video::AdjustPosition()
{
// Get source player & viewport
C4Viewport *pViewport = ::Viewports.GetFirstViewport();
if (!pViewport) return false;
C4Player *pPlr = ::Players.Get(pViewport->GetPlayer());
if (!pPlr) return false;
// Set camera position
X = int32_t(fixtof(pPlr->ViewX) - pViewport->GetViewX() + pViewport->DrawX - Width/2);
X = Clamp( X, 0, pViewport->ViewWdt - Width );
Y = int32_t(fixtof(pPlr->ViewY) - pViewport->GetViewY() + pViewport->DrawY - Height/2);
Y = Clamp( Y, 0, pViewport->ViewHgt - Height );
// Success
return true;
}
#ifdef _WIN32
static void StdBlit(uint8_t *bypSource, int iSourcePitch, int iSrcBufHgt,
int iSrcX, int iSrcY, int iSrcWdt, int iSrcHgt,
uint8_t *bypTarget, int iTargetPitch, int iTrgBufHgt,
int iTrgX, int iTrgY, int iTrgWdt, int iTrgHgt,
int iBytesPerPixel=1, bool fFlip=false)
{
if (!bypSource || !bypTarget) return;
if (!iTrgWdt || !iTrgHgt) return;
int xcnt,ycnt,zcnt,sline,tline,fy;
for (ycnt=0; ycnt<iTrgHgt; ycnt++)
{
fy = iSrcHgt * ycnt / iTrgHgt;
if (iSrcBufHgt>0) sline = ( iSrcBufHgt - 1 - iSrcY - fy ) * iSourcePitch;
else sline = ( iSrcY + fy ) * iSourcePitch;
if (iTrgBufHgt>0) tline = ( iTrgBufHgt - 1 - iTrgY - ycnt ) * iTargetPitch;
else tline = ( iTrgY + ycnt ) * iTargetPitch;
if (!fFlip)
{
for (xcnt=0; xcnt<iTrgWdt; xcnt++)
for (zcnt=0; zcnt<iBytesPerPixel; zcnt++)
bypTarget [ tline + (iTrgX + xcnt) * iBytesPerPixel + zcnt]
= bypSource [ sline + (iSrcX + iSrcWdt * xcnt / iTrgWdt) * iBytesPerPixel + zcnt ];
}
else
{
for (xcnt=0; xcnt<iTrgWdt; xcnt++)
for (zcnt=0; zcnt<iBytesPerPixel; zcnt++)
bypTarget [ tline + (iTrgX + iTrgWdt - 1 -xcnt) * iBytesPerPixel + zcnt]
= bypSource [ sline + (iSrcX + iSrcWdt * xcnt / iTrgWdt) * iBytesPerPixel + zcnt ];
}
}
}
bool C4Video::RecordFrame()
{
// No buffer
if (!Buffer) return false;
// Lock source
int iPitch,iHeight;
if (!Surface->Lock()) { Log("Video: lock surface failure"); Stop(); return false; }
iPitch = Surface->PrimarySurfaceLockPitch;
BYTE *bypBits = Surface->PrimarySurfaceLockBits;
iHeight = Surface->Hgt;
// Adjust source position
if (!AdjustPosition()) { Log("Video: player/viewport failure"); Stop(); return false; }
// Blit screen to buffer
StdBlit((uint8_t*)bypBits,iPitch,-iHeight,
X,Y,Width,Height,
(uint8_t*)Buffer+InfoSize,
DWordAligned(Width) * (Config.Graphics.BitDepth/8),Height,
0,0,Width,Height,
Config.Graphics.BitDepth/8);
// Unlock source
Surface->Unlock();
// Write frame to file
if (!AVIPutFrame(pAviStream,
AviFrame,
Buffer,InfoSize,
Buffer+InfoSize,BufferSize-InfoSize))
{ Log("AVIPutFrame failure"); Stop(); return false; }
// Advance frame
AviFrame++;
// Show flash
ShowFlash=1;
// Success
return true;
}
void C4Video::Draw()
{
// Not active
if (!Active) return;
// Get viewport
C4Viewport *pViewport;
if ( (pViewport = ::Viewports.GetFirstViewport()) )
{
C4TargetFacet cgo;
cgo.Set(Surface,pViewport->DrawX,pViewport->DrawY,pViewport->ViewWdt,pViewport->ViewHgt,pViewport->GetViewX(),pViewport->GetViewY());
Draw(cgo);
}
}
#endif //_WIN32

View File

@ -1,68 +0,0 @@
/*
* OpenClonk, http://www.openclonk.org
*
* Copyright (c) 1998-2000, Matthes Bender
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
* Copyright (c) 2013, The OpenClonk Team and contributors
*
* Distributed under the terms of the ISC license; see accompanying file
* "COPYING" for details.
*
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
* See accompanying file "TRADEMARK" for details.
*
* To redistribute this file separately, substitute the full license texts
* for the above references.
*/
/* Captures uncompressed AVI from game view */
#ifndef INC_C4Video
#define INC_C4Video
#include <C4Surface.h>
// avoid pulling in vfw.h in every file
struct IAVIFile;
struct IAVIStream;
class C4TargetFacet;
class C4Video
{
public:
C4Video();
~C4Video();
protected:
bool Active;
IAVIFile * pAviFile;
IAVIStream * pAviStream;
int AviFrame;
double AspectRatio;
int X,Y,Width,Height;
BYTE *Buffer;
int BufferSize;
int InfoSize;
bool Recording;
C4Surface * Surface;
int ShowFlash;
public:
void Draw();
void Draw(C4TargetFacet &cgo);
void Resize(int iChange);
bool Start(const char *szFilename);
void Default();
void Init(C4Surface * sfcSource, int iWidth=768, int iHeight=576);
void Clear();
bool Start();
bool Stop();
bool Toggle();
void Execute();
bool Reduce();
bool Enlarge();
protected:
bool RecordFrame();
bool AdjustPosition();
};
#endif

View File

@ -1,351 +0,0 @@
/*
* OpenClonk, http://www.openclonk.org
*
* Copyright (c) 1998-2000, Matthes Bender
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
* Copyright (c) 2009-2013, The OpenClonk Team and contributors
*
* Distributed under the terms of the ISC license; see accompanying file
* "COPYING" for details.
*
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
* See accompanying file "TRADEMARK" for details.
*
* To redistribute this file separately, substitute the full license texts
* for the above references.
*/
/* Some functions to help with saving AVI files using Video for Windows */
#include "C4Include.h"
#ifdef _WIN32
#ifdef HAVE_VFW32
#include <StdVideo.h>
#include <C4Surface.h>
bool AVIOpenOutput(const char *szFilename,
PAVIFILE *ppAviFile,
PAVISTREAM *ppAviStream,
int iWidth, int iHeight)
{
// Init AVI system
AVIFileInit();
// Create avi file
if ( AVIFileOpenW(
ppAviFile,
GetWideChar(szFilename),
OF_CREATE | OF_WRITE,
NULL) != 0)
{
return false;
}
// Create stream
AVISTREAMINFOW avi_info;
RECT frame; frame.left=0; frame.top=0; frame.right=iWidth; frame.bottom=iHeight;
avi_info.fccType= streamtypeVIDEO;
avi_info.fccHandler= mmioFOURCC('M','S','V','C');
avi_info.dwFlags= 0;
avi_info.dwCaps= 0;
avi_info.wPriority= 0;
avi_info.wLanguage= 0;
avi_info.dwScale= 1;
avi_info.dwRate= 35;
avi_info.dwStart= 0;
avi_info.dwLength= 10; // ??
avi_info.dwInitialFrames= 0;
avi_info.dwSuggestedBufferSize= 0;
avi_info.dwQuality= -1;
avi_info.dwSampleSize= 0;
avi_info.rcFrame= frame;
avi_info.dwEditCount= 0;
avi_info.dwFormatChangeCount= 0;
wcscpy(avi_info.szName, L"MyRecording");
if ( AVIFileCreateStreamW(
*ppAviFile,
ppAviStream,
&avi_info) != 0)
{
return false;
}
return true;
}
bool AVICloseOutput(PAVIFILE *ppAviFile,
PAVISTREAM *ppAviStream)
{
if (ppAviStream && *ppAviStream)
{ AVIStreamRelease(*ppAviStream); *ppAviStream=NULL; }
if (ppAviFile && *ppAviFile)
{ AVIFileRelease(*ppAviFile); *ppAviFile=NULL; }
return true;
}
bool AVIPutFrame(PAVISTREAM pAviStream,
long lFrame,
void *lpInfo, long lInfoSize,
void *lpData, long lDataSize)
{
long lBytesWritten=0,lSamplesWritten=0;
AVIStreamSetFormat(
pAviStream,
lFrame,
lpInfo,
lInfoSize
);
if (AVIStreamWrite(
pAviStream,
lFrame,
1,
lpData,
lDataSize,
AVIIF_KEYFRAME,
&lSamplesWritten,
&lBytesWritten) != 0) return false;
return true;
}
bool AVIOpenGrab(const char *szFilename,
PAVISTREAM *ppAviStream,
PGETFRAME *ppGetFrame,
int &rAviLength, int &rFrameWdt, int &rFrameHgt,
int &rFrameBitsPerPixel, int &rFramePitch)
{
// Open avi stream
if ( AVIStreamOpenFromFileW(
ppAviStream,
GetWideChar(szFilename),
streamtypeVIDEO,
0,
OF_READ,
NULL) != 0) return false;
// Get stream info
AVISTREAMINFO avi_info;
AVIStreamInfo(*ppAviStream,&avi_info,sizeof(avi_info));
rAviLength=avi_info.dwLength;
// Open get frame
if (!(*ppGetFrame = AVIStreamGetFrameOpen(*ppAviStream,NULL))) return false;
// Get sample frame
void *pframe;
if (!(pframe = AVIStreamGetFrame(*ppGetFrame,0))) return false;
// Assign sample bmp info
BITMAPINFOHEADER *sample = (BITMAPINFOHEADER*) pframe;
rFrameWdt = sample->biWidth;
rFrameHgt = sample->biHeight;
rFrameBitsPerPixel = sample->biBitCount;
rFramePitch = DWordAligned(rFrameWdt*rFrameBitsPerPixel/8);
return true;
}
void AVICloseGrab(PAVISTREAM *ppAviStream,
PGETFRAME *ppGetFrame)
{
if (ppGetFrame && *ppGetFrame)
{ AVIStreamGetFrameClose(*ppGetFrame); *ppGetFrame=NULL; }
if (ppAviStream && *ppAviStream)
{ AVIStreamRelease(*ppAviStream); *ppAviStream=NULL; }
}
// ----------------------------------------
CStdAVIFile::CStdAVIFile()
: pAVIFile(NULL), pStream(NULL), pGetFrame(NULL), pbmi(NULL), hOutDib(NULL), hBitmap(NULL), hDD(NULL), hDC(NULL), hWnd(NULL),
pAudioStream(NULL), pAudioData(NULL), iAudioBufferLength(0), pAudioInfo(NULL)
{
AVIFileInit();
}
CStdAVIFile::~CStdAVIFile()
{
Clear();
AVIFileExit();
}
void CStdAVIFile::Clear()
{
// free any stuff
CloseAudioStream();
if (hBitmap) { DeleteObject(hBitmap); hBitmap = NULL; }
if (hDD) { DrawDibClose(hDD); hDD = NULL; }
if (hDC) { ReleaseDC(hWnd, hDC); hDC = NULL; }
if (pGetFrame) { AVIStreamGetFrameClose(pGetFrame); pGetFrame=NULL; }
if (pStream) { AVIStreamRelease(pStream); pStream = NULL; }
if (pbmi) { delete [] pbmi; pbmi = NULL; }
if (pAVIFile) { AVIFileRelease(pAVIFile); pAVIFile = NULL; }
sFilename.Clear();
}
bool CStdAVIFile::OpenFile(const char *szFilename, HWND hWnd, int32_t iOutBitDepth)
{
// clear previous
Clear();
sFilename.Copy(szFilename);
// open the AVI file
if (AVIFileOpenW(&pAVIFile, GetWideChar(szFilename), OF_READ, NULL))
return false;
if (AVIFileGetStream(pAVIFile, &pStream, streamtypeVIDEO, 0))
return false;
// get stream information
AVIStreamInfo(pStream, &StreamInfo, sizeof(AVISTREAMINFO));
iWdt = StreamInfo.rcFrame.right-StreamInfo.rcFrame.left;
iHgt = StreamInfo.rcFrame.bottom-StreamInfo.rcFrame.top;
iFinalFrame = AVIStreamLength(pStream);
// some safety
if (iWdt<=0 || iHgt<=0 || iFinalFrame<=0) return false;
// calculate playback speed
iTimePerFrame = AVIStreamSampleToTime(pStream,iFinalFrame)/iFinalFrame;
// init buffer bitmap info
pbmi = (BITMAPINFO *) new BYTE[sizeof (BITMAPINFO) + 3*sizeof(RGBQUAD)];
ZeroMemory(pbmi, sizeof (BITMAPINFO) + 3*sizeof(RGBQUAD));
pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pbmi->bmiHeader.biPlanes = 1;
pbmi->bmiHeader.biBitCount = iOutBitDepth;
pbmi->bmiHeader.biWidth = iWdt;
pbmi->bmiHeader.biHeight = -iHgt;
pbmi->bmiHeader.biCompression = (iOutBitDepth == 16) ? BI_BITFIELDS : BI_RGB;
if (iOutBitDepth == 16)
{
*(DWORD*)(&(pbmi->bmiColors[2])) = 0x00f;
*(DWORD*)(&(pbmi->bmiColors[1])) = 0x0f0;
*(DWORD*)(&(pbmi->bmiColors[0])) = 0xf00;
}
hDC = CreateCompatibleDC(NULL);
if (!hDC) return false;
hDD = DrawDibOpen();
if (!hDD) return false;
hBitmap = CreateDIBSection(hDC, pbmi, DIB_RGB_COLORS, (void**)(&pFrameData), NULL, 0);
if (!hBitmap) return false;
SelectObject(hDC, hBitmap);
// create a GetFrame-object
pGetFrame=AVIStreamGetFrameOpen(pStream, NULL);
if (!pGetFrame) return false;
// done, success!
return true;
}
bool CStdAVIFile::GetFrameByTime(time_t iTime, int32_t *piFrame)
{
// safeties
if (iTime < 0) return false;
if (!piFrame || !iTimePerFrame) return false;
// get frame
int iFrame = *piFrame = int32_t((iTime + (iTimePerFrame/2)) / iTimePerFrame);
return iFrame < iFinalFrame;
}
bool CStdAVIFile::GrabFrame(int32_t iFrame, C4Surface *sfc) const
{
// safeties
if (!pGetFrame || !sfc) return false;
if (iFrame<0 || iFrame >= iFinalFrame) return false;
// grab desired frame
LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)AVIStreamGetFrame(pGetFrame, iFrame);
// calculate actual data position
BYTE *pImageData = (BYTE *)lpbi + lpbi->biSize + lpbi->biClrUsed*sizeof(RGBQUAD);
// draw into buffer bitmap
if (!DrawDibDraw (hDD, hDC, 0, 0, iWdt, iHgt, lpbi, pImageData, 0, 0, iWdt, iHgt, 0)) return false;
// copy from buffer bitmap into surface - assumes surface is created in the correct size!
if (!sfc->Lock()) return false;
if (!sfc->CopyBytes(pFrameData)) return false;
return !!sfc->Unlock();
}
bool CStdAVIFile::OpenAudioStream()
{
// close previous
CloseAudioStream();
// open new
if (!pAVIFile) return false;
if (AVIFileGetStream(pAVIFile, &pAudioStream, streamtypeAUDIO, 0))
return false;
// get audio stream format
if (AVIStreamReadFormat(pAudioStream, AVIStreamStart(pAudioStream), NULL, &iAudioInfoLength)) return false;
if (iAudioInfoLength<static_cast<LONG>(sizeof(WAVEFORMAT))) return false;
pAudioInfo = (WAVEFORMAT *) new BYTE[iAudioInfoLength];
if (AVIStreamReadFormat(pAudioStream, AVIStreamStart(pAudioStream), pAudioInfo, &iAudioInfoLength))
{ delete [] pAudioInfo; pAudioInfo=NULL; return false; }
// done!
return true;
}
BYTE *CStdAVIFile::GetAudioStreamData(size_t *piStreamLength)
{
// returning the complete audio stream at once here - not very efficient, but easy...
// get stream size
if (!pAudioInfo) return NULL;
if (AVIStreamRead(pAudioStream, 0, AVIStreamLength(pAudioStream), NULL, 0, &iAudioDataLength, NULL)) return NULL;
if (iAudioDataLength<=0) return NULL;
// make sure current audio data buffer is large enoiugh to hold the data
// preceding return data with the RIFF+waveformat structure here
uint32_t iHeaderLength = iAudioInfoLength + sizeof(FOURCC) * 4 + 3 * sizeof(uint32_t);
LONG iReturnDataLength = iAudioDataLength + iHeaderLength;
if (iAudioBufferLength < iReturnDataLength)
{
delete [] pAudioData;
pAudioData = new BYTE[iAudioBufferLength = iReturnDataLength];
// build wave file header
BYTE *pWrite = pAudioData;
*((FOURCC *)pWrite) = mmioFOURCC('R', 'I', 'F', 'F'); pWrite += sizeof(FOURCC);
*((uint32_t *)pWrite) = iReturnDataLength - sizeof(FOURCC) - sizeof(uint32_t); pWrite += sizeof(uint32_t);
*((FOURCC *)pWrite) = mmioFOURCC('W', 'A', 'V', 'E'); pWrite += sizeof(FOURCC);
*((FOURCC *)pWrite) = mmioFOURCC('f', 'm', 't', ' '); pWrite += sizeof(FOURCC);
*((uint32_t *)pWrite) = iAudioInfoLength; pWrite += sizeof(uint32_t);
memcpy(pWrite, pAudioInfo, iAudioInfoLength); pWrite += iAudioInfoLength;
*((FOURCC *)pWrite) = mmioFOURCC('d', 'a', 't', 'a'); pWrite += sizeof(FOURCC);
*((uint32_t *)pWrite) = iAudioDataLength;
}
// get it
if (AVIStreamRead(pAudioStream, 0, AVIStreamLength(pAudioStream), pAudioData+iHeaderLength, iAudioDataLength, NULL, NULL)) return NULL;
// got the data successfully!
*piStreamLength = iReturnDataLength;
return pAudioData;
}
void CStdAVIFile::CloseAudioStream()
{
if (pAudioStream) { AVIStreamRelease(pAudioStream); pAudioStream = NULL; }
if (pAudioData) { delete [] pAudioData; pAudioData = NULL; }
if (pAudioInfo) { delete [] pAudioInfo; pAudioInfo = NULL; }
iAudioBufferLength = 0;
}
#else //HAVE_VFW32
#include <StdVideo.h>
#include <C4Surface.h>
bool AVIOpenOutput(const char *, PAVIFILE *, PAVISTREAM *, int, int) { return false; }
bool AVICloseOutput(PAVIFILE *, PAVISTREAM *) { return true; }
bool AVIPutFrame(PAVISTREAM, long, void *, long, void *, long) { return false; }
bool AVIOpenGrab(const char *, PAVISTREAM *, PGETFRAME *, int &, int &, int &, int &, int &) { return false; }
void AVICloseGrab(PAVISTREAM *, PGETFRAME *) { }
CStdAVIFile::CStdAVIFile() { }
CStdAVIFile::~CStdAVIFile() { }
void CStdAVIFile::Clear() { }
bool CStdAVIFile::OpenFile(const char *, HWND, int32_t) { return false; }
bool CStdAVIFile::GetFrameByTime(time_t, int32_t *) { return false; }
bool CStdAVIFile::GrabFrame(int32_t, C4Surface *) const { return false; }
bool CStdAVIFile::OpenAudioStream() { return false; }
BYTE *CStdAVIFile::GetAudioStreamData(size_t *) { return NULL; }
void CStdAVIFile::CloseAudioStream() { }
#endif // HAVE_VFW32
#endif // _WIN32

View File

@ -1,112 +0,0 @@
/*
* OpenClonk, http://www.openclonk.org
*
* Copyright (c) 1998-2000, Matthes Bender
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
* Copyright (c) 2013, The OpenClonk Team and contributors
*
* Distributed under the terms of the ISC license; see accompanying file
* "COPYING" for details.
*
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
* See accompanying file "TRADEMARK" for details.
*
* To redistribute this file separately, substitute the full license texts
* for the above references.
*/
/* Some functions to help with loading and saving AVI files using Video for Windows */
#ifndef INC_STDVIDEO
#define INC_STDVIDEO
#ifdef _WIN32
#pragma once
#include <C4windowswrapper.h> // some vfw.h versions do not compile without this
#undef MK_ALT
#include <mmsystem.h>
#include <vfw.h>
#include <io.h>
#include "StdBuf.h"
bool AVIOpenGrab(const char *szFilename,
PAVISTREAM *ppAviStream,
PGETFRAME *ppGetFrame,
int &rAviLength, int &rFrameWdt, int &rFrameHgt,
int &rFrameBitsPerPixel, int &rFramePitch);
void AVICloseGrab(PAVISTREAM *ppAviStream,
PGETFRAME *ppGetFrame);
bool AVIOpenOutput(const char *szFilename,
PAVIFILE *ppAviFile,
PAVISTREAM *ppAviStream,
int iWidth, int iHeight);
bool AVICloseOutput(PAVIFILE *ppAviFile,
PAVISTREAM *ppAviStream);
bool AVIPutFrame(PAVISTREAM pAviStream,
long lFrame,
void *lpInfo, long lInfoSize,
void *lpData, long lDataSize);
// AVI file reading class
class CStdAVIFile
{
private:
// file data
StdStrBuf sFilename;
PAVIFILE pAVIFile;
// video data
AVISTREAMINFO StreamInfo;
PAVISTREAM pStream;
PGETFRAME pGetFrame;
// video processing helpers
BITMAPINFO *pbmi;
HDRAWDIB hOutDib;
HBITMAP hBitmap;
HDRAWDIB hDD;
HDC hDC;
BYTE *pFrameData;
HWND hWnd;
// audio data
PAVISTREAM pAudioStream;
BYTE *pAudioData;
LONG iAudioDataLength, iAudioBufferLength;
WAVEFORMAT *pAudioInfo;
LONG iAudioInfoLength;
// frame data
int32_t iFinalFrame, iWdt, iHgt;
time_t iTimePerFrame; // [ms/frame]
public:
CStdAVIFile();
~CStdAVIFile();
void Clear();
bool OpenFile(const char *szFilename, HWND hWnd, int32_t iOutBitDepth);
int32_t GetWdt() const { return iWdt; }
int32_t GetHgt() const { return iHgt; }
// get desired frame from time offset to video start - return false if past video length
bool GetFrameByTime(time_t iTime, int32_t *piFrame);
// dump RGBa-data for specified frame
bool GrabFrame(int32_t iFrame, class C4Surface *sfc) const;
// getting audio data
bool OpenAudioStream();
BYTE *GetAudioStreamData(size_t *piStreamLength);
void CloseAudioStream();
};
#endif //_WIN32
#endif //INC_STDVIDEO