]> git.sesse.net Git - casparcg/commitdiff
Moved internal trunk to public trunk.
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Thu, 7 Oct 2010 16:07:18 +0000 (16:07 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Thu, 7 Oct 2010 16:07:18 +0000 (16:07 +0000)
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/trunk@155 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

227 files changed:
CG.fth.17 [new file with mode: 0644]
casparcg.sln [new file with mode: 0644]
cg.fth.18 [new file with mode: 0644]
server setup/Server Setup.vdproj [new file with mode: 0644]
server/Application.cpp [new file with mode: 0644]
server/Application.h [new file with mode: 0644]
server/CLK/CLKCommand.cpp [new file with mode: 0644]
server/CLK/CLKCommand.h [new file with mode: 0644]
server/CLK/CLKProtocolStrategy.cpp [new file with mode: 0644]
server/CLK/CLKProtocolStrategy.h [new file with mode: 0644]
server/Channel.cpp [new file with mode: 0644]
server/Channel.h [new file with mode: 0644]
server/Controller.h [new file with mode: 0644]
server/FileInfo.h [new file with mode: 0644]
server/Main.cpp [new file with mode: 0644]
server/MediaController.h [new file with mode: 0644]
server/MediaManager.h [new file with mode: 0644]
server/MediaProducer.h [new file with mode: 0644]
server/MediaProducerInfo.h [new file with mode: 0644]
server/Monitor.cpp [new file with mode: 0644]
server/Monitor.h [new file with mode: 0644]
server/PlaybackControl.h [new file with mode: 0644]
server/Resource.h [new file with mode: 0644]
server/Server.vcproj [new file with mode: 0644]
server/Server.vcxproj [new file with mode: 0644]
server/Server.vcxproj.filters [new file with mode: 0644]
server/StdAfx.cpp [new file with mode: 0644]
server/StdAfx.h [new file with mode: 0644]
server/TransitionInfo.h [new file with mode: 0644]
server/VersionNo.h [new file with mode: 0644]
server/VideoConsumer.h [new file with mode: 0644]
server/Window.cpp [new file with mode: 0644]
server/Window.h [new file with mode: 0644]
server/amcp/AMCPCommand.h [new file with mode: 0644]
server/amcp/AMCPCommandQueue.cpp [new file with mode: 0644]
server/amcp/AMCPCommandQueue.h [new file with mode: 0644]
server/amcp/AMCPCommandsImpl.cpp [new file with mode: 0644]
server/amcp/AMCPCommandsImpl.h [new file with mode: 0644]
server/amcp/AMCPProtocolStrategy.cpp [new file with mode: 0644]
server/amcp/AMCPProtocolStrategy.h [new file with mode: 0644]
server/audio/AudioManager.h [new file with mode: 0644]
server/audio/DirectSoundManager.cpp [new file with mode: 0644]
server/audio/DirectSoundManager.h [new file with mode: 0644]
server/cg/CGControl.h [new file with mode: 0644]
server/cg/FlashCGManager.cpp [new file with mode: 0644]
server/cg/FlashCGManager.h [new file with mode: 0644]
server/cg/FlashCGProxy.cpp [new file with mode: 0644]
server/cg/FlashCGProxy.h [new file with mode: 0644]
server/cii/CIICommand.h [new file with mode: 0644]
server/cii/CIICommandsImpl.cpp [new file with mode: 0644]
server/cii/CIICommandsImpl.h [new file with mode: 0644]
server/cii/CIIProtocolStrategy.cpp [new file with mode: 0644]
server/cii/CIIProtocolStrategy.h [new file with mode: 0644]
server/consumers/Audio/AudioConsumer.cpp [new file with mode: 0644]
server/consumers/Audio/AudioConsumer.h [new file with mode: 0644]
server/consumers/GDI/GDIVideoConsumer.cpp [new file with mode: 0644]
server/consumers/GDI/GDIVideoConsumer.h [new file with mode: 0644]
server/consumers/OGL/OGLVideoConsumer.cpp [new file with mode: 0644]
server/consumers/OGL/OGLVideoConsumer.h [new file with mode: 0644]
server/consumers/bluefish/BlueFishVideoConsumer.cpp [new file with mode: 0644]
server/consumers/bluefish/BlueFishVideoConsumer.h [new file with mode: 0644]
server/consumers/bluefish/BluefishException.h [new file with mode: 0644]
server/consumers/bluefish/BluefishFrameManager.cpp [new file with mode: 0644]
server/consumers/bluefish/BluefishFrameManager.h [new file with mode: 0644]
server/consumers/bluefish/BluefishPlaybackStrategy.cpp [new file with mode: 0644]
server/consumers/bluefish/BluefishPlaybackStrategy.h [new file with mode: 0644]
server/consumers/decklink/DeckLinkAPI.idl [new file with mode: 0644]
server/consumers/decklink/DeckLinkAPI_h.h [new file with mode: 0644]
server/consumers/decklink/DeckLinkAPI_i.c [new file with mode: 0644]
server/consumers/decklink/DeckLinkAPI_v7_1.idl [new file with mode: 0644]
server/consumers/decklink/DeckLinkAPI_v7_3.idl [new file with mode: 0644]
server/consumers/decklink/DecklinkVideoConsumer.cpp [new file with mode: 0644]
server/consumers/decklink/DecklinkVideoConsumer.h [new file with mode: 0644]
server/frame/BitmapFrame.cpp [new file with mode: 0644]
server/frame/BitmapFrame.h [new file with mode: 0644]
server/frame/BitmapFrameAdapter.cpp [new file with mode: 0644]
server/frame/BitmapFrameAdapter.h [new file with mode: 0644]
server/frame/BitmapFrameManager.cpp [new file with mode: 0644]
server/frame/BitmapFrameManager.h [new file with mode: 0644]
server/frame/BitmapFrameManagerAdapter.cpp [new file with mode: 0644]
server/frame/BitmapFrameManagerAdapter.h [new file with mode: 0644]
server/frame/ClipInfo.h [new file with mode: 0644]
server/frame/Frame.cpp [new file with mode: 0644]
server/frame/Frame.h [new file with mode: 0644]
server/frame/FrameManager.h [new file with mode: 0644]
server/frame/FrameMediaController.h [new file with mode: 0644]
server/frame/FramePlaybackControl.cpp [new file with mode: 0644]
server/frame/FramePlaybackControl.h [new file with mode: 0644]
server/frame/FramePlaybackStrategy.h [new file with mode: 0644]
server/frame/SystemFrame.cpp [new file with mode: 0644]
server/frame/SystemFrame.h [new file with mode: 0644]
server/frame/SystemFrameManager.cpp [new file with mode: 0644]
server/frame/SystemFrameManager.h [new file with mode: 0644]
server/frame/buffers/FrameBuffer.h [new file with mode: 0644]
server/frame/buffers/MotionFrameBuffer.cpp [new file with mode: 0644]
server/frame/buffers/MotionFrameBuffer.h [new file with mode: 0644]
server/frame/buffers/StaticFrameBuffer.cpp [new file with mode: 0644]
server/frame/buffers/StaticFrameBuffer.h [new file with mode: 0644]
server/io/AsyncEventServer.cpp [new file with mode: 0644]
server/io/AsyncEventServer.h [new file with mode: 0644]
server/io/ClientInfo.h [new file with mode: 0644]
server/io/ProtocolStrategy.h [new file with mode: 0644]
server/io/SerialPort.cpp [new file with mode: 0644]
server/io/SerialPort.h [new file with mode: 0644]
server/io/SocketInfo.cpp [new file with mode: 0644]
server/io/SocketInfo.h [new file with mode: 0644]
server/producers/color/ColorManager.cpp [new file with mode: 0644]
server/producers/color/ColorManager.h [new file with mode: 0644]
server/producers/composites/FrameCompositeProducer.cpp [new file with mode: 0644]
server/producers/composites/FrameCompositeProducer.h [new file with mode: 0644]
server/producers/composites/TransitionProducer.cpp [new file with mode: 0644]
server/producers/composites/TransitionProducer.h [new file with mode: 0644]
server/producers/ffmpeg/FFMPEGException.h [new file with mode: 0644]
server/producers/ffmpeg/FFMPEGFrameOutput.cpp [new file with mode: 0644]
server/producers/ffmpeg/FFMPEGFrameOutput.h [new file with mode: 0644]
server/producers/ffmpeg/FFMPEGInput.cpp [new file with mode: 0644]
server/producers/ffmpeg/FFMPEGInput.h [new file with mode: 0644]
server/producers/ffmpeg/FFMPEGOutput.cpp [new file with mode: 0644]
server/producers/ffmpeg/FFMPEGOutput.h [new file with mode: 0644]
server/producers/ffmpeg/FFMPEGPacket.cpp [new file with mode: 0644]
server/producers/ffmpeg/FFMPEGPacket.h [new file with mode: 0644]
server/producers/ffmpeg/FFMPEGProducer.cpp [new file with mode: 0644]
server/producers/ffmpeg/FFMPEGProducer.h [new file with mode: 0644]
server/producers/ffmpeg/FFmpegManager.cpp [new file with mode: 0644]
server/producers/ffmpeg/audio/FFMPEGAudioDecoder.cpp [new file with mode: 0644]
server/producers/ffmpeg/audio/FFMPEGAudioDecoder.h [new file with mode: 0644]
server/producers/ffmpeg/ffmpegmanager.h [new file with mode: 0644]
server/producers/ffmpeg/video/FFMPEGVideoDecoder.cpp [new file with mode: 0644]
server/producers/ffmpeg/video/FFMPEGVideoDecoder.h [new file with mode: 0644]
server/producers/ffmpeg/video/FFMPEGVideoDeinterlacer.cpp [new file with mode: 0644]
server/producers/ffmpeg/video/FFMPEGVideoDeinterlacer.h [new file with mode: 0644]
server/producers/ffmpeg/video/FFMPEGVideoScaler.cpp [new file with mode: 0644]
server/producers/ffmpeg/video/FFMPEGVideoScaler.h [new file with mode: 0644]
server/producers/ffmpeg/video/FFMPEGVideoScaler2.cpp [new file with mode: 0644]
server/producers/ffmpeg/video/FFMPEGVideoScaler2.h [new file with mode: 0644]
server/producers/flash/CTManager.cpp [new file with mode: 0644]
server/producers/flash/CTManager.h [new file with mode: 0644]
server/producers/flash/Flash9e.IDL [new file with mode: 0644]
server/producers/flash/Flash9e_i.c [new file with mode: 0644]
server/producers/flash/FlashAxContainer.cpp [new file with mode: 0644]
server/producers/flash/FlashAxContainer.h [new file with mode: 0644]
server/producers/flash/FlashCommand.cpp [new file with mode: 0644]
server/producers/flash/FlashCommand.h [new file with mode: 0644]
server/producers/flash/FlashCommandQueue.cpp [new file with mode: 0644]
server/producers/flash/FlashCommandQueue.h [new file with mode: 0644]
server/producers/flash/FlashManager.cpp [new file with mode: 0644]
server/producers/flash/FlashManager.h [new file with mode: 0644]
server/producers/flash/FlashProducer.cpp [new file with mode: 0644]
server/producers/flash/FlashProducer.h [new file with mode: 0644]
server/producers/flash/TimerHelper.h [new file with mode: 0644]
server/producers/flash/axflash.h [new file with mode: 0644]
server/producers/targa/TargaManager.cpp [new file with mode: 0644]
server/producers/targa/TargaManager.h [new file with mode: 0644]
server/producers/targascroll/TargaScrollManager.cpp [new file with mode: 0644]
server/producers/targascroll/TargaScrollManager.h [new file with mode: 0644]
server/producers/targascroll/TargaScrollProducer.cpp [new file with mode: 0644]
server/producers/targascroll/TargaScrollProducer.h [new file with mode: 0644]
server/resources/Server.rc [new file with mode: 0644]
server/resources/icon2.ico [new file with mode: 0644]
server/resources/server.rc2 [new file with mode: 0644]
server/string_convert.h [new file with mode: 0644]
server/utils/Allocator.h [new file with mode: 0644]
server/utils/BitmapHolder.cpp [new file with mode: 0644]
server/utils/BitmapHolder.h [new file with mode: 0644]
server/utils/CPUID.cpp [new file with mode: 0644]
server/utils/CPUID.hpp [new file with mode: 0644]
server/utils/CommandQueue.h [new file with mode: 0644]
server/utils/CritSectLock.h [new file with mode: 0644]
server/utils/DCWrapper.cpp [new file with mode: 0644]
server/utils/DCWrapper.h [new file with mode: 0644]
server/utils/DataBuffer.h [new file with mode: 0644]
server/utils/Event.h [new file with mode: 0644]
server/utils/FileExists.cpp [new file with mode: 0644]
server/utils/FileExists.h [new file with mode: 0644]
server/utils/FileInputStream.cpp [new file with mode: 0644]
server/utils/FileInputStream.h [new file with mode: 0644]
server/utils/FileOutputStream.cpp [new file with mode: 0644]
server/utils/FileOutputStream.h [new file with mode: 0644]
server/utils/FindWrapper.cpp [new file with mode: 0644]
server/utils/FindWrapper.h [new file with mode: 0644]
server/utils/ID.cpp [new file with mode: 0644]
server/utils/ID.h [new file with mode: 0644]
server/utils/InputStream.h [new file with mode: 0644]
server/utils/Lockable.h [new file with mode: 0644]
server/utils/LogException.cpp [new file with mode: 0644]
server/utils/LogException.h [new file with mode: 0644]
server/utils/LogLevel.h [new file with mode: 0644]
server/utils/LogStream.cpp [new file with mode: 0644]
server/utils/LogStream.h [new file with mode: 0644]
server/utils/Logger.cpp [new file with mode: 0644]
server/utils/Logger.h [new file with mode: 0644]
server/utils/Noncopyable.hpp [new file with mode: 0644]
server/utils/ObjectPool.h [new file with mode: 0644]
server/utils/OutputStream.h [new file with mode: 0644]
server/utils/PixmapData.h [new file with mode: 0644]
server/utils/Process.cpp [new file with mode: 0644]
server/utils/Process.h [new file with mode: 0644]
server/utils/Semaphore.cpp [new file with mode: 0644]
server/utils/Semaphore.h [new file with mode: 0644]
server/utils/TaskQueue.h [new file with mode: 0644]
server/utils/Thread.cpp [new file with mode: 0644]
server/utils/Thread.h [new file with mode: 0644]
server/utils/Types.hpp [new file with mode: 0644]
server/utils/UnhandledException.h [new file with mode: 0644]
server/utils/Win32Exception.cpp [new file with mode: 0644]
server/utils/Win32Exception.h [new file with mode: 0644]
server/utils/event.cpp [new file with mode: 0644]
server/utils/functiontask.hpp [new file with mode: 0644]
server/utils/image/Clear.cpp [new file with mode: 0644]
server/utils/image/Clear.hpp [new file with mode: 0644]
server/utils/image/Copy.cpp [new file with mode: 0644]
server/utils/image/Copy.hpp [new file with mode: 0644]
server/utils/image/CopyField.cpp [new file with mode: 0644]
server/utils/image/CopyField.hpp [new file with mode: 0644]
server/utils/image/Image.cpp [new file with mode: 0644]
server/utils/image/Image.hpp [new file with mode: 0644]
server/utils/image/Lerp.cpp [new file with mode: 0644]
server/utils/image/Lerp.hpp [new file with mode: 0644]
server/utils/image/Over.cpp [new file with mode: 0644]
server/utils/image/Over.hpp [new file with mode: 0644]
server/utils/image/Premultiply.cpp [new file with mode: 0644]
server/utils/image/Premultiply.hpp [new file with mode: 0644]
server/utils/image/Shuffle.cpp [new file with mode: 0644]
server/utils/image/Shuffle.hpp [new file with mode: 0644]
server/utils/object_pool.h [new file with mode: 0644]
server/utils/runnable.h [new file with mode: 0644]
server/utils/scope_exit.h [new file with mode: 0644]

diff --git a/CG.fth.17 b/CG.fth.17
new file mode 100644 (file)
index 0000000..b1c4751
Binary files /dev/null and b/CG.fth.17 differ
diff --git a/casparcg.sln b/casparcg.sln
new file mode 100644 (file)
index 0000000..9267fc4
--- /dev/null
@@ -0,0 +1,27 @@
+\r
+Microsoft Visual Studio Solution File, Format Version 11.00\r
+# Visual Studio 2010\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Server", "server\Server.vcxproj", "{79388C20-6499-4BF6-B8B9-D8C33D7D4DDD}"\r
+EndProject\r
+Global\r
+       GlobalSection(SubversionScc) = preSolution\r
+               Svn-Managed = True\r
+               Manager = AnkhSVN - Subversion Support for Visual Studio\r
+       EndGlobalSection\r
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+               Debug|Win32 = Debug|Win32\r
+               no bluefish|Win32 = no bluefish|Win32\r
+               Release|Win32 = Release|Win32\r
+       EndGlobalSection\r
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+               {79388C20-6499-4BF6-B8B9-D8C33D7D4DDD}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {79388C20-6499-4BF6-B8B9-D8C33D7D4DDD}.Debug|Win32.Build.0 = Debug|Win32\r
+               {79388C20-6499-4BF6-B8B9-D8C33D7D4DDD}.no bluefish|Win32.ActiveCfg = no bluefish|Win32\r
+               {79388C20-6499-4BF6-B8B9-D8C33D7D4DDD}.no bluefish|Win32.Build.0 = no bluefish|Win32\r
+               {79388C20-6499-4BF6-B8B9-D8C33D7D4DDD}.Release|Win32.ActiveCfg = Release|Win32\r
+               {79388C20-6499-4BF6-B8B9-D8C33D7D4DDD}.Release|Win32.Build.0 = Release|Win32\r
+       EndGlobalSection\r
+       GlobalSection(SolutionProperties) = preSolution\r
+               HideSolutionNode = FALSE\r
+       EndGlobalSection\r
+EndGlobal\r
diff --git a/cg.fth.18 b/cg.fth.18
new file mode 100644 (file)
index 0000000..5795f76
Binary files /dev/null and b/cg.fth.18 differ
diff --git a/server setup/Server Setup.vdproj b/server setup/Server Setup.vdproj
new file mode 100644 (file)
index 0000000..b04b676
--- /dev/null
@@ -0,0 +1,1449 @@
+"DeployProject"\r
+{\r
+"VSVersion" = "3:800"\r
+"ProjectType" = "8:{978C614F-708E-4E1A-B201-565925725DBA}"\r
+"IsWebType" = "8:FALSE"\r
+"ProjectName" = "8:Server Setup"\r
+"LanguageId" = "3:1033"\r
+"CodePage" = "3:1252"\r
+"UILanguageId" = "3:1033"\r
+"SccProjectName" = "8:"\r
+"SccLocalPath" = "8:"\r
+"SccAuxPath" = "8:"\r
+"SccProvider" = "8:"\r
+    "Hierarchy"\r
+    {\r
+        "Entry"\r
+        {\r
+        "MsmKey" = "8:_39085F3B5FC14FFCBF1CD62F4551EF8C"\r
+        "OwnerKey" = "8:_UNDEFINED"\r
+        "MsmSig" = "8:_UNDEFINED"\r
+        }\r
+        "Entry"\r
+        {\r
+        "MsmKey" = "8:_401120F0A3E94D9F9DA6BD5474650E27"\r
+        "OwnerKey" = "8:_UNDEFINED"\r
+        "MsmSig" = "8:_UNDEFINED"\r
+        }\r
+        "Entry"\r
+        {\r
+        "MsmKey" = "8:_59277C5FE6E94B9F9C971A1C16CFB37E"\r
+        "OwnerKey" = "8:_AAD62042DDED4BE49BD147A2A78F763D"\r
+        "MsmSig" = "8:_UNDEFINED"\r
+        }\r
+        "Entry"\r
+        {\r
+        "MsmKey" = "8:_6175789D1DFAD674AC2E3DC03D75F6B8"\r
+        "OwnerKey" = "8:_401120F0A3E94D9F9DA6BD5474650E27"\r
+        "MsmSig" = "8:_UNDEFINED"\r
+        }\r
+        "Entry"\r
+        {\r
+        "MsmKey" = "8:_6175789D1DFAD674AC2E3DC03D75F6B8"\r
+        "OwnerKey" = "8:_B0373B7651594DCCA4AA16F49FF96652"\r
+        "MsmSig" = "8:_UNDEFINED"\r
+        }\r
+        "Entry"\r
+        {\r
+        "MsmKey" = "8:_66851612066C8C647ECEDCABC8C2389C"\r
+        "OwnerKey" = "8:_B0373B7651594DCCA4AA16F49FF96652"\r
+        "MsmSig" = "8:_UNDEFINED"\r
+        }\r
+        "Entry"\r
+        {\r
+        "MsmKey" = "8:_80C0E135DDC14FFEA2C21797CCF7C934"\r
+        "OwnerKey" = "8:_UNDEFINED"\r
+        "MsmSig" = "8:_UNDEFINED"\r
+        }\r
+        "Entry"\r
+        {\r
+        "MsmKey" = "8:_9589226DB30A7514D00BBD1A04CF473C"\r
+        "OwnerKey" = "8:_401120F0A3E94D9F9DA6BD5474650E27"\r
+        "MsmSig" = "8:_UNDEFINED"\r
+        }\r
+        "Entry"\r
+        {\r
+        "MsmKey" = "8:_9589226DB30A7514D00BBD1A04CF473C"\r
+        "OwnerKey" = "8:_B0373B7651594DCCA4AA16F49FF96652"\r
+        "MsmSig" = "8:_UNDEFINED"\r
+        }\r
+        "Entry"\r
+        {\r
+        "MsmKey" = "8:_970CC65F3EB54C2CBE6AE94AA7BE55A3"\r
+        "OwnerKey" = "8:_UNDEFINED"\r
+        "MsmSig" = "8:_UNDEFINED"\r
+        }\r
+        "Entry"\r
+        {\r
+        "MsmKey" = "8:_AAD62042DDED4BE49BD147A2A78F763D"\r
+        "OwnerKey" = "8:_401120F0A3E94D9F9DA6BD5474650E27"\r
+        "MsmSig" = "8:_UNDEFINED"\r
+        }\r
+        "Entry"\r
+        {\r
+        "MsmKey" = "8:_AAD62042DDED4BE49BD147A2A78F763D"\r
+        "OwnerKey" = "8:_B0373B7651594DCCA4AA16F49FF96652"\r
+        "MsmSig" = "8:_UNDEFINED"\r
+        }\r
+        "Entry"\r
+        {\r
+        "MsmKey" = "8:_B0373B7651594DCCA4AA16F49FF96652"\r
+        "OwnerKey" = "8:_UNDEFINED"\r
+        "MsmSig" = "8:_UNDEFINED"\r
+        }\r
+        "Entry"\r
+        {\r
+        "MsmKey" = "8:_CFE2758D601F426DB9A2B44160093BF7"\r
+        "OwnerKey" = "8:_UNDEFINED"\r
+        "MsmSig" = "8:_UNDEFINED"\r
+        }\r
+        "Entry"\r
+        {\r
+        "MsmKey" = "8:_E1038D2A23C24E858A4A869F00E9F274"\r
+        "OwnerKey" = "8:_UNDEFINED"\r
+        "MsmSig" = "8:_UNDEFINED"\r
+        }\r
+        "Entry"\r
+        {\r
+        "MsmKey" = "8:_E1C7F01A7300440C98234B68CF89520B"\r
+        "OwnerKey" = "8:_401120F0A3E94D9F9DA6BD5474650E27"\r
+        "MsmSig" = "8:_UNDEFINED"\r
+        }\r
+        "Entry"\r
+        {\r
+        "MsmKey" = "8:_E1C7F01A7300440C98234B68CF89520B"\r
+        "OwnerKey" = "8:_B0373B7651594DCCA4AA16F49FF96652"\r
+        "MsmSig" = "8:_UNDEFINED"\r
+        }\r
+        "Entry"\r
+        {\r
+        "MsmKey" = "8:_ECA4D29D357B412598E1AA58F1883939"\r
+        "OwnerKey" = "8:_UNDEFINED"\r
+        "MsmSig" = "8:_UNDEFINED"\r
+        }\r
+    }\r
+    "Configurations"\r
+    {\r
+        "Debug"\r
+        {\r
+        "DisplayName" = "8:Debug"\r
+        "IsDebugOnly" = "11:TRUE"\r
+        "IsReleaseOnly" = "11:FALSE"\r
+        "OutputFilename" = "8:Debug\\Server Setup.msi"\r
+        "PackageFilesAs" = "3:2"\r
+        "PackageFileSize" = "3:-2147483648"\r
+        "CabType" = "3:1"\r
+        "Compression" = "3:2"\r
+        "SignOutput" = "11:FALSE"\r
+        "CertificateFile" = "8:"\r
+        "PrivateKeyFile" = "8:"\r
+        "TimeStampServer" = "8:"\r
+        "InstallerBootstrapper" = "3:2"\r
+            "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}"\r
+            {\r
+            "Enabled" = "11:TRUE"\r
+            "PromptEnabled" = "11:TRUE"\r
+            "PrerequisitesLocation" = "2:1"\r
+            "Url" = "8:"\r
+            "ComponentsUrl" = "8:"\r
+                "Items"\r
+                {\r
+                    "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:Microsoft.Net.Framework.3.5.SP1"\r
+                    {\r
+                    "Name" = "8:.NET Framework 3.5 SP1"\r
+                    "ProductCode" = "8:Microsoft.Net.Framework.3.5.SP1"\r
+                    }\r
+                    "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:Microsoft.Windows.Installer.3.1"\r
+                    {\r
+                    "Name" = "8:Windows Installer 3.1"\r
+                    "ProductCode" = "8:Microsoft.Windows.Installer.3.1"\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        "FFMPEG 0.5"\r
+        {\r
+        "DisplayName" = "8:FFMPEG 0.5"\r
+        "IsDebugOnly" = "11:FALSE"\r
+        "IsReleaseOnly" = "11:FALSE"\r
+        "OutputFilename" = "8:FFMPEG 0.5\\Server Setup.msi"\r
+        "PackageFilesAs" = "3:2"\r
+        "PackageFileSize" = "3:-2147483648"\r
+        "CabType" = "3:1"\r
+        "Compression" = "3:2"\r
+        "SignOutput" = "11:FALSE"\r
+        "CertificateFile" = "8:"\r
+        "PrivateKeyFile" = "8:"\r
+        "TimeStampServer" = "8:"\r
+        "InstallerBootstrapper" = "3:2"\r
+            "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}"\r
+            {\r
+            "Enabled" = "11:TRUE"\r
+            "PromptEnabled" = "11:TRUE"\r
+            "PrerequisitesLocation" = "2:1"\r
+            "Url" = "8:"\r
+            "ComponentsUrl" = "8:"\r
+                "Items"\r
+                {\r
+                    "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:Microsoft.Net.Framework.3.5.SP1"\r
+                    {\r
+                    "Name" = "8:.NET Framework 3.5 SP1"\r
+                    "ProductCode" = "8:Microsoft.Net.Framework.3.5.SP1"\r
+                    }\r
+                    "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:Microsoft.Windows.Installer.3.1"\r
+                    {\r
+                    "Name" = "8:Windows Installer 3.1"\r
+                    "ProductCode" = "8:Microsoft.Windows.Installer.3.1"\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        "Release"\r
+        {\r
+        "DisplayName" = "8:Release"\r
+        "IsDebugOnly" = "11:FALSE"\r
+        "IsReleaseOnly" = "11:TRUE"\r
+        "OutputFilename" = "8:Release\\Server Setup.msi"\r
+        "PackageFilesAs" = "3:2"\r
+        "PackageFileSize" = "3:-2147483648"\r
+        "CabType" = "3:1"\r
+        "Compression" = "3:2"\r
+        "SignOutput" = "11:FALSE"\r
+        "CertificateFile" = "8:"\r
+        "PrivateKeyFile" = "8:"\r
+        "TimeStampServer" = "8:"\r
+        "InstallerBootstrapper" = "3:2"\r
+            "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}"\r
+            {\r
+            "Enabled" = "11:TRUE"\r
+            "PromptEnabled" = "11:TRUE"\r
+            "PrerequisitesLocation" = "2:1"\r
+            "Url" = "8:"\r
+            "ComponentsUrl" = "8:"\r
+                "Items"\r
+                {\r
+                    "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:Microsoft.Visual.C++.9.0.x86"\r
+                    {\r
+                    "Name" = "8:Visual C++ Runtime Libraries (x86)"\r
+                    "ProductCode" = "8:Microsoft.Visual.C++.9.0.x86"\r
+                    }\r
+                    "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:Microsoft.Windows.Installer.3.1"\r
+                    {\r
+                    "Name" = "8:Windows Installer 3.1"\r
+                    "ProductCode" = "8:Microsoft.Windows.Installer.3.1"\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        "WO Bluefish"\r
+        {\r
+        "DisplayName" = "8:WO Bluefish"\r
+        "IsDebugOnly" = "11:FALSE"\r
+        "IsReleaseOnly" = "11:FALSE"\r
+        "OutputFilename" = "8:WO Bluefish\\Server Setup.msi"\r
+        "PackageFilesAs" = "3:2"\r
+        "PackageFileSize" = "3:-2147483648"\r
+        "CabType" = "3:1"\r
+        "Compression" = "3:2"\r
+        "SignOutput" = "11:FALSE"\r
+        "CertificateFile" = "8:"\r
+        "PrivateKeyFile" = "8:"\r
+        "TimeStampServer" = "8:"\r
+        "InstallerBootstrapper" = "3:2"\r
+            "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}"\r
+            {\r
+            "Enabled" = "11:FALSE"\r
+            "PromptEnabled" = "11:TRUE"\r
+            "PrerequisitesLocation" = "2:1"\r
+            "Url" = "8:"\r
+            "ComponentsUrl" = "8:"\r
+                "Items"\r
+                {\r
+                    "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:Microsoft.Windows.Installer.3.1"\r
+                    {\r
+                    "Name" = "8:Windows Installer 3.1"\r
+                    "ProductCode" = "8:Microsoft.Windows.Installer.3.1"\r
+                    }\r
+                }\r
+            }\r
+        }\r
+    }\r
+    "Deployable"\r
+    {\r
+        "CustomAction"\r
+        {\r
+        }\r
+        "DefaultFeature"\r
+        {\r
+        "Name" = "8:DefaultFeature"\r
+        "Title" = "8:"\r
+        "Description" = "8:"\r
+        }\r
+        "ExternalPersistence"\r
+        {\r
+            "LaunchCondition"\r
+            {\r
+                "{A06ECF26-33A3-4562-8140-9B0E340D4F24}:_BEBF6479367149C5BB998F4E30F8287E"\r
+                {\r
+                "Name" = "8:.NET Framework"\r
+                "Message" = "8:[VSDNETMSG]"\r
+                "Version" = "8:3.5.30729"\r
+                "AllowLaterVersions" = "11:FALSE"\r
+                "InstallUrl" = "8:http://go.microsoft.com/fwlink/?LinkId=76617"\r
+                }\r
+            }\r
+        }\r
+        "File"\r
+        {\r
+            "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_39085F3B5FC14FFCBF1CD62F4551EF8C"\r
+            {\r
+            "SourcePath" = "8:..\\server\\build\\avutil-49.dll"\r
+            "TargetName" = "8:avutil-49.dll"\r
+            "Tag" = "8:"\r
+            "Folder" = "8:_9375E488732B409C8187CC9603423443"\r
+            "Condition" = "8:"\r
+            "Transitive" = "11:FALSE"\r
+            "Vital" = "11:TRUE"\r
+            "ReadOnly" = "11:FALSE"\r
+            "Hidden" = "11:FALSE"\r
+            "System" = "11:FALSE"\r
+            "Permanent" = "11:FALSE"\r
+            "SharedLegacy" = "11:FALSE"\r
+            "PackageAs" = "3:1"\r
+            "Register" = "3:1"\r
+            "Exclude" = "11:FALSE"\r
+            "IsDependency" = "11:FALSE"\r
+            "IsolateTo" = "8:"\r
+            }\r
+            "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_6175789D1DFAD674AC2E3DC03D75F6B8"\r
+            {\r
+            "SourcePath" = "8:tbb.dll"\r
+            "TargetName" = "8:tbb.dll"\r
+            "Tag" = "8:"\r
+            "Folder" = "8:_9375E488732B409C8187CC9603423443"\r
+            "Condition" = "8:"\r
+            "Transitive" = "11:FALSE"\r
+            "Vital" = "11:TRUE"\r
+            "ReadOnly" = "11:FALSE"\r
+            "Hidden" = "11:FALSE"\r
+            "System" = "11:FALSE"\r
+            "Permanent" = "11:FALSE"\r
+            "SharedLegacy" = "11:FALSE"\r
+            "PackageAs" = "3:1"\r
+            "Register" = "3:1"\r
+            "Exclude" = "11:FALSE"\r
+            "IsDependency" = "11:TRUE"\r
+            "IsolateTo" = "8:"\r
+            }\r
+            "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_66851612066C8C647ECEDCABC8C2389C"\r
+            {\r
+            "SourcePath" = "8:BlueVelvet3.dll"\r
+            "TargetName" = "8:BlueVelvet3.dll"\r
+            "Tag" = "8:"\r
+            "Folder" = "8:_9375E488732B409C8187CC9603423443"\r
+            "Condition" = "8:"\r
+            "Transitive" = "11:FALSE"\r
+            "Vital" = "11:TRUE"\r
+            "ReadOnly" = "11:FALSE"\r
+            "Hidden" = "11:FALSE"\r
+            "System" = "11:FALSE"\r
+            "Permanent" = "11:FALSE"\r
+            "SharedLegacy" = "11:FALSE"\r
+            "PackageAs" = "3:1"\r
+            "Register" = "3:1"\r
+            "Exclude" = "11:TRUE"\r
+            "IsDependency" = "11:TRUE"\r
+            "IsolateTo" = "8:"\r
+            }\r
+            "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_80C0E135DDC14FFEA2C21797CCF7C934"\r
+            {\r
+            "SourcePath" = "8:..\\..\\..\\..\\Dokument\\COPYING.TXT"\r
+            "TargetName" = "8:COPYING.TXT"\r
+            "Tag" = "8:"\r
+            "Folder" = "8:_9375E488732B409C8187CC9603423443"\r
+            "Condition" = "8:"\r
+            "Transitive" = "11:FALSE"\r
+            "Vital" = "11:TRUE"\r
+            "ReadOnly" = "11:FALSE"\r
+            "Hidden" = "11:FALSE"\r
+            "System" = "11:FALSE"\r
+            "Permanent" = "11:FALSE"\r
+            "SharedLegacy" = "11:FALSE"\r
+            "PackageAs" = "3:1"\r
+            "Register" = "3:1"\r
+            "Exclude" = "11:FALSE"\r
+            "IsDependency" = "11:FALSE"\r
+            "IsolateTo" = "8:"\r
+            }\r
+            "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_9589226DB30A7514D00BBD1A04CF473C"\r
+            {\r
+            "SourcePath" = "8:DSOUND.dll"\r
+            "TargetName" = "8:DSOUND.dll"\r
+            "Tag" = "8:"\r
+            "Folder" = "8:_9375E488732B409C8187CC9603423443"\r
+            "Condition" = "8:"\r
+            "Transitive" = "11:FALSE"\r
+            "Vital" = "11:TRUE"\r
+            "ReadOnly" = "11:FALSE"\r
+            "Hidden" = "11:FALSE"\r
+            "System" = "11:FALSE"\r
+            "Permanent" = "11:FALSE"\r
+            "SharedLegacy" = "11:FALSE"\r
+            "PackageAs" = "3:1"\r
+            "Register" = "3:1"\r
+            "Exclude" = "11:TRUE"\r
+            "IsDependency" = "11:TRUE"\r
+            "IsolateTo" = "8:"\r
+            }\r
+            "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_970CC65F3EB54C2CBE6AE94AA7BE55A3"\r
+            {\r
+            "SourcePath" = "8:C:\\CASPAR\\CG.fth.18"\r
+            "TargetName" = "8:CG.fth.18"\r
+            "Tag" = "8:"\r
+            "Folder" = "8:_F09AF73BFECB41448B6547928411A3BE"\r
+            "Condition" = "8:"\r
+            "Transitive" = "11:FALSE"\r
+            "Vital" = "11:TRUE"\r
+            "ReadOnly" = "11:FALSE"\r
+            "Hidden" = "11:FALSE"\r
+            "System" = "11:FALSE"\r
+            "Permanent" = "11:FALSE"\r
+            "SharedLegacy" = "11:FALSE"\r
+            "PackageAs" = "3:1"\r
+            "Register" = "3:1"\r
+            "Exclude" = "11:FALSE"\r
+            "IsDependency" = "11:FALSE"\r
+            "IsolateTo" = "8:"\r
+            }\r
+            "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_CFE2758D601F426DB9A2B44160093BF7"\r
+            {\r
+            "SourcePath" = "8:..\\..\\..\\..\\Dokument\\README.TXT"\r
+            "TargetName" = "8:README.TXT"\r
+            "Tag" = "8:"\r
+            "Folder" = "8:_9375E488732B409C8187CC9603423443"\r
+            "Condition" = "8:"\r
+            "Transitive" = "11:FALSE"\r
+            "Vital" = "11:TRUE"\r
+            "ReadOnly" = "11:FALSE"\r
+            "Hidden" = "11:FALSE"\r
+            "System" = "11:FALSE"\r
+            "Permanent" = "11:FALSE"\r
+            "SharedLegacy" = "11:FALSE"\r
+            "PackageAs" = "3:1"\r
+            "Register" = "3:1"\r
+            "Exclude" = "11:FALSE"\r
+            "IsDependency" = "11:FALSE"\r
+            "IsolateTo" = "8:"\r
+            }\r
+            "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_E1038D2A23C24E858A4A869F00E9F274"\r
+            {\r
+            "SourcePath" = "8:..\\server\\build\\avformat-51.dll"\r
+            "TargetName" = "8:avformat-51.dll"\r
+            "Tag" = "8:"\r
+            "Folder" = "8:_9375E488732B409C8187CC9603423443"\r
+            "Condition" = "8:"\r
+            "Transitive" = "11:FALSE"\r
+            "Vital" = "11:TRUE"\r
+            "ReadOnly" = "11:FALSE"\r
+            "Hidden" = "11:FALSE"\r
+            "System" = "11:FALSE"\r
+            "Permanent" = "11:FALSE"\r
+            "SharedLegacy" = "11:FALSE"\r
+            "PackageAs" = "3:1"\r
+            "Register" = "3:1"\r
+            "Exclude" = "11:FALSE"\r
+            "IsDependency" = "11:FALSE"\r
+            "IsolateTo" = "8:"\r
+            }\r
+            "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_E1C7F01A7300440C98234B68CF89520B"\r
+            {\r
+            "SourcePath" = "8:OPENGL32.dll"\r
+            "TargetName" = "8:OPENGL32.dll"\r
+            "Tag" = "8:"\r
+            "Folder" = "8:_9375E488732B409C8187CC9603423443"\r
+            "Condition" = "8:"\r
+            "Transitive" = "11:FALSE"\r
+            "Vital" = "11:TRUE"\r
+            "ReadOnly" = "11:FALSE"\r
+            "Hidden" = "11:FALSE"\r
+            "System" = "11:FALSE"\r
+            "Permanent" = "11:FALSE"\r
+            "SharedLegacy" = "11:FALSE"\r
+            "PackageAs" = "3:1"\r
+            "Register" = "3:1"\r
+            "Exclude" = "11:TRUE"\r
+            "IsDependency" = "11:TRUE"\r
+            "IsolateTo" = "8:"\r
+            }\r
+            "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_ECA4D29D357B412598E1AA58F1883939"\r
+            {\r
+            "SourcePath" = "8:..\\server\\build\\avcodec-51.dll"\r
+            "TargetName" = "8:avcodec-51.dll"\r
+            "Tag" = "8:"\r
+            "Folder" = "8:_9375E488732B409C8187CC9603423443"\r
+            "Condition" = "8:"\r
+            "Transitive" = "11:FALSE"\r
+            "Vital" = "11:TRUE"\r
+            "ReadOnly" = "11:FALSE"\r
+            "Hidden" = "11:FALSE"\r
+            "System" = "11:FALSE"\r
+            "Permanent" = "11:FALSE"\r
+            "SharedLegacy" = "11:FALSE"\r
+            "PackageAs" = "3:1"\r
+            "Register" = "3:1"\r
+            "Exclude" = "11:FALSE"\r
+            "IsDependency" = "11:FALSE"\r
+            "IsolateTo" = "8:"\r
+            }\r
+        }\r
+        "FileType"\r
+        {\r
+        }\r
+        "Folder"\r
+        {\r
+            "{1525181F-901A-416C-8A58-119130FE478E}:_6E1E550D71074B408E318E9AFAA73EBE"\r
+            {\r
+            "Name" = "8:#1916"\r
+            "AlwaysCreate" = "11:FALSE"\r
+            "Condition" = "8:"\r
+            "Transitive" = "11:FALSE"\r
+            "Property" = "8:DesktopFolder"\r
+                "Folders"\r
+                {\r
+                }\r
+            }\r
+            "{3C67513D-01DD-4637-8A68-80971EB9504F}:_9375E488732B409C8187CC9603423443"\r
+            {\r
+            "DefaultLocation" = "8:[ProgramFilesFolder]\\[ProductName]"\r
+            "Name" = "8:#1925"\r
+            "AlwaysCreate" = "11:FALSE"\r
+            "Condition" = "8:"\r
+            "Transitive" = "11:FALSE"\r
+            "Property" = "8:TARGETDIR"\r
+                "Folders"\r
+                {\r
+                }\r
+            }\r
+            "{1525181F-901A-416C-8A58-119130FE478E}:_962EBE7C3BB548E5B4EF88B0B54FA0A9"\r
+            {\r
+            "Name" = "8:#1919"\r
+            "AlwaysCreate" = "11:FALSE"\r
+            "Condition" = "8:"\r
+            "Transitive" = "11:FALSE"\r
+            "Property" = "8:ProgramMenuFolder"\r
+                "Folders"\r
+                {\r
+                    "{9EF0B969-E518-4E46-987F-47570745A589}:_9FFCC4DB9E8B4FCDB847173FFEFD85B9"\r
+                    {\r
+                    "Name" = "8:CasparCG"\r
+                    "AlwaysCreate" = "11:FALSE"\r
+                    "Condition" = "8:"\r
+                    "Transitive" = "11:FALSE"\r
+                    "Property" = "8:_974D0E8854384C53A34E158576F30085"\r
+                        "Folders"\r
+                        {\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+            "{994432C3-9487-495D-8656-3E829A8DBDDE}:_F09AF73BFECB41448B6547928411A3BE"\r
+            {\r
+            "DefaultLocation" = "8:C:\\Casparcg"\r
+            "Name" = "8:CASPARCG"\r
+            "AlwaysCreate" = "11:FALSE"\r
+            "Condition" = "8:"\r
+            "Transitive" = "11:FALSE"\r
+            "Property" = "8:NEWPROPERTY1"\r
+                "Folders"\r
+                {\r
+                    "{9EF0B969-E518-4E46-987F-47570745A589}:_5E186392CF894DFBA568D0404F22178B"\r
+                    {\r
+                    "Name" = "8:_log"\r
+                    "AlwaysCreate" = "11:TRUE"\r
+                    "Condition" = "8:"\r
+                    "Transitive" = "11:FALSE"\r
+                    "Property" = "8:_6327D7E757994C799920331783418DE3"\r
+                        "Folders"\r
+                        {\r
+                        }\r
+                    }\r
+                    "{9EF0B969-E518-4E46-987F-47570745A589}:_91160328B29C4552A0182A1C84EA2144"\r
+                    {\r
+                    "Name" = "8:_data"\r
+                    "AlwaysCreate" = "11:TRUE"\r
+                    "Condition" = "8:"\r
+                    "Transitive" = "11:FALSE"\r
+                    "Property" = "8:_B937C04B2A69483886CBD50DB48C3EF0"\r
+                        "Folders"\r
+                        {\r
+                        }\r
+                    }\r
+                    "{9EF0B969-E518-4E46-987F-47570745A589}:_F364DD7D53D44D79AEDF19B22F92D7CD"\r
+                    {\r
+                    "Name" = "8:_media"\r
+                    "AlwaysCreate" = "11:TRUE"\r
+                    "Condition" = "8:"\r
+                    "Transitive" = "11:FALSE"\r
+                    "Property" = "8:_DBD8BF8B331F4365973548BC5F11A048"\r
+                        "Folders"\r
+                        {\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        "LaunchCondition"\r
+        {\r
+        }\r
+        "Locator"\r
+        {\r
+        }\r
+        "MsiBootstrapper"\r
+        {\r
+        "LangId" = "3:1033"\r
+        "RequiresElevation" = "11:FALSE"\r
+        }\r
+        "Product"\r
+        {\r
+        "Name" = "8:Microsoft Visual Studio"\r
+        "ProductName" = "8:CasparCG 1.8.0b4"\r
+        "ProductCode" = "8:{CA164F8A-1A10-47C8-875D-251A2E273CE6}"\r
+        "PackageCode" = "8:{7EE4E785-8E31-44FB-B359-A7E2B0909650}"\r
+        "UpgradeCode" = "8:{E02D764D-FA5E-4AE2-BF0C-D9B632065D1E}"\r
+        "RestartWWWService" = "11:FALSE"\r
+        "RemovePreviousVersions" = "11:TRUE"\r
+        "DetectNewerInstalledVersion" = "11:TRUE"\r
+        "InstallAllUsers" = "11:TRUE"\r
+        "ProductVersion" = "8:1.8"\r
+        "Manufacturer" = "8:Sveriges Television AB"\r
+        "ARPHELPTELEPHONE" = "8:"\r
+        "ARPHELPLINK" = "8:http://www.casparcg.com/wiki"\r
+        "Title" = "8:CasparCG 1.8.0b4 Setup"\r
+        "Subject" = "8:"\r
+        "ARPCONTACT" = "8:Sveriges Television AB"\r
+        "Keywords" = "8:"\r
+        "ARPCOMMENTS" = "8:"\r
+        "ARPURLINFOABOUT" = "8:"\r
+        "ARPPRODUCTICON" = "8:_B0373B7651594DCCA4AA16F49FF96652"\r
+        "ARPIconIndex" = "3:101"\r
+        "SearchPath" = "8:"\r
+        "UseSystemSearchPath" = "11:TRUE"\r
+        "TargetPlatform" = "3:0"\r
+        "PreBuildEvent" = "8:"\r
+        "PostBuildEvent" = "8:"\r
+        "RunPostBuildEvent" = "3:0"\r
+        }\r
+        "Registry"\r
+        {\r
+            "HKLM"\r
+            {\r
+                "Keys"\r
+                {\r
+                    "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_FBB8CE1E14984B598977A19CDE37669B"\r
+                    {\r
+                    "Name" = "8:Software"\r
+                    "Condition" = "8:"\r
+                    "AlwaysCreate" = "11:FALSE"\r
+                    "DeleteAtUninstall" = "11:FALSE"\r
+                    "Transitive" = "11:FALSE"\r
+                        "Keys"\r
+                        {\r
+                            "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_2FA9467E86394E2A8A11E9C98AB8FED5"\r
+                            {\r
+                            "Name" = "8:Sveriges Television AB"\r
+                            "Condition" = "8:"\r
+                            "AlwaysCreate" = "11:FALSE"\r
+                            "DeleteAtUninstall" = "11:FALSE"\r
+                            "Transitive" = "11:FALSE"\r
+                                "Keys"\r
+                                {\r
+                                    "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_9AC33B20E2434AC29078CC415F11584C"\r
+                                    {\r
+                                    "Name" = "8:Caspar CG"\r
+                                    "Condition" = "8:"\r
+                                    "AlwaysCreate" = "11:TRUE"\r
+                                    "DeleteAtUninstall" = "11:FALSE"\r
+                                    "Transitive" = "11:FALSE"\r
+                                        "Keys"\r
+                                        {\r
+                                            "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_761CDC381375419FBF66BE1299E6111E"\r
+                                            {\r
+                                            "Name" = "8:1.7"\r
+                                            "Condition" = "8:"\r
+                                            "AlwaysCreate" = "11:FALSE"\r
+                                            "DeleteAtUninstall" = "11:FALSE"\r
+                                            "Transitive" = "11:FALSE"\r
+                                                "Keys"\r
+                                                {\r
+                                                }\r
+                                                "Values"\r
+                                                {\r
+                                                    "{ADCFDA98-8FDD-45E4-90BC-E3D20B029870}:_21E47DFB98C048D99B74CE323ADCD0A4"\r
+                                                    {\r
+                                                    "Name" = "8:DataFolder"\r
+                                                    "Condition" = "8:"\r
+                                                    "Transitive" = "11:FALSE"\r
+                                                    "ValueTypes" = "3:1"\r
+                                                    "Value" = "8:C:\\CASPARCG\\_data"\r
+                                                    }\r
+                                                }\r
+                                            }\r
+                                            "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_8A03683A8EB24EF7AB4778AB7E083671"\r
+                                            {\r
+                                            "Name" = "8:1.0"\r
+                                            "Condition" = "8:"\r
+                                            "AlwaysCreate" = "11:TRUE"\r
+                                            "DeleteAtUninstall" = "11:FALSE"\r
+                                            "Transitive" = "11:FALSE"\r
+                                                "Keys"\r
+                                                {\r
+                                                }\r
+                                                "Values"\r
+                                                {\r
+                                                    "{ADCFDA98-8FDD-45E4-90BC-E3D20B029870}:_8C5B2BEA073E454181D2634B9BE194A1"\r
+                                                    {\r
+                                                    "Name" = "8:LogLevel"\r
+                                                    "Condition" = "8:"\r
+                                                    "Transitive" = "11:FALSE"\r
+                                                    "ValueTypes" = "3:3"\r
+                                                    "Value" = "3:0"\r
+                                                    }\r
+                                                    "{ADCFDA98-8FDD-45E4-90BC-E3D20B029870}:_9A29A88774BC464794AFE4E704146944"\r
+                                                    {\r
+                                                    "Name" = "8:MediaFolder"\r
+                                                    "Condition" = "8:"\r
+                                                    "Transitive" = "11:FALSE"\r
+                                                    "ValueTypes" = "3:1"\r
+                                                    "Value" = "8:C:\\CASPARCG\\_media"\r
+                                                    }\r
+                                                    "{ADCFDA98-8FDD-45E4-90BC-E3D20B029870}:_EBEB51B9F1D24F5284B2420BFD54A534"\r
+                                                    {\r
+                                                    "Name" = "8:LogFolder"\r
+                                                    "Condition" = "8:"\r
+                                                    "Transitive" = "11:FALSE"\r
+                                                    "ValueTypes" = "3:1"\r
+                                                    "Value" = "8:C:\\CASPARCG\\_LOG"\r
+                                                    }\r
+                                                }\r
+                                            }\r
+                                            "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_A135AFA2839C4C4DB2CA702118FFABEC"\r
+                                            {\r
+                                            "Name" = "8:controllers"\r
+                                            "Condition" = "8:"\r
+                                            "AlwaysCreate" = "11:TRUE"\r
+                                            "DeleteAtUninstall" = "11:FALSE"\r
+                                            "Transitive" = "11:FALSE"\r
+                                                "Keys"\r
+                                                {\r
+                                                    "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_B5B88707EAA944F4A3F1E40D0E3B6AD0"\r
+                                                    {\r
+                                                    "Name" = "8:0"\r
+                                                    "Condition" = "8:"\r
+                                                    "AlwaysCreate" = "11:FALSE"\r
+                                                    "DeleteAtUninstall" = "11:FALSE"\r
+                                                    "Transitive" = "11:FALSE"\r
+                                                        "Keys"\r
+                                                        {\r
+                                                        }\r
+                                                        "Values"\r
+                                                        {\r
+                                                            "{ADCFDA98-8FDD-45E4-90BC-E3D20B029870}:_23C2D71D92974E1E8D085BD577099CFD"\r
+                                                            {\r
+                                                            "Name" = "8:protocol"\r
+                                                            "Condition" = "8:"\r
+                                                            "Transitive" = "11:FALSE"\r
+                                                            "ValueTypes" = "3:3"\r
+                                                            "Value" = "3:0"\r
+                                                            }\r
+                                                            "{ADCFDA98-8FDD-45E4-90BC-E3D20B029870}:_51094D37A4C449529AB7DFFCAA6F9D73"\r
+                                                            {\r
+                                                            "Name" = "8:TCPPort"\r
+                                                            "Condition" = "8:"\r
+                                                            "Transitive" = "11:FALSE"\r
+                                                            "ValueTypes" = "3:3"\r
+                                                            "Value" = "3:5250"\r
+                                                            }\r
+                                                            "{ADCFDA98-8FDD-45E4-90BC-E3D20B029870}:_E2D09B99BA6947588BD1288DF77C851A"\r
+                                                            {\r
+                                                            "Name" = "8:transport"\r
+                                                            "Condition" = "8:"\r
+                                                            "Transitive" = "11:FALSE"\r
+                                                            "ValueTypes" = "3:3"\r
+                                                            "Value" = "3:0"\r
+                                                            }\r
+                                                        }\r
+                                                    }\r
+                                                }\r
+                                                "Values"\r
+                                                {\r
+                                                    "{ADCFDA98-8FDD-45E4-90BC-E3D20B029870}:_5B0B3DB482754F7A801876C746CB3505"\r
+                                                    {\r
+                                                    "Name" = "8:transports"\r
+                                                    "Condition" = "8:"\r
+                                                    "Transitive" = "11:FALSE"\r
+                                                    "ValueTypes" = "3:1"\r
+                                                    "Value" = "8:TCP/IP;Serial"\r
+                                                    }\r
+                                                    "{ADCFDA98-8FDD-45E4-90BC-E3D20B029870}:_A60DB72236914EF7B9C3E21CAAE5367B"\r
+                                                    {\r
+                                                    "Name" = "8:protocols"\r
+                                                    "Condition" = "8:"\r
+                                                    "Transitive" = "11:FALSE"\r
+                                                    "ValueTypes" = "3:1"\r
+                                                    "Value" = "8:AMCP;CII"\r
+                                                    }\r
+                                                }\r
+                                            }\r
+                                            "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_A679799EC8E74789BA2B5968EDBA495E"\r
+                                            {\r
+                                            "Name" = "8:1.5"\r
+                                            "Condition" = "8:"\r
+                                            "AlwaysCreate" = "11:TRUE"\r
+                                            "DeleteAtUninstall" = "11:FALSE"\r
+                                            "Transitive" = "11:FALSE"\r
+                                                "Keys"\r
+                                                {\r
+                                                }\r
+                                                "Values"\r
+                                                {\r
+                                                    "{ADCFDA98-8FDD-45E4-90BC-E3D20B029870}:_B7BEF5E3C81645339AFB8BCD8CF78139"\r
+                                                    {\r
+                                                    "Name" = "8:TemplateFolder"\r
+                                                    "Condition" = "8:"\r
+                                                    "Transitive" = "11:FALSE"\r
+                                                    "ValueTypes" = "3:1"\r
+                                                    "Value" = "8:C:\\Casparcg"\r
+                                                    }\r
+                                                }\r
+                                            }\r
+                                        }\r
+                                        "Values"\r
+                                        {\r
+                                        }\r
+                                    }\r
+                                }\r
+                                "Values"\r
+                                {\r
+                                }\r
+                            }\r
+                        }\r
+                        "Values"\r
+                        {\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+            "HKCU"\r
+            {\r
+                "Keys"\r
+                {\r
+                    "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_B88E21B5C85741E58990F9D072FA796B"\r
+                    {\r
+                    "Name" = "8:Software"\r
+                    "Condition" = "8:"\r
+                    "AlwaysCreate" = "11:FALSE"\r
+                    "DeleteAtUninstall" = "11:FALSE"\r
+                    "Transitive" = "11:FALSE"\r
+                        "Keys"\r
+                        {\r
+                            "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_06D5827004D14CFABA3436B6B48D4DB3"\r
+                            {\r
+                            "Name" = "8:[Manufacturer]"\r
+                            "Condition" = "8:"\r
+                            "AlwaysCreate" = "11:FALSE"\r
+                            "DeleteAtUninstall" = "11:FALSE"\r
+                            "Transitive" = "11:FALSE"\r
+                                "Keys"\r
+                                {\r
+                                }\r
+                                "Values"\r
+                                {\r
+                                }\r
+                            }\r
+                        }\r
+                        "Values"\r
+                        {\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+            "HKCR"\r
+            {\r
+                "Keys"\r
+                {\r
+                }\r
+            }\r
+            "HKU"\r
+            {\r
+                "Keys"\r
+                {\r
+                }\r
+            }\r
+            "HKPU"\r
+            {\r
+                "Keys"\r
+                {\r
+                }\r
+            }\r
+        }\r
+        "Sequences"\r
+        {\r
+        }\r
+        "Shortcut"\r
+        {\r
+            "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_20CF7AA1AA584EAAB475C1DF746CCD99"\r
+            {\r
+            "Name" = "8:CasparCG (DeckLink)"\r
+            "Arguments" = "8:"\r
+            "Description" = "8:"\r
+            "ShowCmd" = "3:1"\r
+            "IconIndex" = "3:101"\r
+            "Transitive" = "11:FALSE"\r
+            "Target" = "8:_401120F0A3E94D9F9DA6BD5474650E27"\r
+            "Folder" = "8:_9FFCC4DB9E8B4FCDB847173FFEFD85B9"\r
+            "WorkingFolder" = "8:_9375E488732B409C8187CC9603423443"\r
+            "Icon" = "8:_401120F0A3E94D9F9DA6BD5474650E27"\r
+            "Feature" = "8:"\r
+            }\r
+            "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_62F7CD07617947FD80B9E6637BCE76ED"\r
+            {\r
+            "Name" = "8:CasparCG (Bluefish, PAL)"\r
+            "Arguments" = "8:"\r
+            "Description" = "8:"\r
+            "ShowCmd" = "3:1"\r
+            "IconIndex" = "3:101"\r
+            "Transitive" = "11:FALSE"\r
+            "Target" = "8:_B0373B7651594DCCA4AA16F49FF96652"\r
+            "Folder" = "8:_9FFCC4DB9E8B4FCDB847173FFEFD85B9"\r
+            "WorkingFolder" = "8:_9375E488732B409C8187CC9603423443"\r
+            "Icon" = "8:_B0373B7651594DCCA4AA16F49FF96652"\r
+            "Feature" = "8:"\r
+            }\r
+            "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_698600EF3E8747A9A76589BB5CF95EDB"\r
+            {\r
+            "Name" = "8:CasparCG (Fullscreen)"\r
+            "Arguments" = "8:oglchannel"\r
+            "Description" = "8:"\r
+            "ShowCmd" = "3:1"\r
+            "IconIndex" = "3:101"\r
+            "Transitive" = "11:FALSE"\r
+            "Target" = "8:_401120F0A3E94D9F9DA6BD5474650E27"\r
+            "Folder" = "8:_9FFCC4DB9E8B4FCDB847173FFEFD85B9"\r
+            "WorkingFolder" = "8:_9375E488732B409C8187CC9603423443"\r
+            "Icon" = "8:_401120F0A3E94D9F9DA6BD5474650E27"\r
+            "Feature" = "8:"\r
+            }\r
+            "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_88DCCB5547A5497394BD5A2CB4F01866"\r
+            {\r
+            "Name" = "8:CasparCG (Bluefish, 720p50)"\r
+            "Arguments" = "8:videomode=720p5000"\r
+            "Description" = "8:"\r
+            "ShowCmd" = "3:1"\r
+            "IconIndex" = "3:101"\r
+            "Transitive" = "11:FALSE"\r
+            "Target" = "8:_B0373B7651594DCCA4AA16F49FF96652"\r
+            "Folder" = "8:_9FFCC4DB9E8B4FCDB847173FFEFD85B9"\r
+            "WorkingFolder" = "8:_9375E488732B409C8187CC9603423443"\r
+            "Icon" = "8:_B0373B7651594DCCA4AA16F49FF96652"\r
+            "Feature" = "8:"\r
+            }\r
+            "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_EC15F4EEE8964FE8B7D3384774A89CC7"\r
+            {\r
+            "Name" = "8:CasparCG (GDI)"\r
+            "Arguments" = "8:gdichannel"\r
+            "Description" = "8:"\r
+            "ShowCmd" = "3:1"\r
+            "IconIndex" = "3:101"\r
+            "Transitive" = "11:FALSE"\r
+            "Target" = "8:_401120F0A3E94D9F9DA6BD5474650E27"\r
+            "Folder" = "8:_9FFCC4DB9E8B4FCDB847173FFEFD85B9"\r
+            "WorkingFolder" = "8:_9375E488732B409C8187CC9603423443"\r
+            "Icon" = "8:_401120F0A3E94D9F9DA6BD5474650E27"\r
+            "Feature" = "8:"\r
+            }\r
+        }\r
+        "UserInterface"\r
+        {\r
+            "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_2132741F67E34E459A02871FFF46CEBC"\r
+            {\r
+            "UseDynamicProperties" = "11:FALSE"\r
+            "IsDependency" = "11:FALSE"\r
+            "SourcePath" = "8:<VsdDialogDir>\\VsdBasicDialogs.wim"\r
+            }\r
+            "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_3E0A00EEFCEC4256B31ED6E89B8E8FF4"\r
+            {\r
+            "Name" = "8:#1900"\r
+            "Sequence" = "3:2"\r
+            "Attributes" = "3:1"\r
+                "Dialogs"\r
+                {\r
+                    "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_00FD106AD9A64B318DA72396C5EA2D08"\r
+                    {\r
+                    "Sequence" = "3:100"\r
+                    "DisplayName" = "8:Welcome"\r
+                    "UseDynamicProperties" = "11:TRUE"\r
+                    "IsDependency" = "11:FALSE"\r
+                    "SourcePath" = "8:<VsdDialogDir>\\VsdAdminWelcomeDlg.wid"\r
+                        "Properties"\r
+                        {\r
+                            "BannerBitmap"\r
+                            {\r
+                            "Name" = "8:BannerBitmap"\r
+                            "DisplayName" = "8:#1001"\r
+                            "Description" = "8:#1101"\r
+                            "Type" = "3:8"\r
+                            "ContextData" = "8:Bitmap"\r
+                            "Attributes" = "3:4"\r
+                            "Setting" = "3:1"\r
+                            "UsePlugInResources" = "11:TRUE"\r
+                            }\r
+                            "CopyrightWarning"\r
+                            {\r
+                            "Name" = "8:CopyrightWarning"\r
+                            "DisplayName" = "8:#1002"\r
+                            "Description" = "8:#1102"\r
+                            "Type" = "3:3"\r
+                            "ContextData" = "8:"\r
+                            "Attributes" = "3:0"\r
+                            "Setting" = "3:2"\r
+                            "Value" = "8:"\r
+                            "DefaultValue" = "8:#1202"\r
+                            "UsePlugInResources" = "11:TRUE"\r
+                            }\r
+                            "Welcome"\r
+                            {\r
+                            "Name" = "8:Welcome"\r
+                            "DisplayName" = "8:#1003"\r
+                            "Description" = "8:#1103"\r
+                            "Type" = "3:3"\r
+                            "ContextData" = "8:"\r
+                            "Attributes" = "3:0"\r
+                            "Setting" = "3:1"\r
+                            "Value" = "8:#1203"\r
+                            "DefaultValue" = "8:#1203"\r
+                            "UsePlugInResources" = "11:TRUE"\r
+                            }\r
+                        }\r
+                    }\r
+                    "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_A5B37DA803E043148A8F51DD9565937F"\r
+                    {\r
+                    "Sequence" = "3:200"\r
+                    "DisplayName" = "8:Installation Folder"\r
+                    "UseDynamicProperties" = "11:TRUE"\r
+                    "IsDependency" = "11:FALSE"\r
+                    "SourcePath" = "8:<VsdDialogDir>\\VsdAdminFolderDlg.wid"\r
+                        "Properties"\r
+                        {\r
+                            "BannerBitmap"\r
+                            {\r
+                            "Name" = "8:BannerBitmap"\r
+                            "DisplayName" = "8:#1001"\r
+                            "Description" = "8:#1101"\r
+                            "Type" = "3:8"\r
+                            "ContextData" = "8:Bitmap"\r
+                            "Attributes" = "3:4"\r
+                            "Setting" = "3:1"\r
+                            "UsePlugInResources" = "11:TRUE"\r
+                            }\r
+                        }\r
+                    }\r
+                    "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_CC0CE59BBEC44F4895005E46F7BCC825"\r
+                    {\r
+                    "Sequence" = "3:300"\r
+                    "DisplayName" = "8:Confirm Installation"\r
+                    "UseDynamicProperties" = "11:TRUE"\r
+                    "IsDependency" = "11:FALSE"\r
+                    "SourcePath" = "8:<VsdDialogDir>\\VsdAdminConfirmDlg.wid"\r
+                        "Properties"\r
+                        {\r
+                            "BannerBitmap"\r
+                            {\r
+                            "Name" = "8:BannerBitmap"\r
+                            "DisplayName" = "8:#1001"\r
+                            "Description" = "8:#1101"\r
+                            "Type" = "3:8"\r
+                            "ContextData" = "8:Bitmap"\r
+                            "Attributes" = "3:4"\r
+                            "Setting" = "3:1"\r
+                            "UsePlugInResources" = "11:TRUE"\r
+                            }\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+            "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_652EBC6E46764870BFB253B0613A09E9"\r
+            {\r
+            "Name" = "8:#1901"\r
+            "Sequence" = "3:1"\r
+            "Attributes" = "3:2"\r
+                "Dialogs"\r
+                {\r
+                    "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_545BA2AE509242F1AC456065CBA5B651"\r
+                    {\r
+                    "Sequence" = "3:100"\r
+                    "DisplayName" = "8:Progress"\r
+                    "UseDynamicProperties" = "11:TRUE"\r
+                    "IsDependency" = "11:FALSE"\r
+                    "SourcePath" = "8:<VsdDialogDir>\\VsdProgressDlg.wid"\r
+                        "Properties"\r
+                        {\r
+                            "BannerBitmap"\r
+                            {\r
+                            "Name" = "8:BannerBitmap"\r
+                            "DisplayName" = "8:#1001"\r
+                            "Description" = "8:#1101"\r
+                            "Type" = "3:8"\r
+                            "ContextData" = "8:Bitmap"\r
+                            "Attributes" = "3:4"\r
+                            "Setting" = "3:1"\r
+                            "UsePlugInResources" = "11:TRUE"\r
+                            }\r
+                            "ShowProgress"\r
+                            {\r
+                            "Name" = "8:ShowProgress"\r
+                            "DisplayName" = "8:#1009"\r
+                            "Description" = "8:#1109"\r
+                            "Type" = "3:5"\r
+                            "ContextData" = "8:1;True=1;False=0"\r
+                            "Attributes" = "3:0"\r
+                            "Setting" = "3:0"\r
+                            "Value" = "3:1"\r
+                            "DefaultValue" = "3:1"\r
+                            "UsePlugInResources" = "11:TRUE"\r
+                            }\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+            "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_833B54AB586B49AA9F7702DB9B29AB4C"\r
+            {\r
+            "Name" = "8:#1902"\r
+            "Sequence" = "3:2"\r
+            "Attributes" = "3:3"\r
+                "Dialogs"\r
+                {\r
+                    "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_F135491AE6B74AF38A4504DE1441A76C"\r
+                    {\r
+                    "Sequence" = "3:100"\r
+                    "DisplayName" = "8:Finished"\r
+                    "UseDynamicProperties" = "11:TRUE"\r
+                    "IsDependency" = "11:FALSE"\r
+                    "SourcePath" = "8:<VsdDialogDir>\\VsdAdminFinishedDlg.wid"\r
+                        "Properties"\r
+                        {\r
+                            "BannerBitmap"\r
+                            {\r
+                            "Name" = "8:BannerBitmap"\r
+                            "DisplayName" = "8:#1001"\r
+                            "Description" = "8:#1101"\r
+                            "Type" = "3:8"\r
+                            "ContextData" = "8:Bitmap"\r
+                            "Attributes" = "3:4"\r
+                            "Setting" = "3:1"\r
+                            "UsePlugInResources" = "11:TRUE"\r
+                            }\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+            "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_A06A59F7662B40A39373A94706F5DC86"\r
+            {\r
+            "Name" = "8:#1902"\r
+            "Sequence" = "3:1"\r
+            "Attributes" = "3:3"\r
+                "Dialogs"\r
+                {\r
+                    "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_BA4ED42464BF4242978A17DEC09B6A29"\r
+                    {\r
+                    "Sequence" = "3:100"\r
+                    "DisplayName" = "8:Finished"\r
+                    "UseDynamicProperties" = "11:TRUE"\r
+                    "IsDependency" = "11:FALSE"\r
+                    "SourcePath" = "8:<VsdDialogDir>\\VsdFinishedDlg.wid"\r
+                        "Properties"\r
+                        {\r
+                            "BannerBitmap"\r
+                            {\r
+                            "Name" = "8:BannerBitmap"\r
+                            "DisplayName" = "8:#1001"\r
+                            "Description" = "8:#1101"\r
+                            "Type" = "3:8"\r
+                            "ContextData" = "8:Bitmap"\r
+                            "Attributes" = "3:4"\r
+                            "Setting" = "3:1"\r
+                            "UsePlugInResources" = "11:TRUE"\r
+                            }\r
+                            "UpdateText"\r
+                            {\r
+                            "Name" = "8:UpdateText"\r
+                            "DisplayName" = "8:#1058"\r
+                            "Description" = "8:#1158"\r
+                            "Type" = "3:15"\r
+                            "ContextData" = "8:"\r
+                            "Attributes" = "3:0"\r
+                            "Setting" = "3:1"\r
+                            "Value" = "8:#1258"\r
+                            "DefaultValue" = "8:#1258"\r
+                            "UsePlugInResources" = "11:TRUE"\r
+                            }\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+            "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_CB8A14D6A80044A388B13FD0E936AA62"\r
+            {\r
+            "Name" = "8:#1901"\r
+            "Sequence" = "3:2"\r
+            "Attributes" = "3:2"\r
+                "Dialogs"\r
+                {\r
+                    "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_BBD3FDACA8024F199799816A1A7970D2"\r
+                    {\r
+                    "Sequence" = "3:100"\r
+                    "DisplayName" = "8:Progress"\r
+                    "UseDynamicProperties" = "11:TRUE"\r
+                    "IsDependency" = "11:FALSE"\r
+                    "SourcePath" = "8:<VsdDialogDir>\\VsdAdminProgressDlg.wid"\r
+                        "Properties"\r
+                        {\r
+                            "BannerBitmap"\r
+                            {\r
+                            "Name" = "8:BannerBitmap"\r
+                            "DisplayName" = "8:#1001"\r
+                            "Description" = "8:#1101"\r
+                            "Type" = "3:8"\r
+                            "ContextData" = "8:Bitmap"\r
+                            "Attributes" = "3:4"\r
+                            "Setting" = "3:1"\r
+                            "UsePlugInResources" = "11:TRUE"\r
+                            }\r
+                            "ShowProgress"\r
+                            {\r
+                            "Name" = "8:ShowProgress"\r
+                            "DisplayName" = "8:#1009"\r
+                            "Description" = "8:#1109"\r
+                            "Type" = "3:5"\r
+                            "ContextData" = "8:1;True=1;False=0"\r
+                            "Attributes" = "3:0"\r
+                            "Setting" = "3:0"\r
+                            "Value" = "3:1"\r
+                            "DefaultValue" = "3:1"\r
+                            "UsePlugInResources" = "11:TRUE"\r
+                            }\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+            "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_D9E17BCC50E54CCD95A36A083D555D83"\r
+            {\r
+            "Name" = "8:#1900"\r
+            "Sequence" = "3:1"\r
+            "Attributes" = "3:1"\r
+                "Dialogs"\r
+                {\r
+                    "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_4BABF6AAEEFB4683919F425593C243FD"\r
+                    {\r
+                    "Sequence" = "3:100"\r
+                    "DisplayName" = "8:Welcome"\r
+                    "UseDynamicProperties" = "11:TRUE"\r
+                    "IsDependency" = "11:FALSE"\r
+                    "SourcePath" = "8:<VsdDialogDir>\\VsdWelcomeDlg.wid"\r
+                        "Properties"\r
+                        {\r
+                            "BannerBitmap"\r
+                            {\r
+                            "Name" = "8:BannerBitmap"\r
+                            "DisplayName" = "8:#1001"\r
+                            "Description" = "8:#1101"\r
+                            "Type" = "3:8"\r
+                            "ContextData" = "8:Bitmap"\r
+                            "Attributes" = "3:4"\r
+                            "Setting" = "3:1"\r
+                            "UsePlugInResources" = "11:TRUE"\r
+                            }\r
+                            "CopyrightWarning"\r
+                            {\r
+                            "Name" = "8:CopyrightWarning"\r
+                            "DisplayName" = "8:#1002"\r
+                            "Description" = "8:#1102"\r
+                            "Type" = "3:3"\r
+                            "ContextData" = "8:"\r
+                            "Attributes" = "3:0"\r
+                            "Setting" = "3:2"\r
+                            "Value" = "8:"\r
+                            "DefaultValue" = "8:#1202"\r
+                            "UsePlugInResources" = "11:TRUE"\r
+                            }\r
+                            "Welcome"\r
+                            {\r
+                            "Name" = "8:Welcome"\r
+                            "DisplayName" = "8:#1003"\r
+                            "Description" = "8:#1103"\r
+                            "Type" = "3:3"\r
+                            "ContextData" = "8:"\r
+                            "Attributes" = "3:0"\r
+                            "Setting" = "3:1"\r
+                            "Value" = "8:#1203"\r
+                            "DefaultValue" = "8:#1203"\r
+                            "UsePlugInResources" = "11:TRUE"\r
+                            }\r
+                        }\r
+                    }\r
+                    "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_6AF41D068F044D608DD9932B84515D2F"\r
+                    {\r
+                    "Sequence" = "3:300"\r
+                    "DisplayName" = "8:Confirm Installation"\r
+                    "UseDynamicProperties" = "11:TRUE"\r
+                    "IsDependency" = "11:FALSE"\r
+                    "SourcePath" = "8:<VsdDialogDir>\\VsdConfirmDlg.wid"\r
+                        "Properties"\r
+                        {\r
+                            "BannerBitmap"\r
+                            {\r
+                            "Name" = "8:BannerBitmap"\r
+                            "DisplayName" = "8:#1001"\r
+                            "Description" = "8:#1101"\r
+                            "Type" = "3:8"\r
+                            "ContextData" = "8:Bitmap"\r
+                            "Attributes" = "3:4"\r
+                            "Setting" = "3:1"\r
+                            "UsePlugInResources" = "11:TRUE"\r
+                            }\r
+                        }\r
+                    }\r
+                    "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_D6C119AFCDF84AEEB54E0FB1D0DE1A9E"\r
+                    {\r
+                    "Sequence" = "3:200"\r
+                    "DisplayName" = "8:Installation Folder"\r
+                    "UseDynamicProperties" = "11:TRUE"\r
+                    "IsDependency" = "11:FALSE"\r
+                    "SourcePath" = "8:<VsdDialogDir>\\VsdFolderDlg.wid"\r
+                        "Properties"\r
+                        {\r
+                            "BannerBitmap"\r
+                            {\r
+                            "Name" = "8:BannerBitmap"\r
+                            "DisplayName" = "8:#1001"\r
+                            "Description" = "8:#1101"\r
+                            "Type" = "3:8"\r
+                            "ContextData" = "8:Bitmap"\r
+                            "Attributes" = "3:4"\r
+                            "Setting" = "3:1"\r
+                            "UsePlugInResources" = "11:TRUE"\r
+                            }\r
+                            "InstallAllUsersVisible"\r
+                            {\r
+                            "Name" = "8:InstallAllUsersVisible"\r
+                            "DisplayName" = "8:#1059"\r
+                            "Description" = "8:#1159"\r
+                            "Type" = "3:5"\r
+                            "ContextData" = "8:1;True=1;False=0"\r
+                            "Attributes" = "3:0"\r
+                            "Setting" = "3:0"\r
+                            "Value" = "3:1"\r
+                            "DefaultValue" = "3:1"\r
+                            "UsePlugInResources" = "11:TRUE"\r
+                            }\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+            "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_FF220C76772943DF8C53AD209359D8DD"\r
+            {\r
+            "UseDynamicProperties" = "11:FALSE"\r
+            "IsDependency" = "11:FALSE"\r
+            "SourcePath" = "8:<VsdDialogDir>\\VsdUserInterface.wim"\r
+            }\r
+        }\r
+        "MergeModule"\r
+        {\r
+            "{CEE29DC0-9FBA-4B99-8D47-5BC643D9B626}:_59277C5FE6E94B9F9C971A1C16CFB37E"\r
+            {\r
+            "UseDynamicProperties" = "11:TRUE"\r
+            "IsDependency" = "11:TRUE"\r
+            "SourcePath" = "8:microsoft_vc90_crt_x86.msm"\r
+                "Properties"\r
+                {\r
+                }\r
+            "LanguageId" = "3:0"\r
+            "Exclude" = "11:FALSE"\r
+            "Folder" = "8:"\r
+            "Feature" = "8:"\r
+            "IsolateTo" = "8:"\r
+            }\r
+            "{CEE29DC0-9FBA-4B99-8D47-5BC643D9B626}:_AAD62042DDED4BE49BD147A2A78F763D"\r
+            {\r
+            "UseDynamicProperties" = "11:TRUE"\r
+            "IsDependency" = "11:TRUE"\r
+            "SourcePath" = "8:policy_9_0_Microsoft_VC90_CRT_x86.msm"\r
+                "Properties"\r
+                {\r
+                }\r
+            "LanguageId" = "3:0"\r
+            "Exclude" = "11:FALSE"\r
+            "Folder" = "8:"\r
+            "Feature" = "8:"\r
+            "IsolateTo" = "8:"\r
+            }\r
+        }\r
+        "ProjectOutput"\r
+        {\r
+            "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_401120F0A3E94D9F9DA6BD5474650E27"\r
+            {\r
+            "SourcePath" = "8:..\\no bluefish\\CasparCG.exe"\r
+            "TargetName" = "8:"\r
+            "Tag" = "8:"\r
+            "Folder" = "8:_9375E488732B409C8187CC9603423443"\r
+            "Condition" = "8:"\r
+            "Transitive" = "11:FALSE"\r
+            "Vital" = "11:TRUE"\r
+            "ReadOnly" = "11:FALSE"\r
+            "Hidden" = "11:FALSE"\r
+            "System" = "11:FALSE"\r
+            "Permanent" = "11:FALSE"\r
+            "SharedLegacy" = "11:FALSE"\r
+            "PackageAs" = "3:1"\r
+            "Register" = "3:1"\r
+            "Exclude" = "11:FALSE"\r
+            "IsDependency" = "11:FALSE"\r
+            "IsolateTo" = "8:"\r
+            "ProjectOutputGroupRegister" = "3:1"\r
+            "OutputConfiguration" = "8:no bluefish|Win32"\r
+            "OutputGroupCanonicalName" = "8:Built"\r
+            "OutputProjectGuid" = "8:{79388C20-6499-4BF6-B8B9-D8C33D7D4DDD}"\r
+            "ShowKeyOutput" = "11:TRUE"\r
+                "ExcludeFilters"\r
+                {\r
+                }\r
+            }\r
+            "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_B0373B7651594DCCA4AA16F49FF96652"\r
+            {\r
+            "SourcePath" = "8:..\\server\\build\\CasparCG_Bluefish.exe"\r
+            "TargetName" = "8:"\r
+            "Tag" = "8:"\r
+            "Folder" = "8:_9375E488732B409C8187CC9603423443"\r
+            "Condition" = "8:"\r
+            "Transitive" = "11:FALSE"\r
+            "Vital" = "11:TRUE"\r
+            "ReadOnly" = "11:FALSE"\r
+            "Hidden" = "11:FALSE"\r
+            "System" = "11:FALSE"\r
+            "Permanent" = "11:FALSE"\r
+            "SharedLegacy" = "11:FALSE"\r
+            "PackageAs" = "3:1"\r
+            "Register" = "3:1"\r
+            "Exclude" = "11:FALSE"\r
+            "IsDependency" = "11:FALSE"\r
+            "IsolateTo" = "8:"\r
+            "ProjectOutputGroupRegister" = "3:1"\r
+            "OutputConfiguration" = "8:Release|Win32"\r
+            "OutputGroupCanonicalName" = "8:Built"\r
+            "OutputProjectGuid" = "8:{79388C20-6499-4BF6-B8B9-D8C33D7D4DDD}"\r
+            "ShowKeyOutput" = "11:TRUE"\r
+                "ExcludeFilters"\r
+                {\r
+                }\r
+            }\r
+        }\r
+    }\r
+}\r
diff --git a/server/Application.cpp b/server/Application.cpp
new file mode 100644 (file)
index 0000000..c72c026
--- /dev/null
@@ -0,0 +1,1123 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "stdafx.h"\r
+\r
+#ifdef _DEBUG\r
+       #define _CRTDBG_MAP_ALLOC\r
+       #include <stdlib.h>\r
+       #include <crtdbg.h>\r
+#endif\r
+\r
+#include "Application.h"\r
+\r
+#include <direct.h>\r
+#include <io.h>\r
+#include <time.h>\r
+#include <stdio.h>\r
+#include <string>\r
+\r
+#include "Window.h"\r
+#include "Channel.h"\r
+\r
+#include "amcp\AMCPProtocolStrategy.h"\r
+#include "cii\CIIProtocolStrategy.h"\r
+#include "CLK\CLKProtocolStrategy.h"\r
+#include "io\AsyncEventServer.h"\r
+#include "io\SerialPort.h"\r
+\r
+#include "cg\flashcgproxy.h"\r
+\r
+#include "utils\FindWrapper.h"\r
+#include "utils\FileExists.h"\r
+#include "utils\FileOutputStream.h"\r
+#include "utils\Thread.h"\r
+\r
+#include "FileInfo.h"\r
+#include "consumers\decklink\DecklinkVideoConsumer.h"\r
+#include "consumers\OGL\OGLVideoConsumer.h"\r
+#include "consumers\GDI\GDIVideoConsumer.h"\r
+#include "consumers\audio\AudioConsumer.h"\r
+\r
+#ifndef DISABLE_BLUEFISH\r
+#include "consumers\bluefish\BlueFishVideoConsumer.h"\r
+#endif\r
+\r
+#include "audio\DirectSoundManager.h"\r
+\r
+#include "producers\flash\FlashManager.h"\r
+#include "producers\flash\CTManager.h"\r
+#include "producers\flash\FlashAxContainer.h"\r
+#include "producers\targa\TargaManager.h"\r
+#include "producers\targascroll\TargaScrollManager.h"\r
+#include "producers\ffmpeg\FFmpegManager.h"\r
+#include "producers\color\ColorManager.h"\r
+\r
+WTL::CAppModule _Module;\r
+\r
+void WINAPI SvcMain(DWORD argsCount, LPTSTR* ppArgs) {\r
+       //caspar::GetApplication()->ServiceMain();\r
+}\r
+void WINAPI SvcCtrlHandler(DWORD dwCtrl) {\r
+       //caspar::GetApplication()->ServiceCtrlHandler(dwCtrl);\r
+}\r
+\r
+\r
+LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { \r
+       return caspar::GetApplication()->WndProc(hWnd, message, wParam, lParam);\r
+}\r
+\r
+namespace caspar {\r
+\r
+using namespace utils;\r
+\r
+enum ControllerTransports { TCP, Serial, TransportsCount };\r
+enum ControllerProtocols { AMCP, CII, CLOCK, ProtocolsCount };\r
+\r
+const TCHAR* Application::versionString_(TEXT("CG 1.8 BETA(14)"));\r
+const TCHAR* Application::serviceName_(TEXT("Caspar service"));\r
+\r
+Application::Application(const tstring& cmdline, HINSTANCE hInstance) :           hInstance_(hInstance), logLevel_(2), logDir_(TEXT("log")), \r
+                                                                                                                                                  videoDir_(TEXT("media")),\r
+                                                                                                                                                  templateDir_(TEXT("templates")),\r
+                                                                                                                                                  dataDir_(TEXT("data")),\r
+                                                                                                                                                  colorManagerIndex_(-1),\r
+                                                                                                                                                  pAudioManager_(0),\r
+                                                                                                                                                  terminateEvent_(FALSE, FALSE),\r
+                                                                                                                                                  commandline_(cmdline)\r
+                                                                                                                                                  //svcStatusHandle_(0)\r
+{\r
+#ifdef _DEBUG\r
+       _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CRTDBG_CHECK_ALWAYS_DF );\r
+       _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG );\r
+       _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_DEBUG );\r
+       _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_DEBUG );\r
+\r
+//     _CrtSetBreakAlloc(1393);\r
+       Thread::EnableWin32ExceptionHandler(false);\r
+#else\r
+       Thread::EnableWin32ExceptionHandler(true);\r
+#endif\r
+\r
+       HRESULT hResult = ::OleInitialize(NULL);\r
+       _Module.Init(NULL, hInstance, &LIBID_ATLLib);\r
+}\r
+\r
+Application::~Application()\r
+{\r
+       Destroy();\r
+\r
+       _Module.Term();\r
+       ::OleUninitialize();\r
+}\r
+\r
+//////////////////////\r
+// Run as service\r
+void Application::RunAsService() {\r
+       SERVICE_TABLE_ENTRY dispatchTable[] = \r
+       { \r
+               { TEXT(""), (LPSERVICE_MAIN_FUNCTION) SvcMain }, \r
+               { NULL, NULL } \r
+       }; \r
+\r
+       // This call returns when the service has stopped. \r
+       // The process should simply terminate when the call returns.\r
+//     if(!StartServiceCtrlDispatcher(dispatchTable)) { \r
+               //SvcReportEvent(TEXT("StartServiceCtrlDispatcher")); \r
+//     }\r
+}\r
+\r
+//void Application::ServiceMain() {\r
+//     // Register the handler function for the service\r
+//     svcStatusHandle_ = RegisterServiceCtrlHandler(serviceName_, SvcCtrlHandler);\r
+//     if(!svcStatusHandle_) { \r
+//             //SvcReportEvent(TEXT("RegisterServiceCtrlHandler")); \r
+//             return; \r
+//     } \r
+//\r
+//     //These SERVICE_STATUS members remain as set here\r
+//     serviceStatus_.dwServiceType = SERVICE_WIN32_OWN_PROCESS; \r
+//     serviceStatus_.dwServiceSpecificExitCode = 0;    \r
+//\r
+//     // Report initial status to the SCM\r
+//     ServiceReportStatus(SERVICE_START_PENDING, NO_ERROR, 3000);\r
+//\r
+//     if(Initialize()) {\r
+//             ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0);\r
+//\r
+//             MSG msg;\r
+//             bool bQuit = false;\r
+//             int errorCode = 0;\r
+//\r
+//             while(!bQuit) {\r
+//                     const HANDLE waitEvents[] =  {stopEvent_, terminateEvent_ };\r
+//                     HRESULT waitResult = MsgWaitForMultipleObjects(1, &waitEvents, FALSE, 2500, QS_ALLEVENTS);\r
+//                     switch(waitResult) \r
+//                     {\r
+//                     case WAIT_OBJECT_0:\r
+//                             bQuit = true;\r
+//                             errorCode = NO_ERROR;\r
+//                             break;\r
+//\r
+//                     case WAIT_OBJECT_0 + 1:\r
+//                             bQuit = true;\r
+//                             errorCode = 42;\r
+//                             break;\r
+//\r
+//                     case WAIT_OBJECT_0+2:\r
+//                             if(GetMessage(&msg, NULL, 0, 0))\r
+//                             {\r
+//                                     TranslateMessage(&msg);\r
+//                                     DispatchMessage(&msg);\r
+//                             }\r
+//                             else {\r
+//                                     bQuit = true;\r
+//                                     errorCode = msg.wParam;\r
+//                             }\r
+//                             break;\r
+//\r
+//                     case WAIT_TIMEOUT:\r
+//                             break;\r
+//\r
+//                     case WAIT_FAILED:\r
+//                             LOG << LogLevel::Critical << "Wait failed in main thread. Exiting";\r
+//                     default:\r
+//                             bQuit = true;\r
+//                             errorCode = 42;\r
+//                             break;\r
+//                     }\r
+//             }\r
+//\r
+//             Destroy();\r
+//             ServiceReportStatus(SERVICE_STOPPED, errorCode, 0);\r
+//     }\r
+//     else {\r
+//             ServiceReportStatus(SERVICE_STOPPED, NO_ERROR, 0);\r
+//     }\r
+//}\r
+//\r
+//void Application::ServiceCtrlHandler(DWORD dwCtrl) {\r
+//     switch(dwCtrl) {\r
+//             case SERVICE_CONTROL_STOP:\r
+//                     ServiceReportStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);\r
+//                     this->GetShutdownEvent().Set();\r
+//                     return;\r
+//\r
+//             case SERVICE_CONTROL_INTERROGATE:\r
+//                     break;\r
+//             default:\r
+//                     break;\r
+//     }\r
+//     ServiceReportStatus(serviceStatus_.dwCurrentState, NO_ERROR, 0);\r
+//}\r
+//void Application::ServiceReportStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint) {\r
+//    static DWORD dwCheckPoint = 1;\r
+//\r
+//    // Fill in the SERVICE_STATUS structure.\r
+//    serviceStatus_.dwCurrentState = dwCurrentState;\r
+//    serviceStatus_.dwWin32ExitCode = dwWin32ExitCode;\r
+//    serviceStatus_.dwWaitHint = dwWaitHint;\r
+//\r
+//    if (dwCurrentState == SERVICE_START_PENDING)\r
+//        serviceStatus_.dwControlsAccepted = 0;\r
+//    else serviceStatus_.dwControlsAccepted = SERVICE_ACCEPT_STOP;\r
+//\r
+//    if ( (dwCurrentState == SERVICE_RUNNING) ||\r
+//           (dwCurrentState == SERVICE_STOPPED) )\r
+//        serviceStatus_.dwCheckPoint = 0;\r
+//    else serviceStatus_.dwCheckPoint = dwCheckPoint++;\r
+//\r
+//    // Report the status of the service to the SCM.\r
+//    SetServiceStatus(svcStatusHandle_, &serviceStatus_);\r
+//}\r
+\r
+///////////////////\r
+// Run as window\r
+int Application::RunAsWindow() {\r
+       if(Initialize() && pWindow_ != 0) {\r
+               MSG msg;\r
+\r
+               while (GetMessage(&msg, NULL, 0, 0))\r
+               {\r
+                       TranslateMessage(&msg);\r
+                       DispatchMessage(&msg);\r
+               }\r
+               return (int)msg.wParam;\r
+\r
+       //      bool bQuit = false;\r
+\r
+       //      while(!bQuit) {\r
+       //              const HANDLE terminateEvent = terminateEvent_;\r
+       //              HRESULT waitResult = MsgWaitForMultipleObjects(1, &terminateEvent, FALSE, 2500, QS_ALLEVENTS);\r
+       //              switch(waitResult) \r
+       //              {\r
+       //              case WAIT_OBJECT_0:\r
+       //                      return 42;\r
+\r
+       //              case WAIT_OBJECT_0+1:\r
+       //                      if(GetMessage(&msg, NULL, 0, 0))\r
+       //                      {\r
+       //                              TranslateMessage(&msg);\r
+       //                              DispatchMessage(&msg);\r
+       //                      }\r
+       //                      else\r
+       //                              return msg.wParam;\r
+\r
+       //              case WAIT_TIMEOUT:\r
+       //                      break;\r
+\r
+       //              case WAIT_FAILED:\r
+       //                      LOG << LogLevel::Critical << "Wait failed in main thread. Exiting";\r
+       //              default:\r
+       //                      return 99;\r
+       //              }\r
+       //      }\r
+       //      return 0;\r
+       }\r
+       return -1;\r
+}\r
+\r
+LRESULT Application::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)\r
+{\r
+       PAINTSTRUCT ps;\r
+       TCHAR timeString[256];\r
+       static int oldyday = 0;\r
+       static UINT_PTR timerID = 0;\r
+       \r
+    switch (message) \r
+    {\r
+               case WM_PAINT:\r
+                       BeginPaint(hWnd, &ps);\r
+                       EndPaint(hWnd, &ps);\r
+                       break;\r
+\r
+               case WM_CREATE: \r
+                       {\r
+                               timerID = SetTimer(hWnd,1,1000,NULL);\r
+                               InvalidateRect(hWnd,NULL,true);\r
+\r
+                               __time64_t timevalue = _time64(NULL);\r
+                               tm timeStruct;\r
+                               _localtime64_s(&timeStruct, &timevalue);\r
+\r
+                               oldyday = timeStruct.tm_yday;\r
+\r
+                               TCHAR logFile[512];\r
+                               _stprintf_s<>(logFile, TEXT("%slog %04d-%02d-%02d.log"), logDir_.c_str(), timeStruct.tm_year + 1900, timeStruct.tm_mon + 1, timeStruct.tm_mday);\r
+                               Logger::GetInstance().SetOutputStream(OutputStreamPtr(new FileOutputStream(logFile, true)));\r
+                       }\r
+                       break;\r
+\r
+               case WM_TIMER:\r
+                       if(wParam == timerID)\r
+                       {\r
+                               __time64_t timevalue = _time64(NULL);\r
+                               tm timeStruct;\r
+                               _localtime64_s(&timeStruct, &timevalue);\r
+\r
+                               if(timeStruct.tm_yday != oldyday)\r
+                               {\r
+                                       LOG << "new day";\r
+\r
+                                       TCHAR logFile[512];\r
+\r
+                                       oldyday = timeStruct.tm_yday;\r
+                                       _stprintf_s<>(logFile, TEXT("%slog %04d-%02d-%02d.log"), logDir_.c_str(), timeStruct.tm_year + 1900, timeStruct.tm_mon + 1, timeStruct.tm_mday);\r
+                                       Logger::GetInstance().SetOutputStream(OutputStreamPtr(new FileOutputStream(logFile, true)));\r
+                               }\r
+                               \r
+#ifdef DISABLE_BLUEFISH\r
+                               const TCHAR* strCompability = TEXT(" (No bluefish)");\r
+#else\r
+                               const TCHAR* strCompability = TEXT("");\r
+#endif\r
+                               _stprintf_s<>(timeString, TEXT("Caspar %s%s - %02d:%02d:%02d"), GetVersionString(), strCompability, timeStruct.tm_hour, timeStruct.tm_min, timeStruct.tm_sec);\r
+                               SetWindowText(pWindow_->getHwnd(), timeString);\r
+                       }\r
+                       break;\r
+                       \r
+               case WM_ENDSESSION:\r
+                       if(wParam == TRUE) {\r
+                               LOG << TEXT("APPLICATION: User shutdown or rebooting system.\r\n\r\n");\r
+                               if(timerID != 0)\r
+                                       KillTimer(hWnd, timerID);\r
+\r
+                               Destroy();\r
+                       }\r
+                       else {\r
+                               LOG << TEXT("APPLICATION: Received ENDSESSION notification.");\r
+                       }\r
+                       break;\r
+\r
+               case WM_SETFOCUS: \r
+                       break;\r
+\r
+               case WM_CHAR:\r
+                       break;\r
+\r
+               case WM_SIZE: \r
+                       break;\r
+\r
+               case WM_DESTROY:\r
+                       if(timerID != 0)\r
+                               KillTimer(hWnd, timerID);\r
+\r
+                       PostQuitMessage(0);\r
+                       break;\r
+               default:\r
+                       return DefWindowProc(hWnd, message, wParam, lParam);\r
+    }\r
+    return 0;\r
+}\r
+\r
+/////////////////////////////\r
+// Application::Initialize\r
+// PARAMS: hinstance(processens instans. Forwardad frÃ¥n WinMain)\r
+// RETURNS: true if every component was successfully initialized.\r
+// COMMENT: Initializes all the components\r
+/////////////////////////////\r
+bool Application::Initialize()\r
+{\r
+#ifdef _DEBUG\r
+       MessageBox(NULL, TEXT("Now is the time to connect for remote debugging..."), TEXT("Debug"), MB_OK | MB_TOPMOST);\r
+#endif\r
+\r
+       try\r
+       {\r
+               _configthreadlocale(_DISABLE_PER_THREAD_LOCALE);\r
+               std::locale::global(std::locale(""));\r
+\r
+               //Hämtar inställningar\r
+               LoadSettings10();\r
+               LoadSettings15();\r
+               LoadSettings17();\r
+               ParseCommandline();\r
+\r
+               if(!CheckDirectories())\r
+                       return false;\r
+\r
+\r
+               Logger::GetInstance().SetLevel(static_cast<LogLevel::LogLevelEnum>(logLevel_ + 1));\r
+\r
+               pWindow_ = WindowPtr(new Window());\r
+               pWindow_->Initialize(hInstance_, TEXT("Caspar"), TEXT("SVT_CASPAR"));\r
+\r
+               if(caspar::flash::FlashAxContainer::CheckForFlashSupport())\r
+                       caspar::CG::FlashCGProxy::SetCGVersion();\r
+               else {\r
+                       LOG << LogLevel::Critical << TEXT("No flashplayer activex-control installed. Flash support will be disabled");\r
+               }\r
+\r
+               caspar::directsound::DirectSoundManager::GetInstance()->Initialize(pWindow_->getHwnd(), 2, 48000, 16);\r
+               pAudioManager_ = caspar::directsound::DirectSoundManager::GetInstance();\r
+\r
+               sourceMediaManagers_.push_back(MediaManagerPtr(new FlashManager()));\r
+               sourceMediaManagers_.push_back(MediaManagerPtr(new CTManager()));\r
+               sourceMediaManagers_.push_back(MediaManagerPtr(new TargaManager()));\r
+               sourceMediaManagers_.push_back(MediaManagerPtr(new TargaScrollMediaManager()));\r
+               sourceMediaManagers_.push_back(MediaManagerPtr(new ffmpeg::FFMPEGManager()));\r
+               sourceMediaManagers_.push_back(MediaManagerPtr(new ColorManager()));\r
+\r
+               colorManagerIndex_ = static_cast<int>(sourceMediaManagers_.size()-1);\r
+\r
+               ////////////////////////////\r
+               // SETUP VideoOut Channels\r
+               int videoChannelIndex = 1;\r
+#ifndef DISABLE_BLUEFISH\r
+               int videoDeviceCount = caspar::bluefish::BlueFishVideoConsumer::EnumerateDevices();\r
+               LOG << TEXT("BLUEFISH: Found ") << videoDeviceCount << TEXT(" video cards.");\r
+\r
+               for(int bluefishIndex = 1; bluefishIndex<=videoDeviceCount; ++bluefishIndex, ++videoChannelIndex) {\r
+                       CreateVideoChannel(videoChannelIndex, caspar::bluefish::BlueFishVideoConsumer::Create(bluefishIndex));\r
+               }\r
+#endif\r
+\r
+               //Decklink\r
+               if(GetSetting(TEXT("nodecklink")) != TEXT("true")) {\r
+                       VideoConsumerPtr pDecklinkConsumer(caspar::decklink::DecklinkVideoConsumer::Create());\r
+                       if(pDecklinkConsumer)\r
+                               CreateVideoChannel(videoChannelIndex++, pDecklinkConsumer);\r
+               }\r
+\r
+               if(GetSetting(TEXT("gdichannel")) == TEXT("true") && pWindow_ != 0) {\r
+                       CreateVideoChannel(videoChannelIndex++, VideoConsumerPtr(new gdi::GDIVideoConsumer(pWindow_->getHwnd(), FrameFormatDescription::FormatDescriptions[FFormat576p2500])));\r
+               }\r
+               else if(GetSetting(TEXT("oglchannel")) == TEXT("true") && pWindow_ != 0)\r
+               {\r
+                       ogl::Stretch stretch = ogl::Fill;\r
+                       tstring stretchStr = GetSetting(TEXT("stretch"));\r
+                       if(stretchStr == TEXT("none"))\r
+                               stretch = ogl::None;\r
+                       else if(stretchStr == TEXT("uniform"))\r
+                               stretch = ogl::Uniform;\r
+                       else if(stretchStr == TEXT("uniformtofill"))\r
+                               stretch = ogl::UniformToFill;\r
+\r
+                       tstring screenStr = GetSetting(TEXT("displaydevice")).c_str();\r
+                       int screen = 0;\r
+                       if(screenStr != TEXT(""))\r
+                               screen = _wtoi(screenStr.c_str());\r
+\r
+                       tstring strVideoMode = GetSetting(TEXT("oglvideomode"));\r
+                       if(strVideoMode == TEXT(""))\r
+                               strVideoMode = GetSetting(TEXT("videomode"));\r
+                       \r
+                       FrameFormat casparVideoFormat = FFormat576p2500;\r
+                       if(strVideoMode != TEXT(""))\r
+                               casparVideoFormat = caspar::GetVideoFormat(strVideoMode);\r
+\r
+                       CreateVideoChannel(videoChannelIndex++, VideoConsumerPtr(new ogl::OGLVideoConsumer(pWindow_->getHwnd(), FrameFormatDescription::FormatDescriptions[casparVideoFormat], screen, stretch)));\r
+               }\r
+\r
+               CreateVideoChannel(videoChannelIndex++, VideoConsumerPtr(new audio::AudioConsumer(FrameFormatDescription::FormatDescriptions[FFormat576p2500])));\r
+               CreateVideoChannel(videoChannelIndex++, VideoConsumerPtr(new audio::AudioConsumer(FrameFormatDescription::FormatDescriptions[FFormat576p2500])));\r
+\r
+               if(videoChannels_.size() < 1)\r
+               {\r
+                       LOG << TEXT("No channels found, quitting");\r
+                       return false;\r
+               }\r
+\r
+               //////////////////////\r
+               // Setup controllers\r
+               SetupControllers();\r
+\r
+               ///////////////////////////\r
+               // Initiate videochannels\r
+               for(unsigned int i=0;i<videoChannels_.size();++i) {\r
+                       ChannelPtr pChannel = GetChannel(i);\r
+\r
+                       if(pChannel != 0) {\r
+                               pChannel->Clear();\r
+                       }\r
+               }\r
+       }\r
+       catch(const std::exception& ex) {\r
+               LOG << LogLevel::Critical << TEXT("Initialization exception: ") << ex.what();\r
+               MessageBoxA(NULL, ex.what(), "Error", MB_OK | MB_TOPMOST);\r
+               return false;\r
+       }\r
+\r
+       LOG << TEXT("Successful initialization.");\r
+       return true;\r
+}\r
+\r
+/////////////////////////////////////////\r
+// Application::Destroy\r
+// COMMENT: shuts down all the components in the correct order\r
+void Application::Destroy() {\r
+       //First kill all possibilities for new commands to arrive...\r
+       controllers_.clear();\r
+\r
+       //...Then shutdown all channels, stopping playback etc...\r
+       videoChannels_.clear();\r
+\r
+       //...finally delete all mediamanagers\r
+       sourceMediaManagers_.clear();\r
+\r
+       LOG << TEXT("Shutdown complete.\r\n\r\n");\r
+}\r
+\r
+/////////////////////////////////////\r
+// Application::CreateVideoChannel\r
+// PARAMS: index(each channel has to have a unique index), videoConsumer(the consumer)\r
+// COMMENT: Creates a channel and connects a consumer to it\r
+void Application::CreateVideoChannel(int index, VideoConsumerPtr pVideoConsumer) {\r
+       if(pVideoConsumer != 0) {\r
+               ChannelPtr pChannel(new Channel(index, pVideoConsumer));\r
+               if(pChannel != 0 && pChannel->Initialize()) {\r
+                       videoChannels_.push_back(pChannel);\r
+               }\r
+               else {\r
+                       LOG << TEXT("Failed to create channel ") <<  index;\r
+               }\r
+       }\r
+       else {\r
+               LOG << TEXT("Failed to create consumer for channel ") << index << TEXT(". Removing channel completely.");\r
+       }\r
+}\r
+\r
+//////////////////////////////////\r
+// Application::GetChannel\r
+// PARAM: deviceIndex(the index of the requested channel)\r
+// RETURNS: a (smart)pointer to the requested channel.\r
+ChannelPtr Application::GetChannel(unsigned int deviceIndex) {\r
+       ChannelPtr result;\r
+       if(deviceIndex < videoChannels_.size())\r
+               result = videoChannels_[deviceIndex];\r
+\r
+       return result;\r
+}\r
+\r
+/////////////////////////////\r
+// Application::FindFile\r
+// PARAM: filename(fileame without the ending), pFileInfo(pointer to a structure that should be populated with info about the file)\r
+// RETURNS: (smart)pointer to the MediaManager that handles the specified file\r
+// COMMENT: Checks if the file exists and if it can be opened by any of the active mediamanagers.\r
+MediaManagerPtr Application::FindMediaFile(const tstring& filename, FileInfo* pFileInfo)\r
+{\r
+       for(unsigned int index=0;index<sourceMediaManagers_.size();++index)\r
+       {\r
+               const std::vector<tstring>* pExtensions;\r
+               int extensionCount = sourceMediaManagers_[index]->GetSupportedExtensions(pExtensions);\r
+               for(int extensionIndex=0; extensionIndex<extensionCount; ++extensionIndex)\r
+               {\r
+                       tstring fullFilename = filename;\r
+                       if((*pExtensions)[extensionIndex].length() > 0) {\r
+                               fullFilename += TEXT('.');\r
+                               fullFilename += (*pExtensions)[extensionIndex];\r
+                       }\r
+\r
+                       WIN32_FIND_DATA findInfo;\r
+                       FindWrapper findWrapper(fullFilename, &findInfo);\r
+                       if(findWrapper.Success()) {\r
+                               if(pFileInfo != 0) {\r
+                                       pFileInfo->filename = filename;\r
+                                       pFileInfo->filetype = (*pExtensions)[extensionIndex];\r
+\r
+                                       unsigned __int64 fileSize = findInfo.nFileSizeHigh;\r
+                                       fileSize *= 0x100000000;\r
+                                       fileSize += findInfo.nFileSizeLow;\r
+\r
+                                       pFileInfo->size = fileSize;\r
+                               }\r
+\r
+                               return sourceMediaManagers_[index];\r
+                       }\r
+               }\r
+       }\r
+\r
+       return MediaManagerPtr();\r
+}\r
+\r
+bool Application::FindTemplate(const tstring& templateName, tstring* pExtension) {\r
+       bool bResult = exists(templateName + TEXT(".ft"));\r
+       if(bResult) {\r
+               if(pExtension != NULL)\r
+                       *pExtension = TEXT(".ft");\r
+       }\r
+       else {\r
+               bResult = exists(templateName + TEXT(".ct"));\r
+               if(bResult && pExtension != NULL)\r
+                       *pExtension = TEXT(".ct");\r
+       }\r
+       return bResult;\r
+}\r
+\r
+void Application::SetupControllers()\r
+{\r
+       HKEY hKey = 0;\r
+       HKEY hSubkey = 0;\r
+       try {\r
+               if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Sveriges Television AB\\Caspar CG\\Controllers"), 0,KEY_READ, &hKey) == ERROR_SUCCESS)\r
+               {\r
+                       DWORD keyCount = 0;\r
+                       if(RegQueryInfoKey(hKey, NULL, NULL, NULL, &keyCount, NULL, NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) {\r
+                               tstring subkeyName = TEXT("0");\r
+                               for(DWORD keyIndex = 0; keyIndex < min(keyCount, 10); ++keyIndex) {\r
+                                       subkeyName[0] = TEXT('0')+static_cast<TCHAR>(keyIndex);\r
+\r
+                                       if(RegOpenKeyEx(hKey, subkeyName.c_str(), 0, KEY_READ, &hSubkey) == ERROR_SUCCESS) {\r
+                                               DWORD protocolIndex = 0, transportIndex = 0;\r
+                                               DWORD size = 0;\r
+                                               LONG returnValue = 0;\r
+\r
+                                               size = sizeof(DWORD);\r
+                                               returnValue = RegQueryValueEx(hSubkey, TEXT("transport"), 0, 0, (BYTE*)&transportIndex, &size);\r
+                                               if(returnValue != ERROR_SUCCESS || transportIndex >= TransportsCount)\r
+                                                       continue;\r
+\r
+                                               size = sizeof(DWORD);\r
+                                               returnValue = RegQueryValueEx(hSubkey, TEXT("protocol"), 0, 0, (BYTE*)&protocolIndex, &size);\r
+                                               if(returnValue != ERROR_SUCCESS || protocolIndex >= ProtocolsCount)\r
+                                                       continue;\r
+\r
+                                               //Setup controller\r
+                                               ControllerPtr pController;\r
+                                               switch(transportIndex) {\r
+                                                       case TCP:\r
+                                                               pController = CreateTCPController(hSubkey);\r
+                                                               break;\r
+                                                       case Serial:\r
+                                                               pController = CreateSerialController(hSubkey);\r
+                                                               break;\r
+                                               }\r
+\r
+                                               if(pController != 0) {\r
+                                                       //there is a Controller, create ProtocolStrategy\r
+                                                       caspar::IO::ProtocolStrategyPtr pProtocol;\r
+                                                       switch(protocolIndex) {\r
+                                                               case AMCP:\r
+                                                                       pProtocol = caspar::IO::ProtocolStrategyPtr(new caspar::amcp::AMCPProtocolStrategy());\r
+                                                                       break;\r
+                                                               case CII:\r
+                                                                       pProtocol = caspar::IO::ProtocolStrategyPtr(new caspar::cii::CIIProtocolStrategy());\r
+                                                                       break;\r
+                                                               case CLOCK:\r
+                                                                       pProtocol = caspar::IO::ProtocolStrategyPtr(new caspar::CLK::CLKProtocolStrategy());\r
+                                                                       break;\r
+                                                       }\r
+\r
+                                                       if(pProtocol != 0) {\r
+                                                               //Both Controller and ProtocolStrategy created. Initialize!\r
+                                                               pController->SetProtocolStrategy(pProtocol);\r
+                                                               if(pController->Start())\r
+                                                                       controllers_.push_back(pController);\r
+                                                               else {\r
+                                                                       LOG << TEXT("Failed to start controller.");\r
+                                                               }\r
+                                                       }\r
+                                                       else {\r
+                                                               LOG << TEXT("failed to create protocol.");\r
+                                                       }\r
+                                               }\r
+                                               else {\r
+                                                       LOG << TEXT("Failed to create controller.");\r
+                                               }\r
+                                               \r
+                                               RegCloseKey(hSubkey);\r
+                                               hSubkey = 0;\r
+                                       }\r
+                                       else {\r
+                                               LOG << TEXT("Failed to read controller-settings.");\r
+                                       }\r
+                               }\r
+                       }\r
+                       RegCloseKey(hKey);\r
+               }\r
+               else {\r
+                       LOG << TEXT("Failed to read controller-settings.");\r
+               }\r
+       }\r
+       catch(std::exception&) {\r
+               if(hSubkey != 0)\r
+                       RegCloseKey(hSubkey);\r
+\r
+               if(hKey != 0)\r
+                       RegCloseKey(hKey);\r
+       }\r
+}\r
+\r
+ControllerPtr Application::CreateTCPController(HKEY hSubkey) {\r
+       DWORD port = 5250;\r
+\r
+       //read port setting\r
+       DWORD size = sizeof(DWORD);\r
+       RegQueryValueEx(hSubkey, TEXT("TCPPort"), 0, 0, (BYTE*)&port, &size);\r
+\r
+       ControllerPtr pAsyncEventServer(new caspar::IO::AsyncEventServer(port));\r
+       dynamic_cast<caspar::IO::AsyncEventServer*>(pAsyncEventServer.get())->SetClientDisconnectHandler(std::tr1::bind(&Application::OnClientDisconnected, this, std::tr1::placeholders::_1));\r
+\r
+       return pAsyncEventServer;\r
+}\r
+\r
+ControllerPtr Application::CreateSerialController(HKEY hSubkey)\r
+{\r
+       DWORD baudRate = 19200;\r
+       DWORD dataBits = 8;\r
+       DWORD parity = NOPARITY;\r
+       DWORD stopBits = ONESTOPBIT;\r
+       tstring portName;\r
+       TCHAR pPortname[256];\r
+       ZeroMemory(pPortname, sizeof(pPortname));\r
+\r
+       //read baudrate setting\r
+       DWORD size = sizeof(DWORD);\r
+       RegQueryValueEx(hSubkey, TEXT("SerialBaudrate"), 0, 0, (BYTE*)&baudRate, &size);\r
+\r
+       //read databits setting\r
+       size = sizeof(DWORD);\r
+       RegQueryValueEx(hSubkey, TEXT("SerialDatabits"), 0, 0, (BYTE*)&dataBits, &size);\r
+\r
+       //read parity setting\r
+       size = sizeof(DWORD);\r
+       RegQueryValueEx(hSubkey, TEXT("SerialParity"), 0, 0, (BYTE*)&parity, &size);\r
+\r
+       //read stopbits setting\r
+       size = sizeof(DWORD);\r
+       RegQueryValueEx(hSubkey, TEXT("SerialStopbits"), 0, 0, (BYTE*)&stopBits, &size);\r
+\r
+       //read portname setting\r
+       size = sizeof(pPortname) - sizeof(TCHAR);\r
+       LONG returnValue = RegQueryValueEx(hSubkey, TEXT("SerialPortname"), 0, 0, (BYTE*)pPortname, &size);\r
+       if(returnValue == ERROR_SUCCESS && size > 0)\r
+               portName = pPortname;\r
+\r
+       return ControllerPtr(new caspar::IO::SerialPort(baudRate, static_cast<BYTE>(parity), static_cast<BYTE>(dataBits), static_cast<BYTE>(stopBits), portName));\r
+}\r
+\r
+void Application::OnClientDisconnected(caspar::IO::SocketInfoPtr pClient) \r
+{\r
+       Monitor::ClearListener(pClient);\r
+}\r
+\r
+//////////////////////////////////\r
+// Application::LoadSetting10\r
+bool Application::LoadSettings10()\r
+{\r
+       HKEY hKey;\r
+       if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Sveriges Television AB\\Caspar CG\\1.0"), 0,KEY_READ, &hKey) == ERROR_SUCCESS)\r
+       {\r
+               TCHAR pString[512];\r
+\r
+               //read media-folder setting\r
+               DWORD size = sizeof(pString) - sizeof(TCHAR);\r
+               LONG returnValue = RegQueryValueEx(hKey, TEXT("MediaFolder"), 0, 0, (BYTE*)pString, &size);\r
+               if(returnValue == ERROR_SUCCESS && size > 0)\r
+                       videoDir_ = pString;\r
+\r
+               //read log-folder setting\r
+               size = sizeof(pString) - sizeof(TCHAR);\r
+               returnValue = RegQueryValueEx(hKey, TEXT("LogFolder"), 0, 0, (BYTE*)pString, &size);\r
+               if(returnValue == ERROR_SUCCESS && size > 0)\r
+                       logDir_ = pString;\r
+\r
+               //read loglevel\r
+               size = sizeof(int);\r
+               returnValue = RegQueryValueEx(hKey, TEXT("LogLevel"), 0, 0, (BYTE*)&logLevel_, &size);\r
+\r
+               //close handle after all settings have been saved\r
+               RegCloseKey(hKey);\r
+       }\r
+       else {\r
+               LOG << TEXT("No 1.0 settings defined. Using defaults.");\r
+       }\r
+\r
+       return true;\r
+}\r
+\r
+//////////////////////////////////\r
+// Application::LoadSetting15\r
+bool Application::LoadSettings15()\r
+{\r
+       HKEY hKey;\r
+       if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Sveriges Television AB\\Caspar CG\\1.5"), 0,KEY_READ, &hKey) == ERROR_SUCCESS)\r
+       {\r
+               TCHAR pString[512];\r
+\r
+               //read template-folder setting\r
+               DWORD size = sizeof(pString) - sizeof(TCHAR);\r
+               LONG returnValue = RegQueryValueEx(hKey, TEXT("TemplateFolder"), 0, 0, (BYTE*)pString, &size);\r
+               if(returnValue == ERROR_SUCCESS && size > 0)\r
+                       templateDir_ = pString;\r
+\r
+               //close handle after all settings have been saved\r
+               RegCloseKey(hKey);\r
+       }\r
+       else {\r
+               LOG << TEXT("No 1.5 settings defined. Using defaults.");\r
+       }\r
+\r
+       return true;\r
+}\r
+\r
+//////////////////////////////////\r
+// Application::LoadSetting17\r
+bool Application::LoadSettings17()\r
+{\r
+       HKEY hKey;\r
+       if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Sveriges Television AB\\Caspar CG\\1.7"), 0,KEY_READ, &hKey) == ERROR_SUCCESS)\r
+       {\r
+               TCHAR pString[512];\r
+\r
+               //read data-folder setting\r
+               DWORD size = sizeof(pString) - sizeof(TCHAR);\r
+               LONG returnValue = RegQueryValueEx(hKey, TEXT("DataFolder"), 0, 0, (BYTE*)pString, &size);\r
+               if(returnValue == ERROR_SUCCESS && size > 0)\r
+                       dataDir_ = pString;\r
+\r
+               //close handle after all settings have been saved\r
+               RegCloseKey(hKey);\r
+       }\r
+       else {\r
+               LOG << TEXT("No 1.7 settings defined. Using defaults.");\r
+       }\r
+\r
+       return true;\r
+}\r
+\r
+bool Application::CheckDirectories()\r
+{\r
+       bool returnValue = true;\r
+\r
+       if(logDir_.size() == 0) {\r
+               TCHAR pString[512];\r
+               if(_tgetcwd(pString, _MAX_PATH+1)) {\r
+                       logDir_ = pString;\r
+                       logDir_ += TEXT("\\log");\r
+                       _tmkdir(logDir_.c_str());\r
+               }\r
+       }\r
+\r
+       if(!CheckDirectory(logDir_)) {\r
+               LOG << TEXT("Failed to aquire log-folder, logging to c:\\");\r
+               logDir_ = TEXT("c:\\");\r
+       }\r
+\r
+       if(!CheckDirectory(videoDir_)) {\r
+               LOG << TEXT("Media-folder does not exists");\r
+               tstring error = TEXT("Kunde inte hitta mediafolder. ");\r
+               error += videoDir_;\r
+               MessageBox(NULL, error.c_str(), TEXT("Kritiskt fel"), MB_OK);\r
+               returnValue = false;\r
+       }\r
+\r
+       if(!CheckDirectory(templateDir_)) {\r
+               LOG << TEXT("Template-folder does not exists");\r
+               tstring error = TEXT("Kunde inte hitta templatefolder. ");\r
+               error += templateDir_;\r
+               MessageBox(NULL, error.c_str(), TEXT("Kritiskt fel"), MB_OK);\r
+               returnValue = false;\r
+       }\r
+\r
+       if(returnValue) {\r
+               if(!CheckDirectory(dataDir_)) {\r
+                       LOG << TEXT("Data-folder does not exists, default to same as media-folder");\r
+                       dataDir_ = videoDir_;\r
+               }\r
+       }\r
+\r
+       LOG << TEXT("Media-folder: ") << videoDir_.c_str();\r
+       LOG << TEXT("Template-folder: ") << templateDir_.c_str();\r
+       LOG << TEXT("Log-folder: ") << logDir_.c_str();\r
+       LOG << TEXT("Data-folder: ") << dataDir_.c_str();\r
+\r
+       return returnValue;\r
+}\r
+\r
+bool Application::CheckDirectory(tstring& directory) {\r
+       if(directory.size() == 0 || !exists(directory, true))\r
+               return false;\r
+\r
+       bool bIsRelative = false;\r
+       if(directory.size() >= 2) {\r
+               if(directory[1] != TEXT(':')) {\r
+                       bIsRelative = true;\r
+               }\r
+       }\r
+       else \r
+               bIsRelative = true;\r
+\r
+       if(bIsRelative) {\r
+               TCHAR pCurrentWorkingDirectory[_MAX_PATH+1];\r
+               if(_tgetcwd(pCurrentWorkingDirectory, _MAX_PATH)) {\r
+                       tstring fullPath = pCurrentWorkingDirectory;\r
+                       fullPath.push_back(TEXT('\\'));\r
+                       fullPath.append(directory);\r
+                       directory = fullPath;\r
+               }\r
+       }\r
+\r
+       if(directory[directory.size()-1] != TEXT('\\'))\r
+               directory += '\\';\r
+\r
+       return true;\r
+}\r
+\r
+///////////////////////////\r
+//\r
+// Commandline parameters\r
+//\r
+// hd=[720p50, 1080i50] chooses hd-mode for videochannels if availible\r
+// spy{=true} instructs the serialport to NOT SEND ANYTHING\r
+// internalkey(=true) instructs the videochannels to perform internal keying if availible\r
+void Application::ParseCommandline() {\r
+       tstring currentToken = TEXT("");\r
+       tstring lastKey = TEXT("");\r
+\r
+       bool inValue=false, inQuote=false;\r
+\r
+       unsigned int charIndex = 0;\r
+       for(charIndex = 0; charIndex < commandline_.size(); ++charIndex) {\r
+               TCHAR ch = commandline_[charIndex];\r
+               switch(ch) {\r
+                       case TEXT('\"'):\r
+                               inQuote = !inQuote;\r
+                               if(currentToken.size() > 0) {\r
+                                       if(inValue) {\r
+                                               settings_.insert(SettingsMap::value_type(lastKey, currentToken));\r
+                                               lastKey.clear();\r
+                                               inValue = false;\r
+                                       }\r
+                                       else {\r
+                                               settings_.insert(SettingsMap::value_type(currentToken, TEXT("true")));\r
+                                       }\r
+\r
+                                       currentToken.clear();\r
+                               }\r
+                               break;\r
+\r
+                       case TEXT('='):\r
+                               if(currentToken.size() > 0) {\r
+                                       lastKey = currentToken;\r
+                                       currentToken.clear();\r
+                                       inValue = true;\r
+                               }\r
+                               break;\r
+\r
+                       case TEXT(' '):\r
+                               if(inQuote)\r
+                                       currentToken += ch;\r
+                               else {\r
+                                       if(currentToken.size() > 0) {\r
+                                               if(inValue) {\r
+                                                       settings_.insert(SettingsMap::value_type(lastKey, currentToken));\r
+                                                       lastKey.clear();\r
+                                                       inValue = false;\r
+                                               }\r
+                                               else {\r
+                                                       settings_.insert(SettingsMap::value_type(currentToken, TEXT("true")));\r
+                                               }\r
+\r
+                                               currentToken.clear();\r
+                                       }\r
+                               }\r
+                               break;\r
+\r
+                       default:\r
+                               currentToken += ch;\r
+                               break;\r
+               }\r
+       }\r
+\r
+       if(currentToken.size() > 0) {\r
+               if(inValue) {\r
+                       settings_.insert(SettingsMap::value_type(lastKey, currentToken));\r
+               }\r
+               else {\r
+                       settings_.insert(SettingsMap::value_type(currentToken, TEXT("true")));\r
+               }\r
+       }\r
+}\r
+\r
+tstring Application::GetSetting(const tstring& key) {\r
+       SettingsMap::iterator it = settings_.find(key);\r
+       if(it != settings_.end())\r
+               return (*it).second;\r
+       else\r
+               return TEXT("");\r
+}\r
+\r
+//////////////////////////////\r
+// ServiceHelpers\r
+\r
+void Application::InstallService() \r
+{\r
+       tstringstream message;\r
+    SC_HANDLE schSCManager;\r
+       SC_HANDLE schService;\r
+       TCHAR szPath[MAX_PATH];\r
+\r
+       if(!GetModuleFileName(NULL, szPath, MAX_PATH)) {\r
+               message << TEXT("Error: ") << GetLastError();\r
+               MessageBox(NULL, message.str().c_str(), TEXT("Cannot install service"), MB_OK);\r
+        return;\r
+       }\r
+\r
+       // Get a handle to the SCM database. \r
+       schSCManager = OpenSCManager( \r
+               NULL,                    // local computer\r
+               NULL,                    // ServicesActive database \r
+               SC_MANAGER_ALL_ACCESS);  // full access rights \r
+\r
+       if(schSCManager == NULL) {\r
+               message << TEXT("OpenSCManager failed. Error: ") << GetLastError();\r
+               MessageBox(NULL, message.str().c_str(), TEXT("Cannot install service"), MB_OK);\r
+               return;\r
+       }\r
+\r
+       // Create the service\r
+       tstring imagePath(szPath);\r
+       imagePath.append(TEXT(" service"));\r
+\r
+       schService = CreateService( \r
+               schSCManager,              // SCM database \r
+               serviceName_,              // name of service \r
+               serviceName_,              // service name to display \r
+               SERVICE_ALL_ACCESS,        // desired access \r
+               SERVICE_WIN32_OWN_PROCESS, // service type \r
+               SERVICE_DEMAND_START,      // start type \r
+               SERVICE_ERROR_NORMAL,      // error control type \r
+               imagePath.c_str(),         // path to service's binary \r
+               NULL,                      // no load ordering group \r
+               NULL,                      // no tag identifier \r
+               NULL,                      // no dependencies \r
+               NULL,                      // LocalSystem account \r
+               NULL);                     // no password \r
+\r
+       if(schService == NULL) {\r
+               message << TEXT("CreateService failed. Error: ") << GetLastError(); \r
+               CloseServiceHandle(schSCManager);\r
+               MessageBox(NULL, message.str().c_str(), TEXT("Cannot install service"), MB_OK);\r
+               return;\r
+    }\r
+    else\r
+               MessageBox(NULL, TEXT("Service installed successfully"), TEXT("Done!"), MB_OK);\r
+\r
+    CloseServiceHandle(schService); \r
+    CloseServiceHandle(schSCManager);\r
+}\r
+\r
+void Application::UninstallService()\r
+{\r
+       tstringstream message;\r
+    SC_HANDLE schSCManager;\r
+    SC_HANDLE schService;\r
+\r
+    // Get a handle to the SCM database. \r
+    schSCManager = OpenSCManager( \r
+        NULL,                    // local computer\r
+        NULL,                    // ServicesActive database \r
+        SC_MANAGER_ALL_ACCESS);  // full access rights \r
\r
+    if(schSCManager == NULL){\r
+               message << TEXT("OpenSCManager failed. Error: ") << GetLastError();\r
+               MessageBox(NULL, message.str().c_str(), TEXT("Cannot uninstall service"), MB_OK);\r
+        return;\r
+    }\r
+\r
+    // Get a handle to the service.\r
+    schService = OpenService( \r
+        schSCManager,         // SCM database \r
+        serviceName_,  // name of service \r
+        DELETE);              // need delete access \r
\r
+    if (schService == NULL)\r
+    { \r
+               message << TEXT("OpenService failed. Error: ") << GetLastError();\r
+               MessageBox(NULL, message.str().c_str(), TEXT("Cannot uninstall service"), MB_OK);\r
+        CloseServiceHandle(schSCManager);\r
+        return;\r
+    }\r
+\r
+    // Delete the service.\r
+    if (!DeleteService(schService)) \r
+    {\r
+               message << TEXT("DeleteService failed. Error: ") << GetLastError();\r
+               MessageBox(NULL, message.str().c_str(), TEXT("Cannot uninstall service"), MB_OK);\r
+    }\r
+    else\r
+               MessageBox(NULL, TEXT("Service uninstalled successfully"), TEXT("Done!"), MB_OK);\r
+\r
+    CloseServiceHandle(schService); \r
+    CloseServiceHandle(schSCManager);\r
+}\r
+\r
+}
\ No newline at end of file
diff --git a/server/Application.h b/server/Application.h
new file mode 100644 (file)
index 0000000..739c1dc
--- /dev/null
@@ -0,0 +1,170 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _CASPAR_APPLICATION_H__\r
+#define _CASPAR_APPLICATION_H__\r
+\r
+#pragma once\r
+\r
+#include "Window.h"\r
+#include "Controller.h"\r
+#include "MediaManager.h"\r
+#include "audio\audiomanager.h"\r
+#include "utils\event.h"\r
+#include "io\socketInfo.h"\r
+\r
+#include <string>\r
+#include <vector>\r
+#include <list>\r
+#include <map>\r
+\r
+#include <boost/lexical_cast.hpp>\r
+\r
+namespace caspar {\r
+\r
+       class Channel;\r
+       typedef std::tr1::shared_ptr<Channel> ChannelPtr;\r
+\r
+       class IVideoConsumer;\r
+       typedef std::tr1::shared_ptr<IVideoConsumer> VideoConsumerPtr;\r
+\r
+       class FileInfo;\r
+\r
+       class Application\r
+       {\r
+       public:\r
+               explicit Application(const tstring& cmdline, HINSTANCE);\r
+               ~Application();\r
+\r
+               static void InstallService();\r
+               static void UninstallService();\r
+               \r
+               void RunAsService();\r
+               int RunAsWindow();\r
+\r
+               //void ServiceMain();\r
+               //void ServiceCtrlHandler(DWORD dwCtrl);\r
+\r
+               LRESULT WndProc(HWND, UINT, WPARAM, LPARAM);\r
+\r
+               const TCHAR* GetVersionString() const {\r
+                       return versionString_;\r
+               }\r
+               WindowPtr& GetMainWindow() {\r
+                       return pWindow_;\r
+               }\r
+               caspar::audio::IAudioManager* GetAudioManager() {\r
+                       return pAudioManager_;\r
+               }\r
+               const tstring& GetMediaFolder() {\r
+                       return videoDir_;\r
+               }\r
+               const tstring& GetTemplateFolder() {\r
+                       return templateDir_;\r
+               }\r
+               const tstring& GetDataFolder() {\r
+                       return dataDir_;\r
+               }\r
+\r
+               ChannelPtr GetChannel(unsigned int deviceIndex);\r
+\r
+               bool FindTemplate(const tstring& templateName, tstring* pExtension = NULL);\r
+               MediaManagerPtr FindMediaFile(const tstring& filename, FileInfo* pFileInfo=0);\r
+               MediaManagerPtr GetColorMediaManager() {\r
+                       if(colorManagerIndex_ != -1)\r
+                               return sourceMediaManagers_[colorManagerIndex_];\r
+                       else \r
+                               return MediaManagerPtr();\r
+               }\r
+\r
+               tstring GetSetting(const tstring& key);\r
+\r
+               template <typename T>\r
+               T GetSetting(const std::wstring& key, T defaultValue)\r
+               {\r
+                       try\r
+                       {\r
+                               std::wstring str = GetSetting(key);\r
+                               if(!str.empty())\r
+                                       return boost::lexical_cast<T>(str);\r
+                       }\r
+                       catch(...){}\r
+                       return defaultValue;\r
+               }\r
+\r
+               utils::Event& GetTerminateEvent() { return terminateEvent_; }\r
+               //utils::Event& GetStopEvent() { return stopEvent_; }\r
+\r
+       private:\r
+               bool Initialize();\r
+               void Destroy();\r
+\r
+               typedef std::map<tstring, tstring> SettingsMap;\r
+\r
+               void CreateVideoChannel(int index, VideoConsumerPtr videoConsumer);\r
+               ControllerPtr CreateTCPController(HKEY);\r
+               ControllerPtr CreateSerialController(HKEY);\r
+\r
+               bool LoadSettings10();\r
+               bool LoadSettings15();\r
+               bool LoadSettings17();\r
+               void ParseCommandline();\r
+\r
+               bool CheckDirectories();\r
+               bool CheckDirectory(tstring& directory);\r
+\r
+               void SetupControllers();\r
+               void OnClientDisconnected(caspar::IO::SocketInfoPtr);\r
+\r
+               WindowPtr                                                       pWindow_;\r
+\r
+               std::vector<ChannelPtr>         videoChannels_;\r
+               std::vector<MediaManagerPtr>    sourceMediaManagers_;\r
+               std::vector<ControllerPtr>                      controllers_;\r
+\r
+               caspar::audio::IAudioManager*           pAudioManager_;\r
+\r
+               //Once the program is initiated, these directories are guaranteed to have a trailing '\'\r
+               tstring         videoDir_;\r
+               tstring         templateDir_;\r
+               tstring         logDir_;\r
+               tstring         dataDir_;\r
+\r
+               int                             logLevel_;\r
+               static const TCHAR*     versionString_;\r
+               \r
+               static const TCHAR*     serviceName_;\r
+               //SERVICE_STATUS_HANDLE   svcStatusHandle_;\r
+               //SERVICE_STATUS                        serviceStatus_;\r
+               //void ServiceReportStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint);\r
+\r
+               int                             colorManagerIndex_;\r
+               utils::Event    terminateEvent_;\r
+               //utils::Event  stopEvent_;\r
+\r
+               HINSTANCE hInstance_;\r
+               tstring commandline_;\r
+               SettingsMap settings_;\r
+\r
+       };\r
+\r
+}      //namespace caspar\r
+\r
+#endif //_CASPAR_APPLICATION_H__
\ No newline at end of file
diff --git a/server/CLK/CLKCommand.cpp b/server/CLK/CLKCommand.cpp
new file mode 100644 (file)
index 0000000..254e866
--- /dev/null
@@ -0,0 +1,94 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\stdafx.h"\r
+#include <algorithm>\r
+#include <locale>\r
+#include "CLKCommand.h"\r
+\r
+namespace caspar {\r
+namespace CLK {\r
+\r
+CLKCommand::CLKCommand() : clockID_(0), command_(CLKInvalidCommand) {\r
+}\r
+\r
+CLKCommand::~CLKCommand() {\r
+}\r
+\r
+const tstring& CLKCommand::GetData() {\r
+       tstringstream dataStream;\r
+\r
+       dataStream << TEXT("<templateData>");   \r
+       dataStream << TEXT("<componentData id=\"command\">");\r
+       dataStream << TEXT("<command id=\"") << commandString_ << TEXT("\" time=\"") << time_ << TEXT("\" clockID=\"") << clockID_ << TEXT("\">");\r
+\r
+       std::vector<tstring>::const_iterator it = parameters_.begin();\r
+       std::vector<tstring>::const_iterator end = parameters_.end();\r
+       for(; it != end; ++it) {\r
+               dataStream << TEXT("<parameter>") << (*it) << TEXT("</parameter>"); \r
+       }\r
+\r
+       dataStream << TEXT("</command>"); \r
+       dataStream << TEXT("</componentData>"); \r
+       dataStream << TEXT("</templateData>");\r
+\r
+       dataCache_ = dataStream.str();\r
+       return dataCache_;\r
+}\r
+\r
+bool CLKCommand::SetCommand() {\r
+       bool bResult = true;\r
+       std::transform(commandString_.begin(), commandString_.end(), commandString_.begin(), toupper);\r
+\r
+       if(commandString_ == TEXT("DUR"))\r
+               command_ = CLKDuration;\r
+       else if(commandString_ == TEXT("NEWDUR"))\r
+               command_ = CLKNewDuration;\r
+       else if(commandString_ == TEXT("NEXTEVENT"))\r
+               command_ = CLKNextEvent;\r
+       else if(commandString_ == TEXT("STOP"))\r
+               command_ = CLKStop;\r
+       else if(commandString_ == TEXT("UNTIL"))\r
+               command_ = CLKUntil;\r
+       else if(commandString_ == TEXT("ADD"))\r
+               command_ = CLKAdd;\r
+       else if(commandString_ == TEXT("SUB"))\r
+               command_ = CLKSub;\r
+       else if(commandString_ == TEXT("RESET"))\r
+               command_ = CLKReset;\r
+       else {\r
+               command_ = CLKInvalidCommand;\r
+               bResult = false;\r
+       }\r
+\r
+       return bResult;\r
+}\r
+\r
+void CLKCommand::Clear() {\r
+       dataCache_.clear();\r
+       commandString_.clear();\r
+       time_.clear();\r
+       command_ = CLKDuration;\r
+       clockID_ = 0;\r
+       parameters_.clear();\r
+}\r
+\r
+}      //namespace CLK\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/CLK/CLKCommand.h b/server/CLK/CLKCommand.h
new file mode 100644 (file)
index 0000000..20cc543
--- /dev/null
@@ -0,0 +1,66 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+\r
+#include <vector>\r
+#include <string>\r
+\r
+namespace caspar {\r
+namespace CLK {\r
+\r
+class CLKCommand\r
+{\r
+public:\r
+       enum CLKCommands {\r
+               CLKDuration,\r
+               CLKNewDuration,\r
+               CLKNextEvent,\r
+               CLKStop,\r
+               CLKUntil,\r
+               CLKAdd,\r
+               CLKSub,\r
+               CLKReset,\r
+               CLKInvalidCommand\r
+       };\r
+\r
+       CLKCommand();\r
+       virtual ~CLKCommand();\r
+\r
+       bool SetCommand();\r
+       bool NeedsTime() const {\r
+               return !(command_ == CLKNextEvent || command_ == CLKStop);\r
+       }\r
+       void Clear();\r
+       const tstring& GetData();\r
+\r
+       tstring dataCache_;\r
+       tstring commandString_;\r
+       CLKCommands command_;\r
+       int clockID_;\r
+       tstring time_;\r
+       std::vector<tstring> parameters_;\r
+\r
+\r
+\r
+};\r
+\r
+}      //namespace CLK\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/CLK/CLKProtocolStrategy.cpp b/server/CLK/CLKProtocolStrategy.cpp
new file mode 100644 (file)
index 0000000..40903b3
--- /dev/null
@@ -0,0 +1,144 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\StdAfx.h"\r
+\r
+#include <string>\r
+#include <sstream>\r
+#include <algorithm>\r
+#include "CLKProtocolStrategy.h"\r
+#include "..\CG\CGControl.h"\r
+#include "..\producers\flash\FlashManager.h"\r
+#include "..\application.h"\r
+#include "..\fileinfo.h"\r
+\r
+namespace caspar {\r
+namespace CLK {\r
+\r
+using namespace utils;\r
+\r
+CLKProtocolStrategy::CLKProtocolStrategy() : currentState_(ExpectingNewCommand), bClockLoaded_(false) {\r
+       pChannel_ = GetApplication()->GetChannel(0);\r
+       pCGControl_ = pChannel_->GetCGControl();\r
+}\r
+\r
+CLKProtocolStrategy::~CLKProtocolStrategy() {\r
+}\r
+\r
+void CLKProtocolStrategy::Parse(const TCHAR* pData, int charCount, caspar::IO::ClientInfoPtr pClientInfo) {\r
+       for(int index=0; index < charCount; ++index) {\r
+               if(currentState_ == ExpectingNewCommand)\r
+                       currentCommandString_.str(TEXT(""));\r
+\r
+               TCHAR currentByte = pData[index];\r
+               if(currentByte < 32)\r
+                       currentCommandString_ << TEXT("<") << (int)currentByte << TEXT(">");\r
+               else\r
+                       currentCommandString_ << currentByte;\r
+\r
+               if(currentByte != 0) {\r
+                       switch(currentState_) {\r
+                               case ExpectingNewCommand:\r
+                                       if(currentByte == 1) {\r
+                                               currentState_ = ExpectingCommand;\r
+                                       }\r
+                                       //just throw anything else away\r
+                                       break;\r
+\r
+                               case ExpectingCommand:\r
+                                       if(currentByte == 2) {\r
+                                               if(!currentCommand_.SetCommand()) {\r
+                                                       LOG << TEXT("CLK: Failed to interpret command");\r
+                                                       currentState_ = ExpectingNewCommand;\r
+                                                       currentCommand_.Clear();\r
+                                               }\r
+                                               else {\r
+                                                       currentState_ = ExpectingClockID;\r
+                                               }\r
+                                       }\r
+                                       else\r
+                                               currentCommand_.commandString_ += currentByte;\r
+                                       break;\r
+\r
+                               case ExpectingClockID:\r
+                                       if(currentByte == 2)\r
+                                               currentState_ = currentCommand_.NeedsTime() ? ExpectingTime : ExpectingParameter;\r
+                                       else\r
+                                               currentCommand_.clockID_ = currentByte - TCHAR('0');\r
+                                       break;\r
+\r
+                               case ExpectingTime:\r
+                                       if(currentByte == 2)\r
+                                               currentState_ = ExpectingParameter;\r
+                                       else\r
+                                               currentCommand_.time_ += currentByte;\r
+                                       break;\r
+\r
+                               case ExpectingParameter:\r
+                                       //allocate new parameter\r
+                                       if(currentCommand_.parameters_.size() == 0 || currentByte == 2)\r
+                                               currentCommand_.parameters_.push_back(tstring());\r
+\r
+                                       //add the character to end end of the last parameter\r
+                                       if(currentByte == TEXT('<'))\r
+                                               currentCommand_.parameters_[currentCommand_.parameters_.size()-1] += TEXT("&lt;");\r
+                                       else if(currentByte == TEXT('>'))\r
+                                               currentCommand_.parameters_[currentCommand_.parameters_.size()-1] += TEXT("&gt;");\r
+                                       else if(currentByte == TEXT('\"'))\r
+                                               currentCommand_.parameters_[currentCommand_.parameters_.size()-1] += TEXT("&quot;");\r
+                                       else\r
+                                               currentCommand_.parameters_[currentCommand_.parameters_.size()-1] += currentByte;\r
+\r
+                                       break;\r
+                       }\r
+               }\r
+               else {\r
+                       if(currentState_ == ExpectingCommand) {\r
+                               if(!currentCommand_.SetCommand())\r
+                                       LOG << TEXT("CLK: Failed to interpret command");\r
+                       }\r
+\r
+                       if(currentCommand_.command_ == CLKCommand::CLKReset) {\r
+                               pCGControl_->Clear();\r
+                               bClockLoaded_ = false;\r
+                               \r
+                               LOG << TEXT("CLK: Recieved and executed reset-command");\r
+                       }\r
+                       else if(currentCommand_.command_ != CLKCommand::CLKInvalidCommand) {\r
+                               if(!bClockLoaded_) {\r
+                                       pCGControl_->Add(0, TEXT("hawrysklocka/clock"), true, TEXT(""), currentCommand_.GetData());\r
+                                       bClockLoaded_ = true;\r
+                               }\r
+                               else {\r
+                                       pCGControl_->Update(0, currentCommand_.GetData());\r
+                               }\r
+\r
+                               LOG << LogLevel::Debug << TEXT("CLK: Clockdata sent: ") << currentCommand_.GetData();\r
+                               LOG << TEXT("CLK: Executed valid command: ") << currentCommandString_.str();\r
+                       }\r
+\r
+                       currentState_ = ExpectingNewCommand;\r
+                       currentCommand_.Clear();\r
+               }\r
+       }\r
+}\r
+\r
+}      //namespace CLK\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/CLK/CLKProtocolStrategy.h b/server/CLK/CLKProtocolStrategy.h
new file mode 100644 (file)
index 0000000..f8e8d16
--- /dev/null
@@ -0,0 +1,65 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+#include <vector>\r
+\r
+#include "CLKCommand.h"\r
+#include "..\io\ProtocolStrategy.h"\r
+#include "..\channel.h"\r
+#include "..\MediaManager.h"\r
+\r
+namespace caspar {\r
+       namespace CG { class ICGControl; }\r
+namespace CLK {\r
+\r
+class CLKProtocolStrategy : public caspar::IO::IProtocolStrategy\r
+{\r
+public:\r
+       CLKProtocolStrategy();\r
+       virtual ~CLKProtocolStrategy();\r
+\r
+       virtual void Parse(const TCHAR* pData, int charCount, caspar::IO::ClientInfoPtr pClientInfo);\r
+       virtual UINT GetCodepage() {\r
+               return 28591;   //ISO 8859-1\r
+       }\r
+\r
+private:\r
+       enum ParserState {\r
+               ExpectingNewCommand,\r
+               ExpectingCommand,\r
+               ExpectingClockID,\r
+               ExpectingTime,\r
+               ExpectingParameter\r
+       };\r
+\r
+       ParserState     currentState_;\r
+       CLKCommand currentCommand_;\r
+       tstringstream currentCommandString_;\r
+\r
+       caspar::MediaManagerPtr pFlashManager_;\r
+       caspar::CG::ICGControl* pCGControl_;\r
+       ChannelPtr pChannel_;\r
+\r
+       bool bClockLoaded_;\r
+};\r
+\r
+}      //namespace CLK\r
+}      //namespace caspar\r
diff --git a/server/Channel.cpp b/server/Channel.cpp
new file mode 100644 (file)
index 0000000..af9d931
--- /dev/null
@@ -0,0 +1,123 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "stdAfx.h"\r
+\r
+#include "Application.h"\r
+#include "utils\critsectlock.h"\r
+#include "Channel.h"\r
+#include <algorithm>\r
+\r
+using namespace std;\r
+\r
+namespace caspar {\r
+\r
+using namespace caspar::utils;\r
+\r
+Channel::Channel(int index, VideoConsumerPtr pConsumer) : pConsumer_(pConsumer), index_(index), monitor_(index)\r
+{\r
+}\r
+\r
+Channel::~Channel() {\r
+       Destroy();\r
+}\r
+\r
+bool Channel::Initialize() {\r
+       pConsumer_->GetPlaybackControl()->SetMonitor(&monitor_);\r
+       return true;\r
+}\r
+\r
+void Channel::Destroy() {\r
+       pConsumer_.reset();\r
+}\r
+\r
+const TCHAR* Channel::GetFormatDescription() const \r
+{\r
+       return pConsumer_->GetFormatDescription();\r
+}\r
+\r
+bool Channel::IsPlaybackRunning() const \r
+{\r
+       return pConsumer_->GetPlaybackControl()->IsRunning();\r
+}\r
+\r
+CG::ICGControl* Channel::GetCGControl() {\r
+       return pConsumer_->GetPlaybackControl()->GetCGControl();\r
+}\r
+\r
+////////////////\r
+// LOAD\r
+bool Channel::Load(MediaProducerPtr pFP, bool loop)\r
+{\r
+       return pConsumer_->GetPlaybackControl()->Load(pFP, loop);\r
+}\r
+\r
+////////////////\r
+// LOADBG\r
+bool Channel::LoadBackground(MediaProducerPtr pFP, const TransitionInfo& transitionInfo, bool loop)\r
+{\r
+       return pConsumer_->GetPlaybackControl()->LoadBackground(pFP, transitionInfo, loop);\r
+}\r
+\r
+////////////////\r
+// PLAY\r
+bool Channel::Play()\r
+{\r
+       return pConsumer_->GetPlaybackControl()->Play();\r
+}\r
+\r
+////////////////\r
+// STOP\r
+bool Channel::Stop(bool block)\r
+{\r
+       return pConsumer_->GetPlaybackControl()->StopPlayback(block);\r
+}\r
+\r
+bool Channel::SetVideoFormat(const tstring& strDesiredFrameFormat)\r
+{\r
+       tstring strDesiredFrameFormatUpper = strDesiredFrameFormat;\r
+       tstring strFmtDescUpper = this->pConsumer_->GetFormatDescription();\r
+\r
+       std::transform(strDesiredFrameFormatUpper.begin(), strDesiredFrameFormatUpper.end(), strDesiredFrameFormatUpper.begin(), toupper);\r
+       std::transform(strFmtDescUpper.begin(), strFmtDescUpper.end(), strFmtDescUpper.begin(), toupper);\r
+\r
+       if(strDesiredFrameFormatUpper == strFmtDescUpper)\r
+               return true;\r
+\r
+       bool stopped = this->Stop(true);        \r
+       bool formatSet = stopped && this->pConsumer_->SetVideoFormat(strDesiredFrameFormat);    \r
+       bool cleared = formatSet && this->Clear();\r
+\r
+       return stopped && formatSet && cleared;\r
+}\r
+\r
+\r
+\r
+bool Channel::Clear() \r
+{      \r
+       pConsumer_->GetPlaybackControl()->LoadEmpty();\r
+       return true;\r
+}\r
+\r
+bool Channel::Param(const tstring& str) {\r
+       return pConsumer_->GetPlaybackControl()->Param(str);\r
+}\r
+\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/Channel.h b/server/Channel.h
new file mode 100644 (file)
index 0000000..c4437a9
--- /dev/null
@@ -0,0 +1,71 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+\r
+#include "VideoConsumer.h"\r
+#include "MediaProducer.h"\r
+#include "PlaybackControl.h"\r
+#include "producers\composites\TransitionProducer.h"\r
+#include "TransitionInfo.h"\r
+#include "frame\clipinfo.h"\r
+\r
+#include "monitor.h"\r
+\r
+namespace caspar {\r
+\r
+class Channel\r
+{\r
+public:\r
+       explicit Channel(int index, VideoConsumerPtr pVideoConsumer);\r
+       ~Channel();\r
+\r
+       bool Initialize();      //call from app in main-thread\r
+       void Destroy();         //call from app in main-thread\r
+\r
+       const TCHAR* GetFormatDescription() const;\r
+       bool IsPlaybackRunning() const;\r
+\r
+       int GetIndex() const {\r
+               return index_;\r
+       }\r
+\r
+       CG::ICGControl* GetCGControl();\r
+       Monitor& GetMonitor() {\r
+               return monitor_;\r
+       }\r
+\r
+       bool Load(MediaProducerPtr, bool loop=false);                   //call from misc IO threads\r
+       bool LoadBackground(MediaProducerPtr, const TransitionInfo& transitionInfo, bool loop=false);   //call from misc IO threads\r
+       bool Play();    //call from misc IO threads\r
+       bool Stop(bool block = false);  //call from misc IO threads\r
+       bool Param(const tstring& str); //call from misc IO threads\r
+       bool Clear();\r
+       bool SetVideoFormat(const tstring& strDesiredFrameFormat);\r
+\r
+\r
+private:\r
+       Monitor monitor_;\r
+       int index_;\r
+       VideoConsumerPtr        pConsumer_;\r
+};\r
+typedef std::tr1::shared_ptr<Channel> ChannelPtr;\r
+\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/Controller.h b/server/Controller.h
new file mode 100644 (file)
index 0000000..1db59c4
--- /dev/null
@@ -0,0 +1,38 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+\r
+#include "io\protocolStrategy.h"\r
+\r
+namespace caspar {\r
+\r
+class IController {\r
+public:\r
+       virtual ~IController() {\r
+       }\r
+\r
+       virtual bool Start() = 0;\r
+       virtual void Stop() = 0;\r
+       virtual void SetProtocolStrategy(caspar::IO::ProtocolStrategyPtr) = 0;\r
+};\r
+typedef std::tr1::shared_ptr<IController> ControllerPtr;\r
+\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/FileInfo.h b/server/FileInfo.h
new file mode 100644 (file)
index 0000000..1976b02
--- /dev/null
@@ -0,0 +1,42 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef __FILEINFO_H__\r
+#define __FILEINFO_H__\r
+\r
+namespace caspar {\r
+\r
+class FileInfo\r
+{\r
+public:\r
+       FileInfo() : length(0), resolution(0), size(0), filetype(TEXT("")), filename(TEXT("")), encoding(TEXT("")), type(TEXT(""))\r
+       {}\r
+       tstring filename;\r
+       tstring filetype;\r
+       tstring encoding;\r
+       tstring type;\r
+       int length;\r
+       int resolution;\r
+       unsigned long long size;\r
+};\r
+\r
+}      //namespace caspar\r
+\r
+#endif __FILEINFO_H__
\ No newline at end of file
diff --git a/server/Main.cpp b/server/Main.cpp
new file mode 100644 (file)
index 0000000..8baf328
--- /dev/null
@@ -0,0 +1,73 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "StdAfx.h"\r
+#include "Application.h"\r
+#include "utils\FileOutputStream.h"\r
+#include <tbb/task_scheduler_init.h>\r
+\r
+//the easy way to make it possible to forward WndProc messages into the application-object\r
+caspar::Application* pGlobal_Application = 0;\r
+\r
+namespace caspar {\r
+       Application* GetApplication()\r
+       {\r
+               return pGlobal_Application;\r
+       }\r
+}\r
+\r
+int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int)\r
+{\r
+       int returnValue = 0;\r
+       tstring commandline(lpCmdLine);\r
+       \r
+       tbb::task_scheduler_init task_scheduler(max(2, tbb::task_scheduler_init::default_num_threads()));\r
+       \r
+       //if(commandline == TEXT("install"))\r
+       //{\r
+       //      caspar::Application::InstallService();\r
+       //}\r
+       //else if(commandline == TEXT("uninstall"))\r
+       //{\r
+       //      caspar::Application::UninstallService();\r
+       //}\r
+       //else {\r
+               try \r
+               {\r
+                       caspar::utils::OutputStreamPtr pOutputStream(new caspar::utils::FileOutputStream(TEXT("startup.log")));\r
+                       caspar::utils::Logger::GetInstance().SetOutputStream(pOutputStream);\r
+                       caspar::utils::Logger::GetInstance().SetTimestamp(true);\r
+\r
+                       caspar::Application app(lpCmdLine, hInstance);\r
+                       pGlobal_Application = &app;\r
+\r
+                       //if(commandline.find(TEXT("service")) != tstring::npos)\r
+                       //      app.RunAsService();\r
+                       //else\r
+                               returnValue = app.RunAsWindow();\r
+               }\r
+               catch(const std::exception& ex)\r
+               {\r
+                       LOG << caspar::utils::LogLevel::Critical << TEXT("UNHANDLED EXCEPTION in main thread. Message: ") << ex.what();\r
+               }\r
+//     }\r
+\r
+       return returnValue;\r
+}\r
diff --git a/server/MediaController.h b/server/MediaController.h
new file mode 100644 (file)
index 0000000..46ea95f
--- /dev/null
@@ -0,0 +1,41 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _CASPAR_MEDIACONTROLLER_H__\r
+#define _CASPAR_MEDIACONTROLLER_H__\r
+\r
+namespace caspar {\r
+\r
+class IMediaController\r
+{\r
+       IMediaController(const IMediaController&);\r
+       IMediaController& operator=(const IMediaController&);\r
+\r
+protected:\r
+       IMediaController() {}\r
+\r
+public:\r
+       virtual ~IMediaController() {}\r
+\r
+};\r
+\r
+}      //namespace caspar\r
+\r
+#endif //_CASPAR_MEDIACONTROLLER_H__
\ No newline at end of file
diff --git a/server/MediaManager.h b/server/MediaManager.h
new file mode 100644 (file)
index 0000000..c17c4c4
--- /dev/null
@@ -0,0 +1,57 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+\r
+#include <string>\r
+#include <vector>\r
+#include "fileinfo.h"\r
+\r
+namespace caspar {\r
+\r
+class FileInfo;\r
+\r
+class MediaProducer;\r
+typedef std::tr1::shared_ptr<MediaProducer> MediaProducerPtr;\r
+\r
+class IMediaManager\r
+{\r
+public:\r
+\r
+       IMediaManager()\r
+       {}\r
+\r
+       virtual ~IMediaManager()\r
+       {}\r
+       virtual MediaProducerPtr CreateProducer(const tstring& filename) = 0;\r
+\r
+       unsigned short GetSupportedExtensions(const std::vector<tstring>*& extensions)\r
+       {\r
+               extensions = &_extensions;\r
+               return (unsigned short)_extensions.size();\r
+       }\r
+\r
+       virtual bool getFileInfo(FileInfo* pFileInfo) = 0;\r
+protected:\r
+       std::vector<tstring>    _extensions;\r
+};\r
+typedef std::tr1::shared_ptr<IMediaManager> MediaManagerPtr;\r
+\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/MediaProducer.h b/server/MediaProducer.h
new file mode 100644 (file)
index 0000000..9462f7b
--- /dev/null
@@ -0,0 +1,61 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+\r
+namespace caspar {\r
+\r
+class IMediaController;\r
+\r
+class MediaProducer;\r
+typedef std::tr1::shared_ptr<MediaProducer> MediaProducerPtr;\r
+\r
+class MediaProducer\r
+{\r
+       MediaProducer(const MediaProducer&);\r
+       MediaProducer& operator=(const MediaProducer&);\r
+\r
+public:\r
+       MediaProducer() : bLoop_(false)\r
+       {}\r
+       virtual ~MediaProducer()\r
+       {}\r
+\r
+       virtual IMediaController* QueryController(const tstring&) = 0;\r
+\r
+       virtual bool Param(const tstring&) { return false; }\r
+       virtual bool IsEmpty() const { return false; }\r
+\r
+       virtual MediaProducerPtr GetFollowingProducer() {\r
+               return MediaProducerPtr();\r
+       }\r
+\r
+       virtual void SetLoop(bool bLoop) {\r
+               bLoop_ = bLoop;\r
+       }\r
+       bool GetLoop() {\r
+               return bLoop_;\r
+       }\r
+\r
+private:\r
+       bool bLoop_;\r
+};\r
+\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/MediaProducerInfo.h b/server/MediaProducerInfo.h
new file mode 100644 (file)
index 0000000..a6edccb
--- /dev/null
@@ -0,0 +1,38 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+\r
+namespace caspar {\r
+\r
+struct MediaProducerInfo {\r
+\r
+       MediaProducerInfo() : HaveAudio(false), HaveVideo(false), AudioSamplesPerSec(0), AudioChannels(0), BitsPerAudioSample(0)\r
+       {}\r
+\r
+       bool HaveAudio;\r
+       bool HaveVideo;\r
+\r
+       unsigned int AudioSamplesPerSec;\r
+       unsigned short AudioChannels;\r
+       unsigned short BitsPerAudioSample;\r
+};\r
+\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/Monitor.cpp b/server/Monitor.cpp
new file mode 100644 (file)
index 0000000..12a459f
--- /dev/null
@@ -0,0 +1,181 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "stdAfx.h"\r
+\r
+#include "Monitor.h"\r
+#include "io/AsyncEventServer.h"\r
+#include <algorithm>\r
+\r
+namespace caspar {\r
+\r
+using namespace std;\r
+\r
+const int Monitor::ResponseCodeNoParam = 102;\r
+const int Monitor::ResponseCodeWithParam = 101;\r
+\r
+Monitor::MonitorList Monitor::monitors_;\r
+\r
+Monitor::Monitor(int channelIndex) : channelIndex_(channelIndex) {\r
+       monitors_.push_back(this);\r
+}\r
+Monitor::~Monitor() {\r
+       monitors_.remove(this);\r
+}\r
+\r
+void Monitor::ClearListener(const caspar::IO::ClientInfoPtr& pClient) {\r
+       MonitorList::iterator it = monitors_.begin();\r
+       MonitorList::iterator end = monitors_.end();\r
+\r
+       for(; it != end; ++it) {\r
+               (*it)->RemoveListener(pClient);\r
+       }\r
+}\r
+\r
+void Monitor::Inform(MonitorEventType type, const tstring& parameter, MonitorParameterFormatter formatter)\r
+{\r
+       taskSeraializer_.enqueue(bind(&Monitor::internal_Inform, this, type, parameter, formatter));\r
+}\r
+\r
+void Monitor::internal_Inform(MonitorEventType type, const tstring parameter, MonitorParameterFormatter formatter)\r
+{\r
+       //lock the list and make a local copy\r
+       ListenerList localListeners;\r
+       {\r
+               Lock lock(*this);\r
+               localListeners = listeners_;\r
+       }\r
+\r
+       if(localListeners.size() == 0)\r
+               return;\r
+\r
+       tstringstream msg;\r
+       int code = ResponseCodeNoParam;\r
+       if(parameter.size() > 0)\r
+               code = ResponseCodeWithParam;\r
+\r
+       msg << code << TEXT(' ');\r
+\r
+       FormatInfo(msg, type);\r
+\r
+       if(parameter.size() > 0) {\r
+               if(formatter)\r
+                       msg << formatter(parameter) << TEXT("\r\n");\r
+               else\r
+                       msg << parameter << TEXT("\r\n");\r
+       }\r
+\r
+       tstring message(msg.str());\r
+\r
+       //iterate over the local copy\r
+       ListenerList::iterator it = localListeners.begin();\r
+       ListenerList::iterator end = localListeners.end();\r
+       for(; it != end; ++it) {\r
+               (*it)->Send(message);\r
+       }\r
+\r
+//     LOG << utils::LogLevel::Debug << TEXT("MONITOR: ") << msg.str();\r
+}\r
+\r
+void Monitor::FormatInfo(tstringstream& msg, MonitorEventType type) \r
+{\r
+       switch(type) \r
+       {\r
+       case LOADBG:\r
+               msg << TEXT("LOADBG");\r
+               break;\r
+       case LOAD:\r
+               msg << TEXT("LOAD");\r
+               break;\r
+       case PLAY:\r
+               msg << TEXT("PLAY");\r
+               break;\r
+       case STOPPED:\r
+               msg << TEXT("STOP");\r
+               break;\r
+       case CLEAR:\r
+               msg << TEXT("CLEAR");\r
+               break;\r
+\r
+       case CG_ADD:\r
+       case CG_CLEAR:\r
+       case CG_PLAY:\r
+       case CG_STOP:\r
+       case CG_NEXT:\r
+       case CG_REMOVE:\r
+       case CG_UPDATE:\r
+       case CG_INVOKE:\r
+               msg << TEXT("CG");\r
+               break;\r
+\r
+       default:\r
+               break;\r
+       }\r
+\r
+       if(channelIndex_ > 0)\r
+               msg << TEXT(' ') << channelIndex_;\r
+\r
+       switch(type)\r
+       {\r
+       case CG_ADD:\r
+               msg << TEXT(" ADD");\r
+               break;\r
+       case CG_CLEAR:\r
+               msg << TEXT(" CLEAR");\r
+               break;\r
+       case CG_PLAY:\r
+               msg << TEXT(" PLAY");\r
+               break;\r
+       case CG_STOP:\r
+               msg << TEXT(" STOP");\r
+               break;\r
+       case CG_NEXT:\r
+               msg << TEXT(" NEXT");\r
+               break;\r
+       case CG_REMOVE:\r
+               msg << TEXT(" REMOVE");\r
+               break;\r
+       case CG_UPDATE:\r
+               msg << TEXT(" UPDATE");\r
+               break;\r
+       case CG_INVOKE:\r
+               msg << TEXT(" INVOKE");\r
+               break;\r
+       default:\r
+               break;\r
+       }\r
+       msg << TEXT("\r\n");\r
+}\r
+\r
+void Monitor::AddListener(caspar::IO::ClientInfoPtr& pClient) {\r
+       Lock lock(*this);\r
+       ListenerList::iterator it = std::find(listeners_.begin(), listeners_.end(), pClient);\r
+       if(it == listeners_.end()) {\r
+               LOG << utils::LogLevel::Debug << TEXT("Added a client as listener");\r
+               listeners_.push_back(pClient);\r
+       }\r
+}\r
+\r
+void Monitor::RemoveListener(const caspar::IO::ClientInfoPtr& pClient) {\r
+       Lock lock(*this);\r
+       listeners_.remove(pClient);\r
+}\r
+\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/Monitor.h b/server/Monitor.h
new file mode 100644 (file)
index 0000000..062b05f
--- /dev/null
@@ -0,0 +1,85 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+\r
+#include "utils/noncopyable.hpp"\r
+#include "utils/lockable.h"\r
+#include "io/clientinfo.h"\r
+#include <list>\r
+#include <functional>\r
+\r
+#include "utils/functiontask.hpp"\r
+\r
+namespace caspar {\r
+\r
+typedef std::function<tstring(const tstring&)> MonitorParameterFormatter;\r
+\r
+enum MonitorEventType\r
+{\r
+       LOADBG,\r
+       LOAD,\r
+       PLAY,\r
+       STOPPED,\r
+       CLEAR,\r
+\r
+       CG_ADD,\r
+       CG_CLEAR,\r
+       CG_PLAY,\r
+       CG_STOP,\r
+       CG_NEXT,\r
+       CG_REMOVE,\r
+       CG_UPDATE,\r
+       CG_INVOKE\r
+};\r
+\r
+class Monitor : private utils::LockableObject, private utils::Noncopyable\r
+{\r
+public:\r
+       static const int ResponseCodeNoParam;\r
+       static const int ResponseCodeWithParam;\r
+\r
+       //removes the client from all monitors\r
+       static void ClearListener(const caspar::IO::ClientInfoPtr& pClient);\r
+\r
+       explicit Monitor(int channelIndex);\r
+       virtual ~Monitor();\r
+\r
+       void Inform(MonitorEventType type, const tstring& parameter = TEXT(""), MonitorParameterFormatter formatter = 0);\r
+\r
+       void AddListener(caspar::IO::ClientInfoPtr& pClient);\r
+       void RemoveListener(const caspar::IO::ClientInfoPtr& pClient);\r
+\r
+private:\r
+       void internal_Inform(MonitorEventType type, const tstring parameter, MonitorParameterFormatter formatter);\r
+\r
+       void FormatInfo(tstringstream& sstream, MonitorEventType type);\r
+\r
+       int channelIndex_;\r
+       typedef std::list<caspar::IO::ClientInfoPtr> ListenerList;\r
+       typedef std::list<Monitor*> MonitorList;\r
+\r
+       function_task_serializer taskSeraializer_;\r
+\r
+       ListenerList listeners_;\r
+       static MonitorList monitors_;\r
+};\r
+\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/PlaybackControl.h b/server/PlaybackControl.h
new file mode 100644 (file)
index 0000000..5f15f4c
--- /dev/null
@@ -0,0 +1,59 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+\r
+#include "MediaProducer.h"\r
+#include "TransitionInfo.h"\r
+\r
+namespace caspar\r
+{\r
+       namespace CG\r
+       {\r
+               class ICGControl;\r
+       }\r
+\r
+       class Monitor;\r
+\r
+       class IPlaybackControl\r
+       {\r
+               IPlaybackControl(IPlaybackControl&);\r
+               const IPlaybackControl& operator=(const IPlaybackControl&);\r
+\r
+       public:\r
+               IPlaybackControl() {}\r
+               virtual ~IPlaybackControl() {}\r
+\r
+               virtual void SetMonitor(Monitor* pMonitor) = 0;\r
+\r
+               virtual bool Load(MediaProducerPtr pFP, bool loop) = 0;\r
+               virtual bool LoadBackground(MediaProducerPtr pFP, const TransitionInfo& transitionInfo, bool loop) = 0;\r
+               virtual bool Play() = 0;\r
+               virtual void LoadEmpty() = 0;\r
+               //virtual bool Pause() = 0;\r
+               virtual bool StopPlayback(bool block = false) = 0;\r
+               virtual bool IsRunning() = 0;\r
+               virtual bool Param(const tstring& param) = 0;\r
+\r
+               virtual CG::ICGControl* GetCGControl() = 0;\r
+       };\r
+\r
+       typedef std::tr1::shared_ptr<IPlaybackControl> PlaybackControlPtr;\r
+}
\ No newline at end of file
diff --git a/server/Resource.h b/server/Resource.h
new file mode 100644 (file)
index 0000000..4693e04
--- /dev/null
@@ -0,0 +1,16 @@
+//{{NO_DEPENDENCIES}}\r
+// Microsoft Visual C++ generated include file.\r
+// Used by Server.rc\r
+//\r
+#define IDI_ICON1                       101\r
+\r
+// Next default values for new objects\r
+// \r
+#ifdef APSTUDIO_INVOKED\r
+#ifndef APSTUDIO_READONLY_SYMBOLS\r
+#define _APS_NEXT_RESOURCE_VALUE        102\r
+#define _APS_NEXT_COMMAND_VALUE         40001\r
+#define _APS_NEXT_CONTROL_VALUE         1001\r
+#define _APS_NEXT_SYMED_VALUE           101\r
+#endif\r
+#endif\r
diff --git a/server/Server.vcproj b/server/Server.vcproj
new file mode 100644 (file)
index 0000000..3dfce93
--- /dev/null
@@ -0,0 +1,3575 @@
+<?xml version="1.0" encoding="Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="9,00"\r
+       Name="Server"\r
+       ProjectGUID="{79388C20-6499-4BF6-B8B9-D8C33D7D4DDD}"\r
+       RootNamespace="Server"\r
+       Keyword="Win32Proj"\r
+       TargetFrameworkVersion="131072"\r
+       >\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"\r
+               />\r
+       </Platforms>\r
+       <ToolFiles>\r
+       </ToolFiles>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory="$(ProjectDir)build\"\r
+                       IntermediateDirectory="debug"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+                       CharacterSet="1"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                               CommandLine=""\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories=""\r
+                               MinimalRebuild="true"\r
+                               ExceptionHandling="2"\r
+                               BasicRuntimeChecks="3"\r
+                               SmallerTypeCheck="true"\r
+                               RuntimeLibrary="3"\r
+                               EnableEnhancedInstructionSet="0"\r
+                               RuntimeTypeInfo="true"\r
+                               UsePrecompiledHeader="2"\r
+                               BrowseInformation="1"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="false"\r
+                               DebugInformationFormat="4"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="GLee.lib Dxguid.lib Dsound.lib Winmm.lib Ws2_32.lib BlueVelvet3_d.lib avformat-51.lib avcodec-51.lib avutil-49.lib"\r
+                               OutputFile="$(OutDir)/casparcg_bluefish.exe"\r
+                               Version=""\r
+                               LinkIncremental="2"\r
+                               AdditionalLibraryDirectories=""\r
+                               IgnoreDefaultLibraryNames="LIBC.LIB"\r
+                               GenerateDebugInformation="true"\r
+                               ProgramDatabaseFile="$(TargetDir)$(TargetName).pdb"\r
+                               GenerateMapFile="true"\r
+                               MapFileName=""\r
+                               SubSystem="2"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                               CommandLine=""\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory="$(ProjectDir)build\"\r
+                       IntermediateDirectory="release"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+                       CharacterSet="1"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                               CommandLine=""\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="2"\r
+                               InlineFunctionExpansion="2"\r
+                               EnableIntrinsicFunctions="true"\r
+                               FavorSizeOrSpeed="1"\r
+                               AdditionalIncludeDirectories=""\r
+                               ExceptionHandling="2"\r
+                               RuntimeLibrary="2"\r
+                               EnableEnhancedInstructionSet="2"\r
+                               RuntimeTypeInfo="true"\r
+                               UsePrecompiledHeader="2"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="false"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                               CommandLine=""\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="Dxguid.lib Dsound.lib Winmm.lib Ws2_32.lib Bluevelvet3.lib avformat-51.lib avcodec-51.lib avutil-49.lib tbb.lib Glee.lib"\r
+                               OutputFile="$(OutDir)/casparcg_bluefish.exe"\r
+                               Version=""\r
+                               LinkIncremental="1"\r
+                               AdditionalLibraryDirectories=""\r
+                               IgnoreDefaultLibraryNames="LIBC.lib"\r
+                               GenerateDebugInformation="true"\r
+                               GenerateMapFile="true"\r
+                               MapExports="true"\r
+                               SubSystem="2"\r
+                               OptimizeReferences="0"\r
+                               EnableCOMDATFolding="0"\r
+                               RandomizedBaseAddress="1"\r
+                               FixedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                               CommandLine=""\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="no bluefish|Win32"\r
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
+                       IntermediateDirectory="$(ConfigurationName)"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+                       CharacterSet="1"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                               CommandLine=""\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               InlineFunctionExpansion="2"\r
+                               EnableIntrinsicFunctions="true"\r
+                               FavorSizeOrSpeed="1"\r
+                               AdditionalIncludeDirectories=""\r
+                               PreprocessorDefinitions="DISABLE_BLUEFISH"\r
+                               ExceptionHandling="2"\r
+                               RuntimeLibrary="2"\r
+                               EnableEnhancedInstructionSet="2"\r
+                               RuntimeTypeInfo="true"\r
+                               UsePrecompiledHeader="2"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="false"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                               CommandLine=""\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="Dxguid.lib Dsound.lib Winmm.lib Ws2_32.lib avformat-51.lib avcodec-51.lib avutil-49.lib GLee.lib tbb.lib"\r
+                               OutputFile="$(OutDir)/casparcg.exe"\r
+                               Version=""\r
+                               LinkIncremental="1"\r
+                               AdditionalLibraryDirectories=""\r
+                               IgnoreDefaultLibraryNames="LIBC.lib"\r
+                               GenerateDebugInformation="true"\r
+                               GenerateMapFile="true"\r
+                               MapExports="true"\r
+                               SubSystem="2"\r
+                               OptimizeReferences="0"\r
+                               EnableCOMDATFolding="0"\r
+                               RandomizedBaseAddress="1"\r
+                               FixedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                               CommandLine=""\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="SVT special|Win32"\r
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
+                       IntermediateDirectory="$(ConfigurationName)"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+                       CharacterSet="1"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                               CommandLine=""\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               InlineFunctionExpansion="2"\r
+                               EnableIntrinsicFunctions="true"\r
+                               FavorSizeOrSpeed="1"\r
+                               AdditionalIncludeDirectories=""\r
+                               PreprocessorDefinitions="ENABLE_SVT"\r
+                               ExceptionHandling="2"\r
+                               RuntimeLibrary="2"\r
+                               EnableEnhancedInstructionSet="2"\r
+                               RuntimeTypeInfo="true"\r
+                               UsePrecompiledHeader="2"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="false"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                               CommandLine=""\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="Dxguid.lib Dsound.lib Winmm.lib Ws2_32.lib Bluevelvet3.lib avformat-51.lib avcodec-51.lib avutil-49.lib tbb.lib Glee.lib"\r
+                               OutputFile="$(OutDir)/casparcg_bluefish.exe"\r
+                               Version=""\r
+                               LinkIncremental="1"\r
+                               AdditionalLibraryDirectories=""\r
+                               IgnoreDefaultLibraryNames="LIBC.lib"\r
+                               GenerateDebugInformation="true"\r
+                               GenerateMapFile="true"\r
+                               MapExports="true"\r
+                               SubSystem="2"\r
+                               OptimizeReferences="0"\r
+                               EnableCOMDATFolding="0"\r
+                               RandomizedBaseAddress="1"\r
+                               FixedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                               CommandLine=""\r
+                       />\r
+               </Configuration>\r
+       </Configurations>\r
+       <References>\r
+       </References>\r
+       <Files>\r
+               <Filter\r
+                       Name="resources"\r
+                       Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
+                       UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
+                       >\r
+                       <File\r
+                               RelativePath=".\resources\Icon2.ico"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\resources\Server.rc"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\resources\server.rc2"\r
+                               >\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="utils"\r
+                       >\r
+                       <File\r
+                               RelativePath=".\Utils\Allocator.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\utils\BitmapHolder.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\utils\BitmapHolder.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Utils\CommandQueue.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\utils\CPUID.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               UsePrecompiledHeader="0"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               UsePrecompiledHeader="0"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               UsePrecompiledHeader="0"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               UsePrecompiledHeader="0"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\utils\CPUID.hpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Utils\CritSectLock.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Utils\DataBuffer.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\utils\DCWrapper.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\utils\DCWrapper.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Utils\Event.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Utils\Event.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Utils\FileExists.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               UsePrecompiledHeader="2"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               UsePrecompiledHeader="2"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               UsePrecompiledHeader="2"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               UsePrecompiledHeader="2"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Utils\FileExists.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Utils\FileInputStream.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Utils\FileInputStream.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Utils\FileOutputStream.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               UsePrecompiledHeader="2"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               UsePrecompiledHeader="2"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               UsePrecompiledHeader="2"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               UsePrecompiledHeader="2"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Utils\FileOutputStream.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Utils\FindWrapper.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               UsePrecompiledHeader="2"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               UsePrecompiledHeader="2"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               UsePrecompiledHeader="2"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               UsePrecompiledHeader="2"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Utils\FindWrapper.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Utils\ID.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Utils\ID.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Utils\InputStream.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Utils\Lockable.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\utils\LogException.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\utils\LogException.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Utils\Logger.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Utils\Logger.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\utils\LogLevel.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\utils\LogStream.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\utils\LogStream.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\utils\Noncopyable.hpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Utils\OutputStream.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Utils\PixmapData.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\utils\Process.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\utils\Process.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Utils\Runnable.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Utils\Semaphore.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Utils\Semaphore.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\utils\TaskQueue.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Utils\Thread.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Utils\Thread.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\utils\Types.hpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Utils\Win32Exception.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Utils\Win32Exception.h"\r
+                               >\r
+                       </File>\r
+                       <Filter\r
+                               Name="image"\r
+                               >\r
+                               <File\r
+                                       RelativePath=".\Utils\image\Clear.cpp"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\Utils\image\Clear.hpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\Utils\image\Copy.cpp"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\Utils\image\Copy.hpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\utils\image\CopyField.cpp"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\utils\image\CopyField.hpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\utils\image\Image.cpp"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="2"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="2"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="2"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="2"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\utils\image\Image.hpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\utils\image\Lerp.cpp"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="2"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="2"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="2"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="2"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\utils\image\Lerp.hpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\utils\image\Over.cpp"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="2"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="2"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="2"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="2"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\utils\image\Over.hpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\utils\image\Premultiply.cpp"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="2"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="2"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="2"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="2"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\utils\image\Premultiply.hpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\utils\image\Shuffle.cpp"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="2"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="2"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="2"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="2"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\utils\image\Shuffle.hpp"\r
+                                       >\r
+                               </File>\r
+                       </Filter>\r
+               </Filter>\r
+               <Filter\r
+                       Name="io"\r
+                       >\r
+                       <File\r
+                               RelativePath=".\IO\AsyncEventServer.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\IO\AsyncEventServer.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\IO\ClientInfo.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\IO\ProtocolStrategy.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\IO\SerialPort.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\IO\SerialPort.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\IO\SocketInfo.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\IO\SocketInfo.h"\r
+                               >\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="consumers"\r
+                       >\r
+                       <Filter\r
+                               Name="bluefish"\r
+                               >\r
+                               <File\r
+                                       RelativePath=".\consumers\bluefish\BluefishException.h"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCustomBuildTool"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\consumers\bluefish\BluefishFrameManager.cpp"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\stdafx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\stdafx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\stdafx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\stdafx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\consumers\bluefish\BluefishFrameManager.h"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCustomBuildTool"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\consumers\bluefish\BluefishPlaybackStrategy.cpp"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\stdafx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\stdafx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\stdafx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\stdafx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\consumers\bluefish\BluefishPlaybackStrategy.h"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCustomBuildTool"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\consumers\bluefish\BlueFishVideoConsumer.cpp"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\stdafx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\stdafx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\stdafx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\stdafx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\consumers\bluefish\BlueFishVideoConsumer.h"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCustomBuildTool"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                       </Filter>\r
+                       <Filter\r
+                               Name="gdi"\r
+                               >\r
+                               <File\r
+                                       RelativePath=".\consumers\GDI\GDIVideoConsumer.cpp"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\consumers\GDI\GDIVideoConsumer.h"\r
+                                       >\r
+                               </File>\r
+                       </Filter>\r
+                       <Filter\r
+                               Name="ogl"\r
+                               >\r
+                               <File\r
+                                       RelativePath=".\Consumers\OGL\OGLVideoConsumer.cpp"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\Consumers\OGL\OGLVideoConsumer.h"\r
+                                       >\r
+                               </File>\r
+                       </Filter>\r
+                       <Filter\r
+                               Name="audio"\r
+                               >\r
+                               <File\r
+                                       RelativePath=".\consumers\Audio\AudioConsumer.cpp"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\consumers\Audio\AudioConsumer.h"\r
+                                       >\r
+                               </File>\r
+                       </Filter>\r
+                       <Filter\r
+                               Name="decklink"\r
+                               >\r
+                               <File\r
+                                       RelativePath=".\consumers\decklink\DeckLinkAPI.idl"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCMIDLTool"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCMIDLTool"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCMIDLTool"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCMIDLTool"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\consumers\decklink\DeckLinkAPI_h.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\consumers\decklink\DeckLinkAPI_i.c"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="0"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="0"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="0"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="0"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\consumers\decklink\DeckLinkAPI_v7_1.idl"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCMIDLTool"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCMIDLTool"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCMIDLTool"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCMIDLTool"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\consumers\decklink\DeckLinkAPI_v7_3.idl"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCMIDLTool"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCMIDLTool"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCMIDLTool"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCMIDLTool"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\consumers\decklink\DecklinkVideoConsumer.cpp"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\consumers\decklink\DecklinkVideoConsumer.h"\r
+                                       >\r
+                               </File>\r
+                       </Filter>\r
+               </Filter>\r
+               <Filter\r
+                       Name="cg"\r
+                       >\r
+                       <File\r
+                               RelativePath=".\cg\CGControl.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\cg\FlashCGProxy.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\cg\FlashCGProxy.h"\r
+                               >\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="producers"\r
+                       >\r
+                       <Filter\r
+                               Name="ffmpeg"\r
+                               >\r
+                               <File\r
+                                       RelativePath=".\Producers\ffmpeg\FFmpegManager.cpp"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\Producers\ffmpeg\FFmpegManager.h"\r
+                                       >\r
+                               </File>\r
+                       </Filter>\r
+                       <Filter\r
+                               Name="flash"\r
+                               >\r
+                               <File\r
+                                       RelativePath=".\Producers\flash\AxFlash.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\producers\flash\CTManager.cpp"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\producers\flash\CTManager.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\Producers\flash\Flash9e.IDL"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCMIDLTool"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCMIDLTool"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCMIDLTool"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCMIDLTool"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\Producers\flash\Flash9e_i.c"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="0"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="0"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="0"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       UsePrecompiledHeader="0"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\Producers\flash\FlashAxContainer.cpp"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\Producers\flash\FlashAxContainer.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\Producers\flash\FlashCommand.cpp"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\Producers\flash\FlashCommand.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\Producers\flash\FlashCommandQueue.cpp"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\Producers\flash\FlashCommandQueue.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\producers\flash\FlashManager.cpp"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\producers\flash\FlashManager.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\Producers\flash\FlashProducer.cpp"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\Producers\flash\FlashProducer.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\Producers\flash\TimerHelper.h"\r
+                                       >\r
+                               </File>\r
+                       </Filter>\r
+                       <Filter\r
+                               Name="color"\r
+                               >\r
+                               <File\r
+                                       RelativePath=".\producers\color\ColorManager.cpp"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\producers\color\ColorManager.h"\r
+                                       >\r
+                               </File>\r
+                       </Filter>\r
+                       <Filter\r
+                               Name="targa"\r
+                               >\r
+                               <File\r
+                                       RelativePath=".\producers\targa\TargaManager.cpp"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\producers\targa\TargaManager.h"\r
+                                       >\r
+                               </File>\r
+                       </Filter>\r
+                       <Filter\r
+                               Name="composites"\r
+                               >\r
+                               <File\r
+                                       RelativePath=".\producers\composites\FrameCompositeProducer.cpp"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\producers\composites\FrameCompositeProducer.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\producers\composites\TransitionProducer.cpp"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\producers\composites\TransitionProducer.h"\r
+                                       >\r
+                               </File>\r
+                       </Filter>\r
+                       <Filter\r
+                               Name="targascroll"\r
+                               >\r
+                               <File\r
+                                       RelativePath=".\producers\targascroll\TargaScrollManager.cpp"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\producers\targascroll\TargaScrollManager.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\producers\targascroll\TargaScrollProducer.cpp"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="no bluefish|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="SVT special|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       PrecompiledHeaderThrough="..\..\StdAfx.h"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\producers\targascroll\TargaScrollProducer.h"\r
+                                       >\r
+                               </File>\r
+                       </Filter>\r
+               </Filter>\r
+               <Filter\r
+                       Name="amcp"\r
+                       >\r
+                       <File\r
+                               RelativePath=".\AMCP\AMCPCommand.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\AMCP\AMCPCommandQueue.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\AMCP\AMCPCommandQueue.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\AMCP\AMCPCommandsImpl.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\AMCP\AMCPCommandsImpl.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\AMCP\AMCPProtocolStrategy.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\AMCP\AMCPProtocolStrategy.h"\r
+                               >\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="audio"\r
+                       >\r
+                       <File\r
+                               RelativePath=".\audio\AudioManager.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\audio\DirectSoundManager.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\audio\DirectSoundManager.h"\r
+                               >\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="frame"\r
+                       >\r
+                       <File\r
+                               RelativePath=".\frame\BitmapFrame.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\frame\BitmapFrame.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\frame\BitmapFrameAdapter.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="../StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="../StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\frame\BitmapFrameAdapter.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\frame\BitmapFrameManager.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\frame\BitmapFrameManager.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\frame\BitmapFrameManagerAdapter.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="../StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="../StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="../StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\frame\BitmapFrameManagerAdapter.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\frame\ClipInfo.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\frame\Frame.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\frame\Frame.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\frame\FrameManager.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\frame\FrameMediaController.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\frame\FramePlaybackControl.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\frame\FramePlaybackControl.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\frame\FramePlaybackStrategy.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\frame\SystemFrame.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\frame\SystemFrame.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\frame\SystemFrameManager.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\frame\SystemFrameManager.h"\r
+                               >\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="CLK"\r
+                       >\r
+                       <File\r
+                               RelativePath=".\CLK\CLKCommand.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\CLK\CLKCommand.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\CLK\CLKProtocolStrategy.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\CLK\CLKProtocolStrategy.h"\r
+                               >\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="cii"\r
+                       >\r
+                       <File\r
+                               RelativePath=".\CII\CIICommand.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\CII\CIICommandsImpl.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\CII\CIICommandsImpl.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\CII\CIIProtocolStrategy.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="no bluefish|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="SVT special|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PrecompiledHeaderThrough="..\StdAfx.h"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\CII\CIIProtocolStrategy.h"\r
+                               >\r
+                       </File>\r
+               </Filter>\r
+               <File\r
+                       RelativePath=".\Application.cpp"\r
+                       >\r
+               </File>\r
+               <File\r
+                       RelativePath=".\Application.h"\r
+                       >\r
+               </File>\r
+               <File\r
+                       RelativePath=".\Channel.cpp"\r
+                       >\r
+               </File>\r
+               <File\r
+                       RelativePath=".\Channel.h"\r
+                       >\r
+               </File>\r
+               <File\r
+                       RelativePath=".\Controller.h"\r
+                       >\r
+               </File>\r
+               <File\r
+                       RelativePath=".\FileInfo.h"\r
+                       >\r
+               </File>\r
+               <File\r
+                       RelativePath=".\Main.cpp"\r
+                       >\r
+               </File>\r
+               <File\r
+                       RelativePath=".\MediaController.h"\r
+                       >\r
+               </File>\r
+               <File\r
+                       RelativePath=".\MediaManager.h"\r
+                       >\r
+               </File>\r
+               <File\r
+                       RelativePath=".\MediaProducer.h"\r
+                       >\r
+               </File>\r
+               <File\r
+                       RelativePath=".\MediaProducerInfo.h"\r
+                       >\r
+               </File>\r
+               <File\r
+                       RelativePath=".\Monitor.cpp"\r
+                       >\r
+               </File>\r
+               <File\r
+                       RelativePath=".\Monitor.h"\r
+                       >\r
+               </File>\r
+               <File\r
+                       RelativePath=".\PlaybackControl.h"\r
+                       >\r
+                       <FileConfiguration\r
+                               Name="Debug|Win32"\r
+                               >\r
+                               <Tool\r
+                                       Name="VCCustomBuildTool"\r
+                               />\r
+                       </FileConfiguration>\r
+                       <FileConfiguration\r
+                               Name="Release|Win32"\r
+                               >\r
+                               <Tool\r
+                                       Name="VCCustomBuildTool"\r
+                               />\r
+                       </FileConfiguration>\r
+                       <FileConfiguration\r
+                               Name="no bluefish|Win32"\r
+                               >\r
+                               <Tool\r
+                                       Name="VCCustomBuildTool"\r
+                               />\r
+                       </FileConfiguration>\r
+                       <FileConfiguration\r
+                               Name="SVT special|Win32"\r
+                               >\r
+                               <Tool\r
+                                       Name="VCCustomBuildTool"\r
+                               />\r
+                       </FileConfiguration>\r
+               </File>\r
+               <File\r
+                       RelativePath=".\Resource.h"\r
+                       >\r
+               </File>\r
+               <File\r
+                       RelativePath=".\StdAfx.cpp"\r
+                       >\r
+                       <FileConfiguration\r
+                               Name="Debug|Win32"\r
+                               >\r
+                               <Tool\r
+                                       Name="VCCLCompilerTool"\r
+                                       UsePrecompiledHeader="1"\r
+                               />\r
+                       </FileConfiguration>\r
+                       <FileConfiguration\r
+                               Name="Release|Win32"\r
+                               >\r
+                               <Tool\r
+                                       Name="VCCLCompilerTool"\r
+                                       UsePrecompiledHeader="1"\r
+                               />\r
+                       </FileConfiguration>\r
+                       <FileConfiguration\r
+                               Name="no bluefish|Win32"\r
+                               >\r
+                               <Tool\r
+                                       Name="VCCLCompilerTool"\r
+                                       UsePrecompiledHeader="1"\r
+                               />\r
+                       </FileConfiguration>\r
+                       <FileConfiguration\r
+                               Name="SVT special|Win32"\r
+                               >\r
+                               <Tool\r
+                                       Name="VCCLCompilerTool"\r
+                                       UsePrecompiledHeader="1"\r
+                               />\r
+                       </FileConfiguration>\r
+               </File>\r
+               <File\r
+                       RelativePath=".\StdAfx.h"\r
+                       >\r
+               </File>\r
+               <File\r
+                       RelativePath=".\TransitionInfo.h"\r
+                       >\r
+               </File>\r
+               <File\r
+                       RelativePath=".\VersionNo.h"\r
+                       >\r
+               </File>\r
+               <File\r
+                       RelativePath=".\VideoConsumer.h"\r
+                       >\r
+               </File>\r
+               <File\r
+                       RelativePath=".\Window.cpp"\r
+                       >\r
+               </File>\r
+               <File\r
+                       RelativePath=".\Window.h"\r
+                       >\r
+               </File>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/server/Server.vcxproj b/server/Server.vcxproj
new file mode 100644 (file)
index 0000000..3813c54
--- /dev/null
@@ -0,0 +1,795 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup Label="ProjectConfigurations">\r
+    <ProjectConfiguration Include="Debug|Win32">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="no bluefish|Win32">\r
+      <Configuration>no bluefish</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|Win32">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+  </ItemGroup>\r
+  <PropertyGroup Label="Globals">\r
+    <ProjectGuid>{79388C20-6499-4BF6-B8B9-D8C33D7D4DDD}</ProjectGuid>\r
+    <RootNamespace>Server</RootNamespace>\r
+    <Keyword>Win32Proj</Keyword>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
+  <ImportGroup Label="ExtensionSettings">\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />\r
+  </ImportGroup>\r
+  <PropertyGroup Label="UserMacros" />\r
+  <PropertyGroup>\r
+    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)build\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">debug\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)build\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">release\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">$(SolutionDir)$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">$(Configuration)\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">false</LinkIncremental>\r
+    <SourcePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">C:\Lokala Filer\SDK\ffmpeg\src\ffmpeg-export-2008-11-05\libavcodec\i386;$(SourcePath)</SourcePath>\r
+  </PropertyGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <PreBuildEvent>\r
+      <Command>\r
+      </Command>\r
+    </PreBuildEvent>\r
+    <ClCompile>\r
+      <Optimization>Disabled</Optimization>\r
+      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <MinimalRebuild>true</MinimalRebuild>\r
+      <ExceptionHandling>Async</ExceptionHandling>\r
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
+      <SmallerTypeCheck>true</SmallerTypeCheck>\r
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
+      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>\r
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>\r
+      <PrecompiledHeader>Use</PrecompiledHeader>\r
+      <BrowseInformation>true</BrowseInformation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>\r
+    </ClCompile>\r
+    <Link>\r
+      <AdditionalDependencies>GLee.lib;Dxguid.lib;Dsound.lib;Winmm.lib;Ws2_32.lib;BlueVelvet3_d.lib;avformat-52.lib;avcodec-52.lib;avutil-50.lib;swscale-0.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <Version>\r
+      </Version>\r
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
+      <IgnoreSpecificDefaultLibraries>LIBC.LIB;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <ProgramDatabaseFile>$(TargetDir)$(TargetName).pdb</ProgramDatabaseFile>\r
+      <GenerateMapFile>true</GenerateMapFile>\r
+      <MapFileName>\r
+      </MapFileName>\r
+      <SubSystem>Windows</SubSystem>\r
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
+      <DataExecutionPrevention>\r
+      </DataExecutionPrevention>\r
+      <TargetMachine>MachineX86</TargetMachine>\r
+    </Link>\r
+    <PostBuildEvent>\r
+      <Command>\r
+      </Command>\r
+    </PostBuildEvent>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <PreBuildEvent>\r
+      <Command>\r
+      </Command>\r
+    </PreBuildEvent>\r
+    <ClCompile>\r
+      <Optimization>MaxSpeed</Optimization>\r
+      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>\r
+      <IntrinsicFunctions>true</IntrinsicFunctions>\r
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>\r
+      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <ExceptionHandling>Async</ExceptionHandling>\r
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
+      <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>\r
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>\r
+      <PrecompiledHeader>Use</PrecompiledHeader>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>\r
+    </ClCompile>\r
+    <PreLinkEvent>\r
+      <Command>\r
+      </Command>\r
+    </PreLinkEvent>\r
+    <Link>\r
+      <AdditionalDependencies>Dxguid.lib;Dsound.lib;Winmm.lib;Ws2_32.lib;Bluevelvet3.lib;avformat-52.lib;avcodec-52.lib;avutil-50.lib;swscale-0.lib;tbb.lib;Glee.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <Version>\r
+      </Version>\r
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
+      <IgnoreSpecificDefaultLibraries>LIBC.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <GenerateMapFile>true</GenerateMapFile>\r
+      <MapExports>true</MapExports>\r
+      <SubSystem>Windows</SubSystem>\r
+      <OptimizeReferences>\r
+      </OptimizeReferences>\r
+      <EnableCOMDATFolding>\r
+      </EnableCOMDATFolding>\r
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
+      <FixedBaseAddress>false</FixedBaseAddress>\r
+      <DataExecutionPrevention>\r
+      </DataExecutionPrevention>\r
+      <TargetMachine>MachineX86</TargetMachine>\r
+    </Link>\r
+    <PostBuildEvent>\r
+      <Command>\r
+      </Command>\r
+    </PostBuildEvent>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">\r
+    <PreBuildEvent>\r
+      <Command>\r
+      </Command>\r
+    </PreBuildEvent>\r
+    <ClCompile>\r
+      <Optimization>Disabled</Optimization>\r
+      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>\r
+      <IntrinsicFunctions>true</IntrinsicFunctions>\r
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>\r
+      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>DISABLE_BLUEFISH;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <ExceptionHandling>Async</ExceptionHandling>\r
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
+      <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>\r
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>\r
+      <PrecompiledHeader>Use</PrecompiledHeader>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+    </ClCompile>\r
+    <PreLinkEvent>\r
+      <Command>\r
+      </Command>\r
+    </PreLinkEvent>\r
+    <Link>\r
+      <AdditionalDependencies>Dxguid.lib;Dsound.lib;Winmm.lib;Ws2_32.lib;avformat-52.lib;avcodec-52.lib;avutil-50.lib;swscale-0.lib;GLee.lib;tbb.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <Version>\r
+      </Version>\r
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
+      <IgnoreSpecificDefaultLibraries>LIBC.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <GenerateMapFile>true</GenerateMapFile>\r
+      <MapExports>true</MapExports>\r
+      <SubSystem>Windows</SubSystem>\r
+      <OptimizeReferences>\r
+      </OptimizeReferences>\r
+      <EnableCOMDATFolding>\r
+      </EnableCOMDATFolding>\r
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
+      <FixedBaseAddress>false</FixedBaseAddress>\r
+      <DataExecutionPrevention>\r
+      </DataExecutionPrevention>\r
+      <TargetMachine>MachineX86</TargetMachine>\r
+    </Link>\r
+    <PostBuildEvent>\r
+      <Command>\r
+      </Command>\r
+    </PostBuildEvent>\r
+  </ItemDefinitionGroup>\r
+  <ItemGroup>\r
+    <None Include="resources\Icon2.ico" />\r
+    <None Include="resources\server.rc2" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ResourceCompile Include="resources\Server.rc" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClInclude Include="frame\buffers\FrameBuffer.h" />\r
+    <ClInclude Include="frame\buffers\MotionFrameBuffer.h" />\r
+    <ClInclude Include="frame\buffers\StaticFrameBuffer.h" />\r
+    <ClInclude Include="producers\ffmpeg\audio\FFMPEGAudioDecoder.h" />\r
+    <ClInclude Include="producers\ffmpeg\FFMPEGException.h" />\r
+    <ClInclude Include="producers\ffmpeg\FFMPEGFrameOutput.h" />\r
+    <ClInclude Include="producers\ffmpeg\FFMPEGInput.h" />\r
+    <ClInclude Include="producers\ffmpeg\FFMPEGOutput.h" />\r
+    <ClInclude Include="producers\ffmpeg\FFMPEGPacket.h" />\r
+    <ClInclude Include="producers\ffmpeg\FFMPEGProducer.h" />\r
+    <ClInclude Include="producers\ffmpeg\video\FFMPEGVideoDecoder.h" />\r
+    <ClInclude Include="producers\ffmpeg\video\FFMPEGVideoDeinterlacer.h" />\r
+    <ClInclude Include="producers\ffmpeg\video\FFMPEGVideoScaler.h" />\r
+    <ClInclude Include="string_convert.h" />\r
+    <ClInclude Include="Utils\Allocator.h" />\r
+    <ClInclude Include="utils\BitmapHolder.h" />\r
+    <ClInclude Include="Utils\CommandQueue.h" />\r
+    <ClInclude Include="utils\CPUID.hpp" />\r
+    <ClInclude Include="Utils\CritSectLock.h" />\r
+    <ClInclude Include="Utils\DataBuffer.h" />\r
+    <ClInclude Include="utils\DCWrapper.h" />\r
+    <ClInclude Include="Utils\Event.h" />\r
+    <ClInclude Include="Utils\FileExists.h" />\r
+    <ClInclude Include="Utils\FileInputStream.h" />\r
+    <ClInclude Include="Utils\FileOutputStream.h" />\r
+    <ClInclude Include="Utils\FindWrapper.h" />\r
+    <ClInclude Include="utils\functiontask.hpp" />\r
+    <ClInclude Include="Utils\ID.h" />\r
+    <ClInclude Include="Utils\InputStream.h" />\r
+    <ClInclude Include="Utils\Lockable.h" />\r
+    <ClInclude Include="utils\LogException.h" />\r
+    <ClInclude Include="Utils\Logger.h" />\r
+    <ClInclude Include="utils\LogLevel.h" />\r
+    <ClInclude Include="utils\LogStream.h" />\r
+    <ClInclude Include="utils\Noncopyable.hpp" />\r
+    <ClInclude Include="utils\ObjectPool.h" />\r
+    <ClInclude Include="Utils\OutputStream.h" />\r
+    <ClInclude Include="Utils\PixmapData.h" />\r
+    <ClInclude Include="utils\Process.h" />\r
+    <ClInclude Include="Utils\Runnable.h" />\r
+    <ClInclude Include="utils\scope_exit.h" />\r
+    <ClInclude Include="Utils\Semaphore.h" />\r
+    <ClInclude Include="utils\TaskQueue.h" />\r
+    <ClInclude Include="Utils\Thread.h" />\r
+    <ClInclude Include="utils\Types.hpp" />\r
+    <ClInclude Include="utils\UnhandledException.h" />\r
+    <ClInclude Include="Utils\Win32Exception.h" />\r
+    <ClInclude Include="Utils\image\Clear.hpp" />\r
+    <ClInclude Include="Utils\image\Copy.hpp" />\r
+    <ClInclude Include="utils\image\CopyField.hpp" />\r
+    <ClInclude Include="utils\image\Image.hpp" />\r
+    <ClInclude Include="utils\image\Lerp.hpp" />\r
+    <ClInclude Include="utils\image\Over.hpp" />\r
+    <ClInclude Include="utils\image\Premultiply.hpp" />\r
+    <ClInclude Include="utils\image\Shuffle.hpp" />\r
+    <ClInclude Include="IO\AsyncEventServer.h" />\r
+    <ClInclude Include="IO\ClientInfo.h" />\r
+    <ClInclude Include="IO\ProtocolStrategy.h" />\r
+    <ClInclude Include="IO\SerialPort.h" />\r
+    <ClInclude Include="IO\SocketInfo.h" />\r
+    <CustomBuildStep Include="consumers\bluefish\BluefishException.h" />\r
+    <CustomBuildStep Include="consumers\bluefish\BluefishFrameManager.h" />\r
+    <CustomBuildStep Include="consumers\bluefish\BluefishPlaybackStrategy.h" />\r
+    <CustomBuildStep Include="consumers\bluefish\BlueFishVideoConsumer.h" />\r
+    <ClInclude Include="consumers\GDI\GDIVideoConsumer.h" />\r
+    <ClInclude Include="Consumers\OGL\OGLVideoConsumer.h" />\r
+    <ClInclude Include="consumers\Audio\AudioConsumer.h" />\r
+    <ClInclude Include="consumers\decklink\DeckLinkAPI_h.h" />\r
+    <ClInclude Include="consumers\decklink\DecklinkVideoConsumer.h" />\r
+    <ClInclude Include="cg\CGControl.h" />\r
+    <ClInclude Include="cg\FlashCGProxy.h" />\r
+    <ClInclude Include="Producers\ffmpeg\FFmpegManager.h" />\r
+    <ClInclude Include="Producers\flash\AxFlash.h" />\r
+    <ClInclude Include="producers\flash\CTManager.h" />\r
+    <ClInclude Include="Producers\flash\FlashAxContainer.h" />\r
+    <ClInclude Include="Producers\flash\FlashCommand.h" />\r
+    <ClInclude Include="Producers\flash\FlashCommandQueue.h" />\r
+    <ClInclude Include="producers\flash\FlashManager.h" />\r
+    <ClInclude Include="Producers\flash\FlashProducer.h" />\r
+    <ClInclude Include="Producers\flash\TimerHelper.h" />\r
+    <ClInclude Include="producers\color\ColorManager.h" />\r
+    <ClInclude Include="producers\targa\TargaManager.h" />\r
+    <ClInclude Include="producers\composites\FrameCompositeProducer.h" />\r
+    <ClInclude Include="producers\composites\TransitionProducer.h" />\r
+    <ClInclude Include="producers\targascroll\TargaScrollManager.h" />\r
+    <ClInclude Include="producers\targascroll\TargaScrollProducer.h" />\r
+    <ClInclude Include="AMCP\AMCPCommand.h" />\r
+    <ClInclude Include="AMCP\AMCPCommandQueue.h" />\r
+    <ClInclude Include="AMCP\AMCPCommandsImpl.h" />\r
+    <ClInclude Include="AMCP\AMCPProtocolStrategy.h" />\r
+    <ClInclude Include="audio\AudioManager.h" />\r
+    <ClInclude Include="audio\DirectSoundManager.h" />\r
+    <ClInclude Include="frame\BitmapFrame.h" />\r
+    <ClInclude Include="frame\BitmapFrameAdapter.h" />\r
+    <ClInclude Include="frame\BitmapFrameManager.h" />\r
+    <ClInclude Include="frame\BitmapFrameManagerAdapter.h" />\r
+    <ClInclude Include="frame\ClipInfo.h" />\r
+    <ClInclude Include="frame\Frame.h" />\r
+    <ClInclude Include="frame\FrameManager.h" />\r
+    <ClInclude Include="frame\FrameMediaController.h" />\r
+    <ClInclude Include="frame\FramePlaybackControl.h" />\r
+    <ClInclude Include="frame\FramePlaybackStrategy.h" />\r
+    <ClInclude Include="frame\SystemFrame.h" />\r
+    <ClInclude Include="frame\SystemFrameManager.h" />\r
+    <ClInclude Include="CLK\CLKCommand.h" />\r
+    <ClInclude Include="CLK\CLKProtocolStrategy.h" />\r
+    <ClInclude Include="CII\CIICommand.h" />\r
+    <ClInclude Include="CII\CIICommandsImpl.h" />\r
+    <ClInclude Include="CII\CIIProtocolStrategy.h" />\r
+    <ClInclude Include="Application.h" />\r
+    <ClInclude Include="Channel.h" />\r
+    <ClInclude Include="Controller.h" />\r
+    <ClInclude Include="FileInfo.h" />\r
+    <ClInclude Include="MediaController.h" />\r
+    <ClInclude Include="MediaManager.h" />\r
+    <ClInclude Include="MediaProducer.h" />\r
+    <ClInclude Include="MediaProducerInfo.h" />\r
+    <ClInclude Include="Monitor.h" />\r
+    <CustomBuildStep Include="PlaybackControl.h" />\r
+    <ClInclude Include="Resource.h" />\r
+    <ClInclude Include="StdAfx.h" />\r
+    <ClInclude Include="TransitionInfo.h" />\r
+    <ClInclude Include="VersionNo.h" />\r
+    <ClInclude Include="VideoConsumer.h" />\r
+    <ClInclude Include="Window.h" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="frame\buffers\MotionFrameBuffer.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="frame\buffers\StaticFrameBuffer.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\ffmpeg\audio\FFMPEGAudioDecoder.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\ffmpeg\FFMPEGFrameOutput.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\ffmpeg\FFMPEGInput.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\ffmpeg\FFMPEGOutput.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\ffmpeg\FFMPEGPacket.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\ffmpeg\FFMPEGProducer.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\ffmpeg\video\FFMPEGVideoDecoder.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\ffmpeg\video\FFMPEGVideoDeinterlacer.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\ffmpeg\video\FFMPEGVideoScaler.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="utils\BitmapHolder.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="utils\CPUID.cpp">\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+      </PrecompiledHeader>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+      </PrecompiledHeader>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">\r
+      </PrecompiledHeader>\r
+    </ClCompile>\r
+    <ClCompile Include="utils\DCWrapper.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="Utils\Event.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="Utils\FileExists.cpp">\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">Use</PrecompiledHeader>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="Utils\FileInputStream.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="Utils\FileOutputStream.cpp">\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">Use</PrecompiledHeader>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="Utils\FindWrapper.cpp">\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">Use</PrecompiledHeader>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="Utils\ID.cpp" />\r
+    <ClCompile Include="utils\LogException.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="Utils\Logger.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="utils\LogStream.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="utils\Process.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="Utils\Semaphore.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="Utils\Thread.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="Utils\Win32Exception.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="Utils\image\Clear.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="Utils\image\Copy.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="utils\image\CopyField.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="utils\image\Image.cpp">\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">Use</PrecompiledHeader>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="utils\image\Lerp.cpp">\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">Use</PrecompiledHeader>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="utils\image\Over.cpp">\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">Use</PrecompiledHeader>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="utils\image\Premultiply.cpp">\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">Use</PrecompiledHeader>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="utils\image\Shuffle.cpp">\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">Use</PrecompiledHeader>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="IO\AsyncEventServer.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="IO\SerialPort.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="IO\SocketInfo.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="consumers\bluefish\BluefishFrameManager.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\stdafx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\stdafx.h</PrecompiledHeaderFile>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">true</ExcludedFromBuild>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\stdafx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="consumers\bluefish\BluefishPlaybackStrategy.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\stdafx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\stdafx.h</PrecompiledHeaderFile>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">true</ExcludedFromBuild>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\stdafx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="consumers\bluefish\BlueFishVideoConsumer.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\stdafx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\stdafx.h</PrecompiledHeaderFile>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">true</ExcludedFromBuild>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\stdafx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="consumers\GDI\GDIVideoConsumer.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="Consumers\OGL\OGLVideoConsumer.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="consumers\Audio\AudioConsumer.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="consumers\decklink\DeckLinkAPI_i.c">\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+      </PrecompiledHeader>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+      </PrecompiledHeader>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">\r
+      </PrecompiledHeader>\r
+    </ClCompile>\r
+    <ClCompile Include="consumers\decklink\DecklinkVideoConsumer.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="cg\FlashCGProxy.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="Producers\ffmpeg\FFmpegManager.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\flash\CTManager.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="Producers\flash\Flash9e_i.c">\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+      </PrecompiledHeader>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+      </PrecompiledHeader>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">\r
+      </PrecompiledHeader>\r
+    </ClCompile>\r
+    <ClCompile Include="Producers\flash\FlashAxContainer.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="Producers\flash\FlashCommand.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="Producers\flash\FlashCommandQueue.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\flash\FlashManager.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="Producers\flash\FlashProducer.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\color\ColorManager.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\targa\TargaManager.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\composites\FrameCompositeProducer.cpp">\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">true</ExcludedFromBuild>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\composites\TransitionProducer.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\targascroll\TargaScrollManager.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\targascroll\TargaScrollProducer.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="AMCP\AMCPCommandQueue.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="AMCP\AMCPCommandsImpl.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="AMCP\AMCPProtocolStrategy.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="audio\DirectSoundManager.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="frame\BitmapFrame.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="frame\BitmapFrameAdapter.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="frame\BitmapFrameManager.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="frame\BitmapFrameManagerAdapter.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="frame\Frame.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="frame\FramePlaybackControl.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="frame\SystemFrame.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="frame\SystemFrameManager.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="CLK\CLKCommand.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="CLK\CLKProtocolStrategy.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="CII\CIICommandsImpl.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="CII\CIIProtocolStrategy.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">..\StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="Application.cpp" />\r
+    <ClCompile Include="Channel.cpp" />\r
+    <ClCompile Include="Main.cpp" />\r
+    <ClCompile Include="Monitor.cpp" />\r
+    <ClCompile Include="StdAfx.cpp">\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">Create</PrecompiledHeader>\r
+    </ClCompile>\r
+    <ClCompile Include="Window.cpp" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <Midl Include="consumers\decklink\DeckLinkAPI.idl">\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">true</ExcludedFromBuild>\r
+    </Midl>\r
+    <Midl Include="consumers\decklink\DeckLinkAPI_v7_1.idl">\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">true</ExcludedFromBuild>\r
+    </Midl>\r
+    <Midl Include="consumers\decklink\DeckLinkAPI_v7_3.idl">\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">true</ExcludedFromBuild>\r
+    </Midl>\r
+    <Midl Include="Producers\flash\Flash9e.IDL">\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='no bluefish|Win32'">true</ExcludedFromBuild>\r
+    </Midl>\r
+  </ItemGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
+  <ImportGroup Label="ExtensionTargets">\r
+  </ImportGroup>\r
+</Project>
\ No newline at end of file
diff --git a/server/Server.vcxproj.filters b/server/Server.vcxproj.filters
new file mode 100644 (file)
index 0000000..06f6ec3
--- /dev/null
@@ -0,0 +1,692 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup>\r
+    <Filter Include="resources">\r
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\r
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions>\r
+    </Filter>\r
+    <Filter Include="utils">\r
+      <UniqueIdentifier>{de65234e-d9fe-4005-af84-09ea8eeda314}</UniqueIdentifier>\r
+    </Filter>\r
+    <Filter Include="utils\image">\r
+      <UniqueIdentifier>{5322381c-6ced-444c-8f53-ae02ebdd1cd5}</UniqueIdentifier>\r
+    </Filter>\r
+    <Filter Include="io">\r
+      <UniqueIdentifier>{5782c398-5fef-43f1-b52e-0b099f648a93}</UniqueIdentifier>\r
+    </Filter>\r
+    <Filter Include="consumers">\r
+      <UniqueIdentifier>{de0e92f0-d699-4302-9362-d3bee8f8621d}</UniqueIdentifier>\r
+    </Filter>\r
+    <Filter Include="consumers\bluefish">\r
+      <UniqueIdentifier>{4461591f-a286-4c8d-9f0a-303befed0603}</UniqueIdentifier>\r
+    </Filter>\r
+    <Filter Include="consumers\gdi">\r
+      <UniqueIdentifier>{d87ea4f0-ef3f-4647-9655-ac378bb21224}</UniqueIdentifier>\r
+    </Filter>\r
+    <Filter Include="consumers\ogl">\r
+      <UniqueIdentifier>{8454244b-d974-4c5c-8c8f-eb024eb304fe}</UniqueIdentifier>\r
+    </Filter>\r
+    <Filter Include="consumers\audio">\r
+      <UniqueIdentifier>{642f599a-19a8-4082-acf5-e74e8666c4ac}</UniqueIdentifier>\r
+    </Filter>\r
+    <Filter Include="consumers\decklink">\r
+      <UniqueIdentifier>{f7d3bde2-2d03-4bac-808c-93ff623d7279}</UniqueIdentifier>\r
+    </Filter>\r
+    <Filter Include="cg">\r
+      <UniqueIdentifier>{ff78e1a7-a8d8-4660-91f6-f374f0124d72}</UniqueIdentifier>\r
+    </Filter>\r
+    <Filter Include="producers">\r
+      <UniqueIdentifier>{6f75412d-3d6d-4603-a638-c03d08598942}</UniqueIdentifier>\r
+    </Filter>\r
+    <Filter Include="producers\ffmpeg">\r
+      <UniqueIdentifier>{bbdb38a3-e939-426f-824c-13665bafdce1}</UniqueIdentifier>\r
+    </Filter>\r
+    <Filter Include="producers\flash">\r
+      <UniqueIdentifier>{b97c7904-7f85-4930-9966-8b00c0686a3b}</UniqueIdentifier>\r
+    </Filter>\r
+    <Filter Include="producers\color">\r
+      <UniqueIdentifier>{442348e2-9459-42b2-b688-965775724270}</UniqueIdentifier>\r
+    </Filter>\r
+    <Filter Include="producers\targa">\r
+      <UniqueIdentifier>{73ab2334-4260-4806-86c5-d04316b05706}</UniqueIdentifier>\r
+    </Filter>\r
+    <Filter Include="producers\composites">\r
+      <UniqueIdentifier>{5f667ffb-04d6-4bdf-be40-47277b4aba35}</UniqueIdentifier>\r
+    </Filter>\r
+    <Filter Include="producers\targascroll">\r
+      <UniqueIdentifier>{ac3a349b-4646-4fc1-bdb1-2a3ea9c6e89d}</UniqueIdentifier>\r
+    </Filter>\r
+    <Filter Include="amcp">\r
+      <UniqueIdentifier>{d33e8ddc-ccb4-4f4f-ad20-e788a796bb7b}</UniqueIdentifier>\r
+    </Filter>\r
+    <Filter Include="frame">\r
+      <UniqueIdentifier>{69627759-fb18-42fa-8339-66ce27062c90}</UniqueIdentifier>\r
+    </Filter>\r
+    <Filter Include="CLK">\r
+      <UniqueIdentifier>{8355a891-c4db-4a0e-8ecc-795314127cdc}</UniqueIdentifier>\r
+    </Filter>\r
+    <Filter Include="cii">\r
+      <UniqueIdentifier>{a94bc00a-4753-4bce-a777-6a3ea2ceca59}</UniqueIdentifier>\r
+    </Filter>\r
+    <Filter Include="frame\buffers">\r
+      <UniqueIdentifier>{5f57e8d6-78fb-4784-9dea-91e0c95d8aec}</UniqueIdentifier>\r
+    </Filter>\r
+    <Filter Include="producers\ffmpeg\video">\r
+      <UniqueIdentifier>{a6fee242-7d42-4f2e-8c32-ebc57afc38bc}</UniqueIdentifier>\r
+    </Filter>\r
+    <Filter Include="producers\ffmpeg\audio">\r
+      <UniqueIdentifier>{b820b516-95a2-48ac-a302-75e1280375ae}</UniqueIdentifier>\r
+    </Filter>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <None Include="resources\Icon2.ico">\r
+      <Filter>resources</Filter>\r
+    </None>\r
+    <None Include="resources\server.rc2">\r
+      <Filter>resources</Filter>\r
+    </None>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ResourceCompile Include="resources\Server.rc">\r
+      <Filter>resources</Filter>\r
+    </ResourceCompile>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClInclude Include="Utils\Allocator.h">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="utils\BitmapHolder.h">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Utils\CommandQueue.h">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="utils\CPUID.hpp">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Utils\CritSectLock.h">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Utils\DataBuffer.h">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="utils\DCWrapper.h">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Utils\Event.h">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Utils\FileExists.h">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Utils\FileInputStream.h">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Utils\FileOutputStream.h">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Utils\FindWrapper.h">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Utils\ID.h">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Utils\InputStream.h">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Utils\Lockable.h">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="utils\LogException.h">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Utils\Logger.h">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="utils\LogLevel.h">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="utils\LogStream.h">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="utils\Noncopyable.hpp">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Utils\OutputStream.h">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Utils\PixmapData.h">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="utils\Process.h">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Utils\Runnable.h">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Utils\Semaphore.h">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="utils\TaskQueue.h">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Utils\Thread.h">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="utils\Types.hpp">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Utils\Win32Exception.h">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Utils\image\Clear.hpp">\r
+      <Filter>utils\image</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Utils\image\Copy.hpp">\r
+      <Filter>utils\image</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="utils\image\CopyField.hpp">\r
+      <Filter>utils\image</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="utils\image\Image.hpp">\r
+      <Filter>utils\image</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="utils\image\Lerp.hpp">\r
+      <Filter>utils\image</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="utils\image\Over.hpp">\r
+      <Filter>utils\image</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="utils\image\Premultiply.hpp">\r
+      <Filter>utils\image</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="utils\image\Shuffle.hpp">\r
+      <Filter>utils\image</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="IO\AsyncEventServer.h">\r
+      <Filter>io</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="IO\ClientInfo.h">\r
+      <Filter>io</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="IO\ProtocolStrategy.h">\r
+      <Filter>io</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="IO\SerialPort.h">\r
+      <Filter>io</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="IO\SocketInfo.h">\r
+      <Filter>io</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="consumers\GDI\GDIVideoConsumer.h">\r
+      <Filter>consumers\gdi</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Consumers\OGL\OGLVideoConsumer.h">\r
+      <Filter>consumers\ogl</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="consumers\Audio\AudioConsumer.h">\r
+      <Filter>consumers\audio</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="consumers\decklink\DeckLinkAPI_h.h">\r
+      <Filter>consumers\decklink</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="consumers\decklink\DecklinkVideoConsumer.h">\r
+      <Filter>consumers\decklink</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="cg\CGControl.h">\r
+      <Filter>cg</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="cg\FlashCGProxy.h">\r
+      <Filter>cg</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Producers\ffmpeg\FFmpegManager.h">\r
+      <Filter>producers\ffmpeg</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Producers\flash\AxFlash.h">\r
+      <Filter>producers\flash</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="producers\flash\CTManager.h">\r
+      <Filter>producers\flash</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Producers\flash\FlashAxContainer.h">\r
+      <Filter>producers\flash</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Producers\flash\FlashCommand.h">\r
+      <Filter>producers\flash</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Producers\flash\FlashCommandQueue.h">\r
+      <Filter>producers\flash</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="producers\flash\FlashManager.h">\r
+      <Filter>producers\flash</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Producers\flash\FlashProducer.h">\r
+      <Filter>producers\flash</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Producers\flash\TimerHelper.h">\r
+      <Filter>producers\flash</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="producers\color\ColorManager.h">\r
+      <Filter>producers\color</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="producers\targa\TargaManager.h">\r
+      <Filter>producers\targa</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="producers\composites\FrameCompositeProducer.h">\r
+      <Filter>producers\composites</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="producers\composites\TransitionProducer.h">\r
+      <Filter>producers\composites</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="producers\targascroll\TargaScrollManager.h">\r
+      <Filter>producers\targascroll</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="producers\targascroll\TargaScrollProducer.h">\r
+      <Filter>producers\targascroll</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="AMCP\AMCPCommand.h">\r
+      <Filter>amcp</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="AMCP\AMCPCommandQueue.h">\r
+      <Filter>amcp</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="AMCP\AMCPCommandsImpl.h">\r
+      <Filter>amcp</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="AMCP\AMCPProtocolStrategy.h">\r
+      <Filter>amcp</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="audio\AudioManager.h">\r
+      <Filter>consumers\audio</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="audio\DirectSoundManager.h">\r
+      <Filter>consumers\audio</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="frame\BitmapFrame.h">\r
+      <Filter>frame</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="frame\BitmapFrameAdapter.h">\r
+      <Filter>frame</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="frame\BitmapFrameManager.h">\r
+      <Filter>frame</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="frame\BitmapFrameManagerAdapter.h">\r
+      <Filter>frame</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="frame\ClipInfo.h">\r
+      <Filter>frame</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="frame\Frame.h">\r
+      <Filter>frame</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="frame\FrameManager.h">\r
+      <Filter>frame</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="frame\FrameMediaController.h">\r
+      <Filter>frame</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="frame\FramePlaybackControl.h">\r
+      <Filter>frame</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="frame\FramePlaybackStrategy.h">\r
+      <Filter>frame</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="frame\SystemFrame.h">\r
+      <Filter>frame</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="frame\SystemFrameManager.h">\r
+      <Filter>frame</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="CLK\CLKCommand.h">\r
+      <Filter>CLK</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="CLK\CLKProtocolStrategy.h">\r
+      <Filter>CLK</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="CII\CIICommand.h">\r
+      <Filter>cii</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="CII\CIICommandsImpl.h">\r
+      <Filter>cii</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="CII\CIIProtocolStrategy.h">\r
+      <Filter>cii</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Application.h" />\r
+    <ClInclude Include="Channel.h" />\r
+    <ClInclude Include="Controller.h" />\r
+    <ClInclude Include="FileInfo.h" />\r
+    <ClInclude Include="MediaController.h" />\r
+    <ClInclude Include="MediaManager.h" />\r
+    <ClInclude Include="MediaProducer.h" />\r
+    <ClInclude Include="MediaProducerInfo.h" />\r
+    <ClInclude Include="Monitor.h" />\r
+    <ClInclude Include="Resource.h" />\r
+    <ClInclude Include="StdAfx.h" />\r
+    <ClInclude Include="TransitionInfo.h" />\r
+    <ClInclude Include="VersionNo.h" />\r
+    <ClInclude Include="VideoConsumer.h" />\r
+    <ClInclude Include="Window.h" />\r
+    <ClInclude Include="frame\buffers\FrameBuffer.h">\r
+      <Filter>frame\buffers</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="frame\buffers\MotionFrameBuffer.h">\r
+      <Filter>frame\buffers</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="frame\buffers\StaticFrameBuffer.h">\r
+      <Filter>frame\buffers</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="string_convert.h" />\r
+    <ClInclude Include="producers\ffmpeg\video\FFMPEGVideoScaler.h">\r
+      <Filter>producers\ffmpeg\video</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="producers\ffmpeg\video\FFMPEGVideoDeinterlacer.h">\r
+      <Filter>producers\ffmpeg\video</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="producers\ffmpeg\video\FFMPEGVideoDecoder.h">\r
+      <Filter>producers\ffmpeg\video</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="producers\ffmpeg\audio\FFMPEGAudioDecoder.h">\r
+      <Filter>producers\ffmpeg\audio</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="producers\ffmpeg\FFMPEGException.h">\r
+      <Filter>producers\ffmpeg</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="producers\ffmpeg\FFMPEGProducer.h">\r
+      <Filter>producers\ffmpeg</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="producers\ffmpeg\FFMPEGFrameOutput.h">\r
+      <Filter>producers\ffmpeg</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="producers\ffmpeg\FFMPEGInput.h">\r
+      <Filter>producers\ffmpeg</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="producers\ffmpeg\FFMPEGOutput.h">\r
+      <Filter>producers\ffmpeg</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="producers\ffmpeg\FFMPEGPacket.h">\r
+      <Filter>producers\ffmpeg</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="utils\UnhandledException.h">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="utils\scope_exit.h">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="utils\ObjectPool.h">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="utils\functiontask.hpp">\r
+      <Filter>utils</Filter>\r
+    </ClInclude>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="utils\BitmapHolder.cpp">\r
+      <Filter>utils</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="utils\CPUID.cpp">\r
+      <Filter>utils</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="utils\DCWrapper.cpp">\r
+      <Filter>utils</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="Utils\Event.cpp">\r
+      <Filter>utils</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="Utils\FileExists.cpp">\r
+      <Filter>utils</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="Utils\FileInputStream.cpp">\r
+      <Filter>utils</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="Utils\FileOutputStream.cpp">\r
+      <Filter>utils</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="Utils\FindWrapper.cpp">\r
+      <Filter>utils</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="Utils\ID.cpp">\r
+      <Filter>utils</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="utils\LogException.cpp">\r
+      <Filter>utils</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="Utils\Logger.cpp">\r
+      <Filter>utils</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="utils\LogStream.cpp">\r
+      <Filter>utils</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="utils\Process.cpp">\r
+      <Filter>utils</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="Utils\Semaphore.cpp">\r
+      <Filter>utils</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="Utils\Thread.cpp">\r
+      <Filter>utils</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="Utils\Win32Exception.cpp">\r
+      <Filter>utils</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="Utils\image\Clear.cpp">\r
+      <Filter>utils\image</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="Utils\image\Copy.cpp">\r
+      <Filter>utils\image</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="utils\image\CopyField.cpp">\r
+      <Filter>utils\image</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="utils\image\Image.cpp">\r
+      <Filter>utils\image</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="utils\image\Lerp.cpp">\r
+      <Filter>utils\image</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="utils\image\Over.cpp">\r
+      <Filter>utils\image</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="utils\image\Premultiply.cpp">\r
+      <Filter>utils\image</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="utils\image\Shuffle.cpp">\r
+      <Filter>utils\image</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="IO\AsyncEventServer.cpp">\r
+      <Filter>io</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="IO\SerialPort.cpp">\r
+      <Filter>io</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="IO\SocketInfo.cpp">\r
+      <Filter>io</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="consumers\bluefish\BluefishFrameManager.cpp">\r
+      <Filter>consumers\bluefish</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="consumers\bluefish\BluefishPlaybackStrategy.cpp">\r
+      <Filter>consumers\bluefish</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="consumers\bluefish\BlueFishVideoConsumer.cpp">\r
+      <Filter>consumers\bluefish</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="consumers\GDI\GDIVideoConsumer.cpp">\r
+      <Filter>consumers\gdi</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="Consumers\OGL\OGLVideoConsumer.cpp">\r
+      <Filter>consumers\ogl</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="consumers\Audio\AudioConsumer.cpp">\r
+      <Filter>consumers\audio</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="consumers\decklink\DeckLinkAPI_i.c">\r
+      <Filter>consumers\decklink</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="consumers\decklink\DecklinkVideoConsumer.cpp">\r
+      <Filter>consumers\decklink</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="cg\FlashCGProxy.cpp">\r
+      <Filter>cg</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="Producers\ffmpeg\FFmpegManager.cpp">\r
+      <Filter>producers\ffmpeg</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\flash\CTManager.cpp">\r
+      <Filter>producers\flash</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="Producers\flash\Flash9e_i.c">\r
+      <Filter>producers\flash</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="Producers\flash\FlashAxContainer.cpp">\r
+      <Filter>producers\flash</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="Producers\flash\FlashCommand.cpp">\r
+      <Filter>producers\flash</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="Producers\flash\FlashCommandQueue.cpp">\r
+      <Filter>producers\flash</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\flash\FlashManager.cpp">\r
+      <Filter>producers\flash</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="Producers\flash\FlashProducer.cpp">\r
+      <Filter>producers\flash</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\color\ColorManager.cpp">\r
+      <Filter>producers\color</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\targa\TargaManager.cpp">\r
+      <Filter>producers\targa</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\composites\FrameCompositeProducer.cpp">\r
+      <Filter>producers\composites</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\composites\TransitionProducer.cpp">\r
+      <Filter>producers\composites</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\targascroll\TargaScrollManager.cpp">\r
+      <Filter>producers\targascroll</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\targascroll\TargaScrollProducer.cpp">\r
+      <Filter>producers\targascroll</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="AMCP\AMCPCommandQueue.cpp">\r
+      <Filter>amcp</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="AMCP\AMCPCommandsImpl.cpp">\r
+      <Filter>amcp</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="AMCP\AMCPProtocolStrategy.cpp">\r
+      <Filter>amcp</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="audio\DirectSoundManager.cpp">\r
+      <Filter>consumers\audio</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="frame\BitmapFrame.cpp">\r
+      <Filter>frame</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="frame\BitmapFrameAdapter.cpp">\r
+      <Filter>frame</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="frame\BitmapFrameManager.cpp">\r
+      <Filter>frame</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="frame\BitmapFrameManagerAdapter.cpp">\r
+      <Filter>frame</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="frame\Frame.cpp">\r
+      <Filter>frame</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="frame\FramePlaybackControl.cpp">\r
+      <Filter>frame</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="frame\SystemFrame.cpp">\r
+      <Filter>frame</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="frame\SystemFrameManager.cpp">\r
+      <Filter>frame</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="CLK\CLKCommand.cpp">\r
+      <Filter>CLK</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="CLK\CLKProtocolStrategy.cpp">\r
+      <Filter>CLK</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="CII\CIICommandsImpl.cpp">\r
+      <Filter>cii</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="CII\CIIProtocolStrategy.cpp">\r
+      <Filter>cii</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="Application.cpp" />\r
+    <ClCompile Include="Channel.cpp" />\r
+    <ClCompile Include="Main.cpp" />\r
+    <ClCompile Include="Monitor.cpp" />\r
+    <ClCompile Include="StdAfx.cpp" />\r
+    <ClCompile Include="Window.cpp" />\r
+    <ClCompile Include="frame\buffers\MotionFrameBuffer.cpp">\r
+      <Filter>frame\buffers</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="frame\buffers\StaticFrameBuffer.cpp">\r
+      <Filter>frame\buffers</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\ffmpeg\video\FFMPEGVideoDecoder.cpp">\r
+      <Filter>producers\ffmpeg\video</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\ffmpeg\video\FFMPEGVideoScaler.cpp">\r
+      <Filter>producers\ffmpeg\video</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\ffmpeg\video\FFMPEGVideoDeinterlacer.cpp">\r
+      <Filter>producers\ffmpeg\video</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\ffmpeg\audio\FFMPEGAudioDecoder.cpp">\r
+      <Filter>producers\ffmpeg\audio</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\ffmpeg\FFMPEGFrameOutput.cpp">\r
+      <Filter>producers\ffmpeg</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\ffmpeg\FFMPEGInput.cpp">\r
+      <Filter>producers\ffmpeg</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\ffmpeg\FFMPEGOutput.cpp">\r
+      <Filter>producers\ffmpeg</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\ffmpeg\FFMPEGPacket.cpp">\r
+      <Filter>producers\ffmpeg</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="producers\ffmpeg\FFMPEGProducer.cpp">\r
+      <Filter>producers\ffmpeg</Filter>\r
+    </ClCompile>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <Midl Include="consumers\decklink\DeckLinkAPI.idl">\r
+      <Filter>consumers\decklink</Filter>\r
+    </Midl>\r
+    <Midl Include="consumers\decklink\DeckLinkAPI_v7_1.idl">\r
+      <Filter>consumers\decklink</Filter>\r
+    </Midl>\r
+    <Midl Include="consumers\decklink\DeckLinkAPI_v7_3.idl">\r
+      <Filter>consumers\decklink</Filter>\r
+    </Midl>\r
+    <Midl Include="Producers\flash\Flash9e.IDL">\r
+      <Filter>producers\flash</Filter>\r
+    </Midl>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <CustomBuildStep Include="consumers\bluefish\BluefishException.h">\r
+      <Filter>consumers\bluefish</Filter>\r
+    </CustomBuildStep>\r
+    <CustomBuildStep Include="consumers\bluefish\BluefishFrameManager.h">\r
+      <Filter>consumers\bluefish</Filter>\r
+    </CustomBuildStep>\r
+    <CustomBuildStep Include="consumers\bluefish\BluefishPlaybackStrategy.h">\r
+      <Filter>consumers\bluefish</Filter>\r
+    </CustomBuildStep>\r
+    <CustomBuildStep Include="consumers\bluefish\BlueFishVideoConsumer.h">\r
+      <Filter>consumers\bluefish</Filter>\r
+    </CustomBuildStep>\r
+    <CustomBuildStep Include="PlaybackControl.h" />\r
+  </ItemGroup>\r
+</Project>
\ No newline at end of file
diff --git a/server/StdAfx.cpp b/server/StdAfx.cpp
new file mode 100644 (file)
index 0000000..2bd615b
--- /dev/null
@@ -0,0 +1,28 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+// stdafx.cpp : source file that includes just the standard includes\r
+//     dma.pch will be the pre-compiled header\r
+//     stdafx.obj will contain the pre-compiled type information\r
+\r
+#include "stdafx.h"\r
+\r
+// TODO: reference any additional headers you need in STDAFX.H\r
+// and not in this file\r
diff --git a/server/StdAfx.h b/server/StdAfx.h
new file mode 100644 (file)
index 0000000..3e14200
--- /dev/null
@@ -0,0 +1,79 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+// stdafx.h : include file for standard system include files,\r
+//  or project specific include files that are used frequently, but\r
+//      are changed infrequently\r
+//\r
+\r
+#if !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_)\r
+#define AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_\r
+\r
+#if _MSC_VER > 1000\r
+#pragma once\r
+#endif // _MSC_VER > 1000\r
+\r
+#ifdef _DEBUG\r
+#include <crtdbg.h>\r
+#endif\r
+\r
+#include <winsock2.h>\r
+#include <tchar.h>\r
+#include <sstream>\r
+#include <memory>\r
+\r
+#ifndef TEMPLATEHOST_VERSION\r
+#define TEMPLATEHOST_VERSION 1700\r
+#endif\r
+\r
+\r
+#ifndef _UNICODE\r
+typedef std::ostringstream tstringstream;\r
+typedef std::string tstring;\r
+#else\r
+typedef std::wostringstream tstringstream;\r
+typedef std::wstring tstring;\r
+#endif\r
+\r
+#include <assert.h>\r
+\r
+#include "utils\Logger.h"\r
+#define LOG    caspar::utils::Logger::GetInstance().GetStream(caspar::utils::LogLevel::Release)\r
+\r
+\r
+       #include <atlbase.h>\r
+       #include <atlapp.h>\r
+\r
+       extern WTL::CAppModule _Module;\r
+\r
+       #include <atlcom.h>\r
+       #include <atlhost.h>\r
+\r
+       extern LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);\r
+\r
+namespace caspar\r
+{\r
+       class Application;\r
+       Application* GetApplication();\r
+};\r
+//{{AFX_INSERT_LOCATION}}\r
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.\r
+\r
+#endif // !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_)\r
diff --git a/server/TransitionInfo.h b/server/TransitionInfo.h
new file mode 100644 (file)
index 0000000..ffe4a31
--- /dev/null
@@ -0,0 +1,61 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+\r
+#include <string>\r
+\r
+namespace caspar {\r
+\r
+enum TransitionType\r
+{\r
+       Cut = 1,\r
+       Mix,\r
+       Push,\r
+       Slide,\r
+       Wipe\r
+};\r
+\r
+enum TransitionDirection\r
+{\r
+       FromLeft = 1,\r
+       FromRight,\r
+       FromTop,\r
+       FromBottom\r
+};\r
+\r
+class TransitionInfo\r
+{\r
+public:\r
+       TransitionInfo() : type_(Cut), duration_(0), borderWidth_(0), borderColor_(TEXT("#00000000")), direction_(FromLeft)\r
+       {}\r
+\r
+       ~TransitionInfo()\r
+       {}\r
+\r
+       TransitionType          type_;\r
+       unsigned short          duration_;\r
+       unsigned short          borderWidth_;\r
+       tstring                 borderImage_;\r
+       tstring                 borderColor_;\r
+       TransitionDirection     direction_;\r
+};\r
+\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/VersionNo.h b/server/VersionNo.h
new file mode 100644 (file)
index 0000000..bd13733
--- /dev/null
@@ -0,0 +1,29 @@
+/*-----------------------------------------------------------\r
+  VERSION CONTROL BUILD SYSTEM                               \r
+  This header file was created by VERBUILD v1.0.1            \r
+  -----------------------------------------------------------\r
+  help : verbuild -?                                         \r
+  info : http://www.yeamaec.com                              \r
+         yeamaec@hanafos.com ,krkim@yeamaec.com              \r
+-----------------------------------------------------------*/\r
+\r
+#ifndef VERSIONNO__H\r
+#define VERSIONNO__H\r
+\r
+#define VERSION_FULL           1.8.10082.884\r
+\r
+#define VERSION_BASEYEAR       2000\r
+#define VERSION_DATE           "2010-03-24"\r
+#define VERSION_TIME           "14:59:28"\r
+\r
+#define VERSION_MAJOR          1\r
+#define VERSION_MINOR          8\r
+#define VERSION_BUILDNO        10082\r
+#define VERSION_EXTEND         884\r
+\r
+#define VERSION_FILE           1,8,10082,884\r
+#define VERSION_PRODUCT        1,5,7340,5\r
+#define VERSION_FILESTR        "1,8,10082,884"\r
+#define VERSION_PRODUCTSTR     "1,8,0\0"\r
+\r
+#endif\r
diff --git a/server/VideoConsumer.h b/server/VideoConsumer.h
new file mode 100644 (file)
index 0000000..217e13a
--- /dev/null
@@ -0,0 +1,49 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef __VIDEO_CONSUMER_H__\r
+#define __VIDEO_CONSUMER_H__\r
+\r
+namespace caspar {\r
+\r
+class IPlaybackControl;\r
+class MediaProducer;\r
+\r
+class IVideoConsumer\r
+{\r
+public:\r
+       virtual ~IVideoConsumer() {}\r
+       virtual IPlaybackControl* GetPlaybackControl() const = 0;\r
+       virtual void EnableVideoOutput() = 0;\r
+       virtual void DisableVideoOutput() = 0;\r
+       virtual bool SetupDevice(unsigned int deviceIndex) = 0;\r
+       virtual bool ReleaseDevice() = 0;\r
+       virtual const TCHAR* GetFormatDescription() const = 0;\r
+\r
+       virtual bool SetVideoFormat(const tstring& strDesiredFrameFormat)\r
+       {\r
+               LOG << TEXT("SetVideoFormat is no supported");\r
+               return false; \r
+       }\r
+};\r
+typedef std::tr1::shared_ptr<IVideoConsumer> VideoConsumerPtr;\r
+\r
+}      //namespace caspar\r
+#endif //__VIDEO_CONSUMER_H__
\ No newline at end of file
diff --git a/server/Window.cpp b/server/Window.cpp
new file mode 100644 (file)
index 0000000..d7e1856
--- /dev/null
@@ -0,0 +1,179 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "stdafx.h"\r
+\r
+#include "window.h"\r
+#include "resource.h"\r
+\r
+namespace caspar {\r
+\r
+using namespace utils;\r
+\r
+Window::Window() : _hwnd(NULL), _hinstance(NULL), _hdc(NULL)\r
+{\r
+}\r
+\r
+Window::~Window()\r
+{\r
+       Destroy();\r
+}\r
+\r
+bool Window::Initialize(HINSTANCE hinstance, const TCHAR* windowTitle, const TCHAR* className)\r
+{\r
+       _hinstance = hinstance;\r
+       _classname = className;\r
+\r
+    WNDCLASSEX wndClass;         // Window class\r
+    ZeroMemory(&wndClass, sizeof(wndClass)); // Clear the window class structure\r
+    wndClass.cbSize = sizeof(WNDCLASSEX); \r
+    wndClass.style          = CS_HREDRAW | CS_VREDRAW | CS_CLASSDC;\r
+    wndClass.lpfnWndProc    = (WNDPROC)WndProc;\r
+    wndClass.cbClsExtra     = 0;\r
+    wndClass.cbWndExtra     = 0;\r
+    wndClass.hInstance      = _hinstance;\r
+    wndClass.hIcon          = LoadIcon(_hinstance, MAKEINTRESOURCE(IDI_ICON1));\r
+    wndClass.hCursor        = LoadCursor(NULL, IDC_ARROW);\r
+    wndClass.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);\r
+    wndClass.lpszMenuName   = NULL;//MAKEINTRESOURCE(IDR_MAINMENU);\r
+    wndClass.lpszClassName  = _classname.c_str();\r
+    wndClass.hIconSm        = 0;\r
+\r
+    if (RegisterClassEx(&wndClass) == 0)// Attemp to register the window class\r
+    {\r
+               LOG << TEXT("WINDOW ERROR: Failed to register the window class!") << LogStream::Flush;\r
+        return false;\r
+    }\r
+    DWORD dwStyle;              // Window styles\r
+    DWORD dwExStyle;            // Extended window styles\r
+\r
+    dwStyle = WS_OVERLAPPEDWINDOW |        // Creates an overlapping window\r
+              WS_CLIPCHILDREN |            // Doesn"t draw within child windows\r
+              WS_CLIPSIBLINGS;              // Doesn"t draw within sibling windows\r
+    dwExStyle = WS_EX_APPWINDOW |          // Top level window\r
+                WS_EX_WINDOWEDGE;           // Border with a raised edge\r
+    \r
+    //adjust window size\r
+    RECT rMain;\r
+    rMain.left = 0;\r
+    rMain.right = 720;\r
+    rMain.top = 0;\r
+    rMain.bottom = 576;  \r
+\r
+    AdjustWindowRect(&rMain, dwStyle, 0);\r
+\r
+    // Attempt to create the actual window\r
+    _hwnd = CreateWindowEx( dwExStyle,       // Extended window styles\r
+                            _classname.c_str(),   // Class name\r
+                            windowTitle,       // Window title (caption)\r
+                            dwStyle,         // Window styles\r
+                            0, 0,            // Window position\r
+                            rMain.right - rMain.left,\r
+                            rMain.bottom - rMain.top,   // Size of window\r
+                            0,               // No parent window\r
+                            0,               // No menu\r
+                            _hinstance,      // Instance\r
+                            0);            // Pass nothing to WM_CREATE\r
+\r
+    if(_hwnd == 0) \r
+    {\r
+        Destroy();\r
+        LOG << TEXT("WINDOW ERROR: Unable to create window!") << LogStream::Flush;\r
+        return false;\r
+    }\r
+\r
+    ShowWindow(_hwnd, SW_SHOW);\r
+    SetForegroundWindow(_hwnd);\r
+    SetFocus(_hwnd);\r
+\r
+\r
+       //TEST: select a more appropriate pixelformat\r
+       _hdc = ::GetDC(_hwnd);\r
+\r
+       PIXELFORMATDESCRIPTOR pfd = \r
+       {\r
+               sizeof(PIXELFORMATDESCRIPTOR),          //size of struct\r
+               1,                                                                      //version number\r
+               //PFD_DRAW_TO_WINDOW |                          //Format must support draw to window\r
+               PFD_DRAW_TO_BITMAP |                            //Format must support draw to bitmap\r
+               PFD_DOUBLEBUFFER_DONTCARE |                     //Format does not have to support doublebuffer\r
+               PFD_DEPTH_DONTCARE,                                     //Formet does not have to support depthbuffer\r
+               PFD_TYPE_RGBA,                                          //Request RGBA format\r
+               24,                                                                     //Color depth\r
+               0,0,0,0,0,0,                                            //colorbits ignored\r
+               8,                                                                      //8-bit alpha-buffer\r
+               0,                                                                      //shift bit ignored\r
+               0,                                                                      //no accumulation-buffer\r
+               0,0,0,0,                                                        //Accumulation bits ignored\r
+               0,                                                                      //no depth-buffer\r
+               0,                                                                      //no stencil-buffer\r
+               0,                                                                      //no auxiliary-buffer\r
+               PFD_MAIN_PLANE,                                         //Main drawing layer\r
+               0,                                                                      //RESERVED\r
+               0,0,0                                                           //Layer masks ignored\r
+       };\r
+\r
+       unsigned int nPixelFormat = ChoosePixelFormat(_hdc, &pfd);\r
+       if(nPixelFormat) {\r
+               if(!SetPixelFormat(_hdc, nPixelFormat, &pfd)) {\r
+                       ;\r
+               }\r
+       }\r
+       //END TEST: select a more appropriate pixelformat\r
+/*\r
+       //TEST: give flash access to a directdraw device\r
+       IDirectDrawFactory* pDDF = NULL;\r
+       pDD_ = NULL;\r
+       CComBSTR ddfGUID(_T("{4FD2A832-86C8-11d0-8FCA-00C04FD9189D}"));\r
+       CLSID clsid;\r
+       HRESULT hr = CLSIDFromString((LPOLESTR)ddfGUID, &clsid);\r
+\r
+       hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, GUID_DDFactory, (void **)&pDDF);\r
+       if(pDDF != 0) {\r
+               pDDF->CreateDirectDraw(NULL, _hwnd, DDSCL_NORMAL, NULL, NULL, &pDD_);\r
+               pDDF->Release();\r
+       }\r
+       //END TEST: give flash access to a directdraw device\r
+*/\r
+       return true;\r
+}\r
+\r
+void Window::Destroy()\r
+{\r
+/*     if(pDD_ != 0) {\r
+               pDD_->Release();\r
+               pDD_ = 0;\r
+       }\r
+*/\r
+       // Attempts to destroy the window\r
+       if(_hwnd) {\r
+               DestroyWindow(_hwnd);\r
+               _hwnd = NULL;\r
+       }\r
+\r
+    // Attempts to unregister the window class\r
+    if (!UnregisterClass(_classname.c_str(), _hinstance))\r
+    {\r
+        LOG << TEXT("WINDOW ERROR: Unable to unregister window class!") << LogStream::Flush;\r
+        _hinstance = NULL;\r
+    }\r
+}\r
+\r
+}
\ No newline at end of file
diff --git a/server/Window.h b/server/Window.h
new file mode 100644 (file)
index 0000000..b98cdd1
--- /dev/null
@@ -0,0 +1,61 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+\r
+#pragma once\r
+\r
+#include <string>\r
+#include <memory>\r
+//struct IDirectDraw;\r
+\r
+//extern const GUID GUID_DDFactory;\r
+//extern const GUID GUID_DD3;\r
+\r
+namespace caspar\r
+{\r
+       class Window\r
+       {\r
+       public:\r
+               Window();\r
+               virtual ~Window();\r
+\r
+               bool Initialize(HINSTANCE, const TCHAR* windowTitle, const TCHAR* className);\r
+               void Destroy();\r
+\r
+               HWND getHwnd()\r
+               {\r
+                       return _hwnd;\r
+               }\r
+               HINSTANCE getInstance()\r
+               {\r
+                       return _hinstance;\r
+               }\r
+\r
+//             IDirectDraw* pDD_;\r
+       private:\r
+               HDC                     _hdc;\r
+               HWND            _hwnd;\r
+               HINSTANCE       _hinstance;\r
+               tstring _classname;\r
+       };\r
+\r
+       typedef std::tr1::shared_ptr<Window> WindowPtr;\r
+\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/amcp/AMCPCommand.h b/server/amcp/AMCPCommand.h
new file mode 100644 (file)
index 0000000..3e7cc32
--- /dev/null
@@ -0,0 +1,112 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef __AMCPCOMMAND_H__\r
+#define __AMCPCOMMAND_H__\r
+\r
+#include "..\Channel.h"\r
+#include "..\io\clientinfo.h"\r
+#include <string>\r
+#include <vector>\r
+\r
+namespace caspar {\r
+namespace amcp {\r
+\r
+       enum AMCPCommandCondition {\r
+               ConditionGood = 1,\r
+               ConditionTemporarilyBad,\r
+               ConditionPermanentlyBad\r
+       };\r
+\r
+       enum AMCPCommandScheduling\r
+       {\r
+               Default = 0,\r
+               AddToQueue,\r
+               ImmediatelyAndClear\r
+       };\r
+\r
+       class AMCPCommand\r
+       {\r
+               AMCPCommand(const AMCPCommand&);\r
+               AMCPCommand& operator=(const AMCPCommand&);\r
+       public:\r
+               AMCPCommand();\r
+               virtual ~AMCPCommand() {}\r
+               virtual bool Execute() = 0;\r
+               virtual AMCPCommandCondition CheckConditions() = 0;\r
+\r
+               virtual bool NeedChannel() = 0;\r
+               virtual AMCPCommandScheduling GetDefaultScheduling() = 0;\r
+               virtual int GetMinimumParameters() = 0;\r
+\r
+               void SendReply();\r
+\r
+               void AddParameter(const tstring& param) {\r
+                       _parameters.push_back(param);\r
+               }\r
+               void SetClientInfo(caspar::IO::ClientInfoPtr& s) {\r
+                       pClientInfo_ = s;\r
+               }\r
+               caspar::IO::ClientInfoPtr GetClientInfo() {\r
+                       return pClientInfo_;\r
+               }\r
+               void SetChannel(const ChannelPtr& pChannel) {\r
+                       pChannel_ = pChannel;\r
+               }\r
+               ChannelPtr GetChannel() {\r
+                       return pChannel_;\r
+               }\r
+               void SetChannelIndex(unsigned int channelIndex) {\r
+                       channelIndex_ = channelIndex;\r
+               }\r
+               unsigned int GetChannelIndex() {\r
+                       return channelIndex_;\r
+               }\r
+               virtual void Clear();\r
+\r
+               AMCPCommandScheduling GetScheduling()\r
+               {\r
+                       return scheduling_ == Default ? GetDefaultScheduling() : scheduling_;\r
+               }\r
+               void SetScheduling(AMCPCommandScheduling s)\r
+               {\r
+                       scheduling_ = s;\r
+               }\r
+\r
+       protected:\r
+               void SetReplyString(const tstring& str) {\r
+                       replyString_ = str;\r
+               }\r
+               std::vector<tstring> _parameters;\r
+\r
+       private:\r
+               unsigned int channelIndex_;\r
+               caspar::IO::ClientInfoPtr pClientInfo_;\r
+               ChannelPtr pChannel_;\r
+               AMCPCommandScheduling scheduling_;\r
+               tstring replyString_;\r
+       };\r
+\r
+       typedef std::tr1::shared_ptr<AMCPCommand> AMCPCommandPtr;\r
+\r
+}      //namespace amcp\r
+}      //namespace caspar\r
+\r
+#endif //__AMCPCOMMAND_H__
\ No newline at end of file
diff --git a/server/amcp/AMCPCommandQueue.cpp b/server/amcp/AMCPCommandQueue.cpp
new file mode 100644 (file)
index 0000000..152b06b
--- /dev/null
@@ -0,0 +1,145 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\stdafx.h"\r
+\r
+#include "AMCPCommandQueue.h"\r
+\r
+namespace caspar {\r
+namespace amcp {\r
+\r
+using namespace utils;\r
+\r
+AMCPCommandQueue::AMCPCommandQueue() : newCommandEvent_(FALSE, FALSE) {\r
+}\r
+\r
+AMCPCommandQueue::~AMCPCommandQueue() {\r
+       Stop();\r
+}\r
+\r
+bool AMCPCommandQueue::Start() {\r
+       if(commandPump_.IsRunning())\r
+               return false;\r
+\r
+       return commandPump_.Start(this);\r
+}\r
+\r
+void AMCPCommandQueue::Stop() {\r
+       commandPump_.Stop();\r
+}\r
+\r
+void AMCPCommandQueue::AddCommand(AMCPCommandPtr pNewCommand)\r
+{\r
+       {\r
+               Lock lock(*this);\r
+\r
+               if(pNewCommand->GetScheduling() == ImmediatelyAndClear) {\r
+                       //Clears the queue, objects are deleted automatically\r
+                       commands_.clear();\r
+\r
+                       commands_.push_back(pNewCommand);\r
+                       LOG << LogLevel::Verbose << TEXT("Cleared queue and added command");\r
+               }\r
+               else {\r
+                       commands_.push_back(pNewCommand);\r
+                       LOG << LogLevel::Verbose << TEXT("Added command to end of queue");\r
+               }\r
+       }\r
+\r
+       SetEvent(newCommandEvent_);\r
+}\r
+\r
+void AMCPCommandQueue::Run(HANDLE stopEvent)\r
+{\r
+       bool logTemporarilyBadState = true;\r
+       AMCPCommandPtr pCurrentCommand;\r
+\r
+       LOG << LogLevel::Verbose << TEXT("CommandPump started");\r
+\r
+       while(WaitForSingleObject(stopEvent, 0) != WAIT_OBJECT_0) {\r
+               DWORD waitResult = WaitForSingleObject(newCommandEvent_, 50);\r
+               if(waitResult == WAIT_OBJECT_0) {\r
+                       Lock lock(*this);\r
+\r
+                       if(commands_.size() > 0) {\r
+                               LOG << LogLevel::Debug << TEXT("Found ") << commands_.size() << TEXT(" commands in queue");\r
+\r
+                               AMCPCommandPtr pNextCommand = commands_.front();\r
+\r
+                               if(pCurrentCommand == 0 || pNextCommand->GetScheduling() == ImmediatelyAndClear) {\r
+                                       pCurrentCommand = pNextCommand;\r
+                                       commands_.pop_front();\r
+                               }\r
+                       }\r
+               }\r
+\r
+               if(pCurrentCommand != 0) {\r
+                       AMCPCommandCondition condition = pCurrentCommand->CheckConditions();\r
+                       if(condition == ConditionTemporarilyBad) {\r
+                               if(logTemporarilyBadState) {\r
+                                       LOG << LogLevel::Debug << TEXT("Cound not execute command right now, waiting a sec");\r
+                                       logTemporarilyBadState = false;\r
+                               }\r
+\r
+                               //don't fail, just wait for a while and then try again\r
+                               continue;\r
+                       }\r
+                       else if(condition == ConditionGood) {\r
+                               if(pCurrentCommand->Execute()) {\r
+                                       LOG << LogLevel::Verbose << TEXT("Executed command");\r
+                               }\r
+                               else {\r
+                                       LOG << LogLevel::Verbose << TEXT("Failed to executed command");\r
+                               }               \r
+                       }\r
+                       else {  //condition == ConditionPermanentlyBad\r
+                               LOG << TEXT("Invalid commandobject");\r
+                       }\r
+\r
+                       pCurrentCommand->SendReply();\r
+                       pCurrentCommand.reset();\r
+\r
+                       newCommandEvent_.Set();\r
+                       logTemporarilyBadState = true;\r
+\r
+                       LOG << LogLevel::Debug << TEXT("Ready for a new command");\r
+               }\r
+       }\r
+\r
+       LOG << LogLevel::Verbose << TEXT("CommandPump ended");\r
+}\r
+\r
+bool AMCPCommandQueue::OnUnhandledException(const std::exception& ex) throw() {\r
+       bool bDoRestart = true;\r
+\r
+       try \r
+       {\r
+               LOG << LogLevel::Critical << TEXT("UNHANDLED EXCEPTION in commandqueue. Message: ") << ex.what();\r
+       }\r
+       catch(...)\r
+       {\r
+               bDoRestart = false;\r
+       }\r
+\r
+       return bDoRestart;\r
+}\r
+\r
+}      //namespace amcp\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/amcp/AMCPCommandQueue.h b/server/amcp/AMCPCommandQueue.h
new file mode 100644 (file)
index 0000000..934004d
--- /dev/null
@@ -0,0 +1,62 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _AMCPCOMMANDQUEUE_H__\r
+#define _AMCPCOMMANDQUEUE_H__\r
+\r
+#pragma once\r
+\r
+#include <list>\r
+#include "..\utils\thread.h"\r
+#include "..\utils\Lockable.h"\r
+\r
+#include "AMCPCommand.h"\r
+\r
+namespace caspar {\r
+namespace amcp {\r
+\r
+class AMCPCommandQueue : public utils::IRunnable, private utils::LockableObject\r
+{\r
+       AMCPCommandQueue(const AMCPCommandQueue&);\r
+       AMCPCommandQueue& operator=(const AMCPCommandQueue&);\r
+public:\r
+       AMCPCommandQueue();\r
+       ~AMCPCommandQueue();\r
+\r
+       bool Start();\r
+       void Stop();\r
+       void AddCommand(AMCPCommandPtr pCommand);\r
+\r
+private:\r
+       utils::Thread                           commandPump_;\r
+       virtual void Run(HANDLE stopEvent);\r
+       virtual bool OnUnhandledException(const std::exception& ex) throw();\r
+\r
+       utils::Event newCommandEvent_;\r
+\r
+       //Needs synro-protection\r
+       std::list<AMCPCommandPtr>       commands_;\r
+};\r
+typedef std::tr1::shared_ptr<AMCPCommandQueue> AMCPCommandQueuePtr;\r
+\r
+}      //namespace amcp\r
+}      //namespace caspar\r
+\r
+#endif //_AMCPCOMMANDQUEUE_H__
\ No newline at end of file
diff --git a/server/amcp/AMCPCommandsImpl.cpp b/server/amcp/AMCPCommandsImpl.cpp
new file mode 100644 (file)
index 0000000..63f854e
--- /dev/null
@@ -0,0 +1,1214 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\StdAfx.h"\r
+#include "AMCPCommandsImpl.h"\r
+#include "AMCPProtocolStrategy.h"\r
+#include "..\MediaManager.h"\r
+#include "..\Application.h"\r
+#include "..\channel.h"\r
+#include "..\FileInfo.h"\r
+#include "..\utils\findwrapper.h"\r
+#include "..\utils\fileexists.h"\r
+#include "..\cg\cgcontrol.h"\r
+\r
+#include <algorithm>\r
+#include <locale>\r
+#include <fstream>\r
+#include <cctype>\r
+#include <io.h>\r
+\r
+/* Return codes\r
+\r
+100 [action]                   Information om att nÃ¥got har hänt  \r
+101 [action]                   Information om att nÃ¥got har hänt, en rad data skickas  \r
+\r
+202 [kommando] OK              Kommandot har utförts  \r
+201 [kommando] OK              Kommandot har utförts, och en rad data skickas tillbaka  \r
+200 [kommando] OK              Kommandot har utförts, och flera rader data skickas tillbaka. Avslutas med tomrad  \r
+\r
+400 ERROR                              Kommandot kunde inte förstÃ¥s  \r
+401 [kommando] ERROR   Ogiltig kanal  \r
+402 [kommando] ERROR   Parameter saknas  \r
+403 [kommando] ERROR   Ogiltig parameter  \r
+404 [kommando] ERROR   Mediafilen hittades inte  \r
+\r
+500 FAILED                             Internt serverfel  \r
+501 [kommando] FAILED  Internt serverfel  \r
+502 [kommando] FAILED  Oläslig mediafil  \r
+\r
+600 [kommando] FAILED  funktion ej implementerad\r
+*/\r
+\r
+namespace caspar {\r
+namespace amcp {\r
+\r
+using namespace utils;\r
+\r
+AMCPCommand::AMCPCommand() : channelIndex_(0), scheduling_(Default)\r
+{}\r
+\r
+void AMCPCommand::SendReply() {\r
+       if(pClientInfo_) {\r
+               if(replyString_.length() > 0) {\r
+                       pClientInfo_->Send(replyString_);\r
+               }\r
+       }\r
+}\r
+\r
+void AMCPCommand::Clear() {\r
+       pChannel_.reset();\r
+       pClientInfo_.reset();\r
+       channelIndex_ = 0;\r
+       _parameters.clear();\r
+}\r
+\r
+//////////\r
+// LOAD\r
+AMCPCommandCondition LoadCommand::CheckConditions()\r
+{\r
+       return ConditionGood;\r
+}\r
+\r
+bool LoadCommand::Execute()\r
+{\r
+       if(!GetChannel())\r
+               return false;\r
+       if(_parameters.size() < 1)\r
+               return false;\r
+\r
+       bool bLoop = false;\r
+       FileInfo fileInfo;\r
+       MediaManagerPtr pMediaManager;\r
+       \r
+       tstring fullFilename = _parameters[0];\r
+\r
+       if(_parameters.size()>1)\r
+       {\r
+               transform(_parameters[1].begin(), _parameters[1].end(), _parameters[1].begin(), toupper);\r
+               if(_parameters[1] == TEXT("LOOP"))\r
+                       bLoop = true;\r
+       }\r
+\r
+       if(fullFilename[0] == TEXT('#'))\r
+               pMediaManager = GetApplication()->GetColorMediaManager();\r
+       else\r
+               pMediaManager = GetApplication()->FindMediaFile(GetApplication()->GetMediaFolder()+fullFilename, &fileInfo);\r
+\r
+       for(unsigned int i=0;i<_parameters.size();++i)\r
+               transform(_parameters[i].begin(), _parameters[i].end(), _parameters[i].begin(), toupper);\r
+\r
+       if(pMediaManager != 0)\r
+       {\r
+               if(fileInfo.filetype.length()>0)\r
+               {\r
+                       fullFilename += TEXT(".");\r
+                       fullFilename += fileInfo.filetype;\r
+               }\r
+\r
+               MediaProducerPtr pFP;\r
+               if(fullFilename[0] == TEXT('#'))\r
+                       pFP = pMediaManager->CreateProducer(fullFilename);\r
+               else\r
+                       pFP = pMediaManager->CreateProducer(GetApplication()->GetMediaFolder()+fullFilename);\r
+\r
+               if(GetChannel()->Load(pFP, bLoop))\r
+               {\r
+                       LOG << LogLevel::Verbose << TEXT("Loaded ") <<  fullFilename << TEXT(" successfully");\r
+\r
+                       SetReplyString(TEXT("202 LOAD OK\r\n"));\r
+\r
+                       GetChannel()->GetMonitor().Inform(LOAD, _parameters[0]);\r
+                       return true;\r
+               }\r
+               else\r
+               {\r
+                       LOG << LogLevel::Verbose << TEXT("Failed to load ") << fullFilename << TEXT(". It might be corrupt");\r
+\r
+                       SetReplyString(TEXT("502 LOAD FAILED\r\n"));\r
+                       return false;\r
+               }\r
+       }\r
+       //else\r
+       LOG << LogLevel::Verbose << TEXT("Could not find ") << fullFilename;\r
+\r
+       SetReplyString(TEXT("404 LOAD ERROR\r\n"));\r
+       return false;\r
+\r
+}\r
+\r
+//////////\r
+// LOADBG\r
+AMCPCommandCondition LoadbgCommand::CheckConditions()\r
+{\r
+       return ConditionGood;\r
+}\r
+\r
+bool LoadbgCommand::Execute()\r
+{\r
+       if(!GetChannel())\r
+               return false;\r
+       if(_parameters.size() < 1)\r
+               return false;\r
+\r
+       TransitionInfo transitionInfo;\r
+\r
+       FileInfo fileInfo;\r
+       MediaManagerPtr pMediaManager;\r
+\r
+       tstring fullFilename = _parameters[0];\r
+\r
+       bool bLoop = false;\r
+       unsigned short transitionParameterIndex = 1;\r
+\r
+       if(_parameters.size()>1)\r
+       {\r
+               transform(_parameters[1].begin(), _parameters[1].end(), _parameters[1].begin(), toupper);\r
+               if(_parameters[1] == TEXT("LOOP"))\r
+               {\r
+                       ++transitionParameterIndex;\r
+                       bLoop = true;\r
+               }\r
+       }\r
+\r
+       if(fullFilename[0] == TEXT('#'))\r
+               pMediaManager = GetApplication()->GetColorMediaManager();\r
+       else\r
+               pMediaManager = GetApplication()->FindMediaFile(GetApplication()->GetMediaFolder()+fullFilename, &fileInfo);\r
+\r
+       //Setup transition info\r
+       if(_parameters.size()>transitionParameterIndex) //type\r
+       {\r
+               tstring transitionType = _parameters[transitionParameterIndex];\r
+               transform(transitionType.begin(), transitionType.end(), transitionType.begin(), toupper);\r
+\r
+               if(transitionType == TEXT("CUT"))\r
+                       transitionInfo.type_ = Cut;\r
+               else if(transitionType == TEXT("MIX"))\r
+                       transitionInfo.type_ = Mix;\r
+               else if(transitionType == TEXT("PUSH"))\r
+                       transitionInfo.type_ = Push;\r
+               else if(transitionType == TEXT("SLIDE"))\r
+                       transitionInfo.type_ = Slide;\r
+               else if(transitionType == TEXT("WIPE"))\r
+                       transitionInfo.type_ = Wipe;\r
+\r
+               if(_parameters.size() > static_cast<unsigned short>(transitionParameterIndex+1))        //duration\r
+               {\r
+                       int duration = _ttoi(_parameters[transitionParameterIndex+1].c_str());\r
+                       if(duration > 0)\r
+                               transitionInfo.duration_ = duration;\r
+\r
+                       if(_parameters.size() > static_cast<unsigned short>(transitionParameterIndex+2))        //direction\r
+                       {\r
+                               tstring direction = _parameters[transitionParameterIndex+2];\r
+                               transform(direction.begin(), direction.end(), direction.begin(), toupper);\r
+\r
+                               if(direction == TEXT("FROMLEFT"))\r
+                                       transitionInfo.direction_ = FromLeft;\r
+                               else if(direction == TEXT("FROMRIGHT"))\r
+                                       transitionInfo.direction_ = FromRight;\r
+                               else if(direction == TEXT("LEFT"))\r
+                                       transitionInfo.direction_ = FromRight;\r
+                               else if(direction == TEXT("RIGHT"))\r
+                                       transitionInfo.direction_ = FromLeft;\r
+\r
+                               if(_parameters.size() > static_cast<unsigned short>(transitionParameterIndex+3))        //border\r
+                               {\r
+                                       tstring border = _parameters[transitionParameterIndex+3];\r
+                                       if(border.size()>0)\r
+                                       {\r
+                                               if(border[0] == TEXT('#'))\r
+                                                       transitionInfo.borderColor_ = border;\r
+                                               else\r
+                                                       transitionInfo.borderImage_ = border;\r
+                                       }\r
+\r
+                                       if(_parameters.size() > static_cast<unsigned short>(transitionParameterIndex+4))        //border width\r
+                                       {\r
+                                               transitionInfo.borderWidth_ = _ttoi(_parameters[transitionParameterIndex+4].c_str());\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+\r
+       //Perform loading of the clip\r
+       if(pMediaManager != 0)\r
+       {\r
+               if(fileInfo.filetype.length()>0)\r
+               {\r
+                       fullFilename += TEXT(".");\r
+                       fullFilename += fileInfo.filetype;\r
+               }\r
+\r
+               MediaProducerPtr pFP;\r
+               if(fullFilename[0] == TEXT('#'))\r
+                       pFP = pMediaManager->CreateProducer(fullFilename);\r
+               else\r
+                       pFP = pMediaManager->CreateProducer(GetApplication()->GetMediaFolder()+fullFilename);\r
+\r
+               if(GetChannel()->LoadBackground(pFP, transitionInfo, bLoop))\r
+               {\r
+                       LOG << LogLevel::Verbose << TEXT("Loaded ") << fullFilename << TEXT(" successfully to background");\r
+                       SetReplyString(TEXT("202 LOADBG OK\r\n"));\r
+\r
+                       GetChannel()->GetMonitor().Inform(LOADBG, _parameters[0]);\r
+                       return true;\r
+               }\r
+               else\r
+               {\r
+                       LOG << LogLevel::Verbose << TEXT("Failed to load ") << fullFilename << TEXT(" to background. It might be corrupt");\r
+                       SetReplyString(TEXT("502 LOADBG FAILED\r\n"));\r
+                       return false;\r
+               }\r
+       }\r
+       //else\r
+       LOG << LogLevel::Verbose << TEXT("Could not find ") << fullFilename;\r
+       SetReplyString(TEXT("404 LOADBG ERROR\r\n"));\r
+       return false;\r
+\r
+}\r
+\r
+//////////\r
+// PLAY\r
+AMCPCommandCondition PlayCommand::CheckConditions()\r
+{\r
+       return ConditionGood;\r
+}\r
+\r
+bool PlayCommand::Execute()\r
+{\r
+       if(!GetChannel())\r
+               return false;\r
+\r
+       if(GetChannel()->Play())\r
+       {\r
+               SetReplyString(TEXT("202 PLAY OK\r\n"));\r
+               return true;\r
+       }\r
+\r
+       SetReplyString(TEXT("501 PLAY FAILED\r\n"));\r
+       return false;\r
+}\r
+\r
+//////////\r
+// STOP\r
+AMCPCommandCondition StopCommand::CheckConditions()\r
+{\r
+       return ConditionGood;\r
+}\r
+\r
+bool StopCommand::Execute()\r
+{\r
+       if(!GetChannel())\r
+               return false;\r
+\r
+       if(GetChannel()->Stop())\r
+       {\r
+               SetReplyString(TEXT("202 STOP OK\r\n"));\r
+               return true;\r
+       }\r
+\r
+       SetReplyString(TEXT("501 STOP FAILED\r\n"));\r
+       return false;\r
+}\r
+\r
+//////////\r
+// CLEAR\r
+AMCPCommandCondition ClearCommand::CheckConditions()\r
+{\r
+       return ConditionGood;\r
+}\r
+\r
+bool ClearCommand::Execute()\r
+{\r
+       if(!GetChannel())\r
+               return false;\r
+\r
+       if(GetChannel()->Clear())\r
+       {\r
+               SetReplyString(TEXT("202 CLEAR OK\r\n"));\r
+\r
+               GetChannel()->GetMonitor().Inform(CLEAR);\r
+               return true;\r
+       }\r
+\r
+       SetReplyString(TEXT("501 CLEAR FAILED\r\n"));\r
+       return false;\r
+}\r
+\r
+//////////\r
+// PARAM\r
+AMCPCommandCondition ParamCommand::CheckConditions()\r
+{\r
+       return ConditionGood;\r
+}\r
+\r
+bool ParamCommand::Execute()\r
+{\r
+       if(_parameters.size() < 1)\r
+               return false;\r
+\r
+       if(!GetChannel())\r
+               return false;\r
+\r
+       if(GetChannel()->Param(_parameters[0]))\r
+       {\r
+               SetReplyString(TEXT("202 PARAM OK\r\n"));\r
+               return true;\r
+       }\r
+\r
+       SetReplyString(TEXT("501 PARAM FAILED\r\n"));\r
+       return true;\r
+}\r
+\r
+//////////\r
+// CG\r
+AMCPCommandCondition CGCommand::CheckConditions()\r
+{\r
+       return ConditionGood;\r
+}\r
+\r
+bool CGCommand::Execute()\r
+{\r
+       if(_parameters.size() < 1)\r
+               return false;\r
+       if(!GetChannel())\r
+               return false;\r
+\r
+       tstring command = _parameters[0];\r
+       std::transform(command.begin(), command.end(), command.begin(), toupper);\r
+       if(command == TEXT("ADD"))\r
+               return ExecuteAdd();\r
+       else if(command == TEXT("PLAY"))\r
+               return ExecutePlay();\r
+       else if(command == TEXT("STOP"))\r
+               return ExecuteStop();\r
+       else if(command == TEXT("NEXT"))\r
+               return ExecuteNext();\r
+       else if(command == TEXT("REMOVE"))\r
+               return ExecuteRemove();\r
+       else if(command == TEXT("CLEAR"))\r
+               return ExecuteClear();\r
+       else if(command == TEXT("UPDATE"))\r
+               return ExecuteUpdate();\r
+       else if(command == TEXT("INVOKE"))\r
+               return ExecuteInvoke();\r
+       else if(command == TEXT("INFO"))\r
+               return ExecuteInfo();\r
+\r
+       SetReplyString(TEXT("403 CG ERROR\r\n"));\r
+       return false;\r
+}\r
+\r
+bool CGCommand::ValidateLayer(const tstring& layerstring) {\r
+       int length = layerstring.length();\r
+       for(int i = 0; i < length; ++i) {\r
+               if(!_istdigit(layerstring[i])) {\r
+                       return false;\r
+               }\r
+       }\r
+\r
+       return true;\r
+}\r
+\r
+bool CGCommand::ExecuteAdd() {\r
+       //CG 1 ADD 0 "templatefolder/templatename" [STARTLABEL] 0/1 [DATA]\r
+\r
+       int layer = 0;                          //_parameters[1]\r
+//     tstring templateName;   //_parameters[2]\r
+       tstring label;          //_parameters[3]\r
+       bool bDoStart = false;          //_parameters[3] alt. _parameters[4]\r
+//     tstring data;                   //_parameters[4] alt. _parameters[5]\r
+\r
+       if(_parameters.size() < 4) {\r
+               SetReplyString(TEXT("402 CG ERROR\r\n"));\r
+               return false;\r
+       }\r
+       unsigned int dataIndex = 4;\r
+\r
+       if(!ValidateLayer(_parameters[1])) {\r
+               SetReplyString(TEXT("403 CG ERROR\r\n"));\r
+               return false;\r
+       }\r
+\r
+       layer = _ttoi(_parameters[1].c_str());\r
+\r
+       if(_parameters[3].length() > 1) {       //read label\r
+               label = _parameters[3];\r
+               ++dataIndex;\r
+\r
+               if(_parameters.size() > 4 && _parameters[4].length() > 0)       //read play-on-load-flag\r
+                       bDoStart = (_parameters[4][0]==TEXT('1')) ? true : false;\r
+               else {\r
+                       SetReplyString(TEXT("402 CG ERROR\r\n"));\r
+                       return false;\r
+               }\r
+       }\r
+       else if(_parameters[3].length() > 0) {  //read play-on-load-flag\r
+               bDoStart = (_parameters[3][0]==TEXT('1')) ? true : false;\r
+       }\r
+       else {\r
+               SetReplyString(TEXT("403 CG ERROR\r\n"));\r
+               return false;\r
+       }\r
+\r
+       const TCHAR* pDataString = 0;\r
+       tstringstream data;\r
+       tstring dataFromFile;\r
+       if(_parameters.size() > dataIndex) {    //read data\r
+               const tstring& dataString = _parameters[dataIndex];\r
+\r
+               if(dataString[0] == TEXT('<')) {\r
+                       //the data is an XML-string\r
+                       pDataString = dataString.c_str();\r
+               }\r
+               else {\r
+                       //The data is not an XML-string, it must be a filename\r
+                       tstring filename = GetApplication()->GetDataFolder();\r
+                       filename.append(dataString);\r
+                       filename.append(TEXT(".ftd"));\r
+\r
+                       //open file\r
+                       std::wifstream datafile(filename.c_str());\r
+                       if(datafile) {\r
+                               //read all data\r
+                               data << datafile.rdbuf();\r
+                               datafile.close();\r
+\r
+                               //extract data to _parameters\r
+                               dataFromFile = data.str();\r
+                               pDataString = dataFromFile.c_str();\r
+                       }\r
+               }\r
+       }\r
+\r
+       tstring fullFilename = GetApplication()->GetTemplateFolder() + _parameters[2];\r
+       tstring extension;\r
+       if(GetApplication()->FindTemplate(fullFilename, &extension))\r
+       {\r
+               tstring filename = _parameters[2];\r
+               filename.append(extension);\r
+\r
+               GetChannel()->GetCGControl()->Add(layer, filename, bDoStart, label, (pDataString!=0) ? pDataString : TEXT(""));\r
+               SetReplyString(TEXT("202 CG OK\r\n"));\r
+\r
+               GetChannel()->GetMonitor().Inform(CG_ADD, _parameters[2]);\r
+       }\r
+       else\r
+       {\r
+               LOG << LogLevel::Verbose << TEXT("Could not find template ") << _parameters[2];\r
+               SetReplyString(TEXT("404 CG ERROR\r\n"));\r
+       }\r
+       return true;\r
+}\r
+\r
+bool CGCommand::ExecutePlay() {\r
+       if(_parameters.size() > 1) {\r
+               if(!ValidateLayer(_parameters[1])) {\r
+                       SetReplyString(TEXT("403 CG ERROR\r\n"));\r
+                       return false;\r
+               }\r
+               int layer = _ttoi(_parameters[1].c_str());\r
+               GetChannel()->GetCGControl()->Play(layer);\r
+       }\r
+       else {\r
+               SetReplyString(TEXT("402 CG ERROR\r\n"));\r
+               return true;\r
+       }\r
+\r
+       SetReplyString(TEXT("202 CG OK\r\n"));\r
+       return true;\r
+}\r
+\r
+bool CGCommand::ExecuteStop() {\r
+       if(_parameters.size() > 1) {\r
+               if(!ValidateLayer(_parameters[1])) {\r
+                       SetReplyString(TEXT("403 CG ERROR\r\n"));\r
+                       return false;\r
+               }\r
+               int layer = _ttoi(_parameters[1].c_str());\r
+               GetChannel()->GetCGControl()->Stop(layer, 0);\r
+       }\r
+       else {\r
+               SetReplyString(TEXT("402 CG ERROR\r\n"));\r
+               return true;\r
+       }\r
+\r
+       SetReplyString(TEXT("202 CG OK\r\n"));\r
+       return true;\r
+}\r
+\r
+bool CGCommand::ExecuteNext() {\r
+       if(_parameters.size() > 1) {\r
+               if(!ValidateLayer(_parameters[1])) {\r
+                       SetReplyString(TEXT("403 CG ERROR\r\n"));\r
+                       return false;\r
+               }\r
+               int layer = _ttoi(_parameters[1].c_str());\r
+               GetChannel()->GetCGControl()->Next(layer);\r
+       }\r
+       else {\r
+               SetReplyString(TEXT("402 CG ERROR\r\n"));\r
+               return true;\r
+       }\r
+\r
+       SetReplyString(TEXT("202 CG OK\r\n"));\r
+       return true;\r
+}\r
+\r
+bool CGCommand::ExecuteRemove() {\r
+       if(_parameters.size() > 1) {\r
+               if(!ValidateLayer(_parameters[1])) {\r
+                       SetReplyString(TEXT("403 CG ERROR\r\n"));\r
+                       return false;\r
+               }\r
+               int layer = _ttoi(_parameters[1].c_str());\r
+               GetChannel()->GetCGControl()->Remove(layer);\r
+       }\r
+       else {\r
+               SetReplyString(TEXT("402 CG ERROR\r\n"));\r
+               return true;\r
+       }\r
+\r
+       SetReplyString(TEXT("202 CG OK\r\n"));\r
+       return true;\r
+}\r
+\r
+bool CGCommand::ExecuteClear() {\r
+       GetChannel()->GetCGControl()->Clear();\r
+       SetReplyString(TEXT("202 CG OK\r\n"));\r
+       GetChannel()->GetMonitor().Inform(CG_CLEAR);\r
+       return true;\r
+}\r
+\r
+bool CGCommand::ExecuteUpdate() {\r
+       if(_parameters.size() > 2) {\r
+               if(!ValidateLayer(_parameters[1])) {\r
+                       SetReplyString(TEXT("403 CG ERROR\r\n"));\r
+                       return false;\r
+               }\r
+               int layer = _ttoi(_parameters[1].c_str());\r
+               //TODO: Implement indirect data loading from file. Same as in Add\r
+               GetChannel()->GetCGControl()->Update(layer, _parameters[2]);\r
+       }\r
+       else {\r
+               SetReplyString(TEXT("402 CG ERROR\r\n"));\r
+               return true;\r
+       }\r
+\r
+       SetReplyString(TEXT("202 CG OK\r\n"));\r
+       return true;\r
+}\r
+\r
+bool CGCommand::ExecuteInvoke() {\r
+       if(_parameters.size() > 2) {\r
+               if(!ValidateLayer(_parameters[1])) {\r
+                       SetReplyString(TEXT("403 CG ERROR\r\n"));\r
+                       return false;\r
+               }\r
+               int layer = _ttoi(_parameters[1].c_str());\r
+               GetChannel()->GetCGControl()->Invoke(layer, _parameters[2]);\r
+       }\r
+       else {\r
+               SetReplyString(TEXT("402 CG ERROR\r\n"));\r
+               return true;\r
+       }\r
+\r
+       SetReplyString(TEXT("202 CG OK\r\n"));\r
+       return true;\r
+}\r
+\r
+bool CGCommand::ExecuteInfo() {\r
+//     GetChannel()->GetCGControl()->Info();\r
+       SetReplyString(TEXT("600 CG FAILED\r\n"));\r
+       return true;\r
+}\r
+\r
+//////////\r
+// DATA\r
+AMCPCommandCondition DataCommand::CheckConditions()\r
+{\r
+       return ConditionGood;\r
+}\r
+\r
+bool DataCommand::Execute()\r
+{\r
+       if(_parameters.size() < 1)\r
+               return false;\r
+\r
+       tstring command = _parameters[0];\r
+       std::transform(command.begin(), command.end(), command.begin(), toupper);\r
+       if(command == TEXT("STORE"))\r
+               return ExecuteStore();\r
+       else if(command == TEXT("RETRIEVE"))\r
+               return ExecuteRetrieve();\r
+       else if(command == TEXT("LIST"))\r
+               return ExecuteList();\r
+\r
+       SetReplyString(TEXT("403 DATA ERROR\r\n"));\r
+       return false;\r
+}\r
+\r
+bool DataCommand::ExecuteStore() {\r
+       if(_parameters.size() < 3) {\r
+               SetReplyString(TEXT("402 DATA STORE ERROR\r\n"));\r
+               return false;\r
+       }\r
+\r
+       tstring filename = GetApplication()->GetDataFolder();\r
+       filename.append(_parameters[1]);\r
+       filename.append(TEXT(".ftd"));\r
+\r
+       std::wofstream datafile(filename.c_str());\r
+       if(!datafile) {\r
+               SetReplyString(TEXT("501 DATA STORE FAILED\r\n"));\r
+               return false;\r
+       }\r
+\r
+       datafile << _parameters[2];\r
+       datafile.close();\r
+\r
+       tstring replyString = TEXT("202 DATA STORE OK\r\n");\r
+       SetReplyString(replyString);\r
+       return true;\r
+}\r
+\r
+bool DataCommand::ExecuteRetrieve() {\r
+       if(_parameters.size() < 2) {\r
+               SetReplyString(TEXT("402 DATA RETRIEVE ERROR\r\n"));\r
+               return false;\r
+       }\r
+\r
+       tstring filename = GetApplication()->GetDataFolder();\r
+       filename.append(_parameters[1]);\r
+       filename.append(TEXT(".ftd"));\r
+\r
+       std::wifstream datafile(filename.c_str());\r
+       if(!datafile) {\r
+               SetReplyString(TEXT("404 DATA RETRIEVE ERROR\r\n"));\r
+               return false;\r
+       }\r
+\r
+       tstringstream reply(TEXT("201 DATA RETRIEVE OK\r\n"));\r
+       tstring line;\r
+       bool bFirstLine = true;\r
+       while(std::getline(datafile, line)) {\r
+               if(!bFirstLine)\r
+                       reply << "\\n";\r
+               else\r
+                       bFirstLine = false;\r
+\r
+               reply << line;\r
+       }\r
+       datafile.close();\r
+\r
+       reply << "\r\n";\r
+       SetReplyString(reply.str());\r
+       return true;\r
+}\r
+\r
+bool DataCommand::ExecuteList() {\r
+       tstringstream replyString;\r
+       replyString << TEXT("200 DATA LIST OK\r\n");\r
+\r
+       WIN32_FIND_DATA fileInfo;\r
+       caspar::utils::FindWrapper findWrapper(GetApplication()->GetDataFolder() + TEXT("*.ftd"), &fileInfo);\r
+       if(findWrapper.Success())\r
+       {\r
+               do\r
+               {\r
+                       tstring filename = fileInfo.cFileName;\r
+                       transform(filename.begin(), filename.end(), filename.begin(), toupper);\r
+                       \r
+                       tstring::size_type pos = filename.rfind(TEXT("."));\r
+                       if(pos != tstring::npos)\r
+                       {\r
+                               TCHAR numBuffer[32];\r
+                               TCHAR timeBuffer[32];\r
+                               TCHAR dateBuffer[32];\r
+\r
+                               unsigned __int64 fileSize = fileInfo.nFileSizeHigh;\r
+                               fileSize *= 0x100000000;\r
+                               fileSize += fileInfo.nFileSizeLow;\r
+\r
+                               _ui64tot_s(fileSize, numBuffer, 32, 10);\r
+\r
+                               SYSTEMTIME lastWriteTime;\r
+                               FileTimeToSystemTime(&(fileInfo.ftLastWriteTime), &lastWriteTime);\r
+                               GetDateFormat(LOCALE_USER_DEFAULT, 0, &lastWriteTime, _T("yyyyMMdd"), dateBuffer, sizeof(dateBuffer));\r
+                               GetTimeFormat(LOCALE_USER_DEFAULT, 0, &lastWriteTime, _T("HHmmss"), timeBuffer, sizeof(timeBuffer));\r
+\r
+                               replyString << TEXT("\"") << filename.substr(0, pos) << TEXT("\" ") << numBuffer << TEXT(" ") << dateBuffer << timeBuffer << TEXT("\r\n");\r
+                       }\r
+               }\r
+               while(findWrapper.FindNext(&fileInfo));\r
+       }\r
+       replyString << TEXT("\r\n");\r
+\r
+       SetReplyString(replyString.str());\r
+       return true;\r
+}\r
+\r
+//////////\r
+// CINF\r
+AMCPCommandCondition CinfCommand::CheckConditions()\r
+{\r
+       return ConditionGood;\r
+}\r
+\r
+bool CinfCommand::Execute()\r
+{\r
+       tstringstream replyString;\r
+\r
+       if(_parameters.size() < 1)\r
+               return false;\r
+\r
+       tstring filename = GetApplication()->GetMediaFolder()+_parameters[0];\r
+\r
+       FileInfo fileInfo;\r
+\r
+       MediaManagerPtr pMediaManager = GetApplication()->FindMediaFile(filename, &fileInfo);\r
+       if(pMediaManager != 0 && fileInfo.filetype.length() >0) //File was found\r
+       {\r
+               if(pMediaManager->getFileInfo(&fileInfo))\r
+               {\r
+                       TCHAR numBuffer[32];\r
+                       _ui64tot_s(fileInfo.size, numBuffer, 32, 10);\r
+\r
+                       replyString << TEXT("201 CINF OK\r\n\"") << fileInfo.filename << TEXT("\" ") << fileInfo.type << TEXT("/") << fileInfo.filetype << TEXT("/") << fileInfo.encoding << TEXT(" ") << numBuffer << TEXT("\r\n");\r
+\r
+                       SetReplyString(replyString.str());\r
+                       return true;\r
+               }\r
+       }\r
+\r
+       SetReplyString(TEXT("404 CINF ERROR\r\n"));\r
+       return false;\r
+}\r
+\r
+//////////\r
+// INFO\r
+AMCPCommandCondition InfoCommand::CheckConditions()\r
+{\r
+       return ConditionGood;\r
+}\r
+\r
+bool InfoCommand::Execute()\r
+{\r
+       tstringstream replyString;\r
+\r
+       if(_parameters.size() >= 1)\r
+       {\r
+               int channelIndex = _ttoi(_parameters[0].c_str())-1;\r
+               ChannelPtr pChannel = GetApplication()->GetChannel(static_cast<unsigned int>(channelIndex));\r
+\r
+               if(pChannel != 0)\r
+               {\r
+                       replyString << TEXT("201 INFO OK\r\n");\r
+                       GenerateChannelInfo(pChannel, replyString);\r
+               }\r
+               else\r
+               {\r
+                       SetReplyString(TEXT("401 INFO ERROR\r\n"));\r
+                       return false;\r
+               }\r
+       }\r
+       else\r
+       {\r
+               replyString << TEXT("200 INFO OK\r\n");\r
+\r
+               ChannelPtr pChannel;\r
+               unsigned int channelIndex = 0;\r
+               while((pChannel = GetApplication()->GetChannel(channelIndex++)) != 0)\r
+               {\r
+                       GenerateChannelInfo(pChannel, replyString);\r
+               }\r
+               replyString << TEXT("\r\n");\r
+       }\r
+\r
+       SetReplyString(replyString.str());\r
+       return true;\r
+}\r
+\r
+void InfoCommand::GenerateChannelInfo(ChannelPtr& pChannel, tstringstream& replyString)\r
+{\r
+       replyString << pChannel->GetIndex() << TEXT(" ") << pChannel->GetFormatDescription() << (pChannel->IsPlaybackRunning() ? TEXT(" PLAYING") : TEXT(" STOPPED")) << TEXT("\r\n");\r
+}\r
+\r
+//////////\r
+// CLS\r
+AMCPCommandCondition ClsCommand::CheckConditions()\r
+{\r
+       return ConditionGood;\r
+}\r
+\r
+bool ClsCommand::Execute()\r
+{\r
+       /*\r
+               wav = audio\r
+               mp3 = audio\r
+               swf     = movie\r
+               dv  = movie\r
+               tga = still\r
+               col = still\r
+       */\r
+       tstring cliptype[4] = { _T(" N/A "), _T(" AUDIO "), _T(" MOVIE "), _T(" STILL ") };\r
+\r
+\r
+       tstringstream replyString;\r
+       replyString << TEXT("200 CLS OK\r\n");\r
+\r
+       WIN32_FIND_DATA fileInfo;\r
+       caspar::utils::FindWrapper findWrapper(GetApplication()->GetMediaFolder() + TEXT("*.*"), &fileInfo);\r
+       if(findWrapper.Success())\r
+       {\r
+               unsigned char cliptypeindex = 0;\r
+               bool bGood = false;\r
+\r
+               do\r
+               {\r
+                       tstring filename = fileInfo.cFileName;\r
+\r
+                       transform(filename.begin(), filename.end(), filename.begin(), toupper);\r
+                       \r
+                       tstring::size_type pos = filename.rfind(TEXT("."));\r
+                       if(pos != tstring::npos)\r
+                       {\r
+                               tstring extension = filename.substr(pos+1);\r
+                               if(extension == TEXT("TGA") || extension == TEXT("COL"))\r
+                               {\r
+                                       cliptypeindex = 3;\r
+                                       bGood = true;\r
+                               }\r
+                               else if(extension == TEXT("SWF") || extension == TEXT("CT") || extension == TEXT("DV") || extension == TEXT("MOV") || extension == TEXT("MPG") || extension == TEXT("AVI"))\r
+                               {\r
+                                       cliptypeindex = 2;\r
+                                       bGood = true;\r
+                               }\r
+                               else if(extension == TEXT("WAV") || extension == TEXT("MP3"))\r
+                               {\r
+                                       cliptypeindex = 1;\r
+                                       bGood = true;\r
+                               }\r
+\r
+                               if(bGood)\r
+                               {\r
+                                       TCHAR numBuffer[32];\r
+                                       TCHAR timeBuffer[32];\r
+                                       TCHAR dateBuffer[32];\r
+\r
+                                       unsigned __int64 fileSize = fileInfo.nFileSizeHigh;\r
+                                       fileSize *= 0x100000000;\r
+                                       fileSize += fileInfo.nFileSizeLow;\r
+\r
+                                       _ui64tot_s(fileSize, numBuffer, 32, 10);\r
+\r
+                                       SYSTEMTIME lastWriteTime;\r
+                                       FileTimeToSystemTime(&(fileInfo.ftLastWriteTime), &lastWriteTime);\r
+                                       GetDateFormat(LOCALE_USER_DEFAULT, 0, &lastWriteTime, _T("yyyyMMdd"), dateBuffer, sizeof(dateBuffer));\r
+                                       GetTimeFormat(LOCALE_USER_DEFAULT, 0, &lastWriteTime, _T("HHmmss"), timeBuffer, sizeof(timeBuffer));\r
+\r
+                                       replyString << TEXT("\"") << filename.substr(0, pos) << TEXT("\" ") << cliptype[cliptypeindex] << TEXT(" ") << numBuffer << TEXT(" ") << dateBuffer << timeBuffer << TEXT("\r\n");\r
+\r
+                                       cliptypeindex = 0;\r
+                                       bGood = false;\r
+                               }\r
+                       }\r
+               }\r
+               while(findWrapper.FindNext(&fileInfo));\r
+       }\r
+       replyString << TEXT("\r\n");\r
+\r
+       SetReplyString(replyString.str());\r
+       return true;\r
+}\r
+\r
+//////////\r
+// TLS\r
+AMCPCommandCondition TlsCommand::CheckConditions()\r
+{\r
+       return ConditionGood;\r
+}\r
+\r
+bool TlsCommand::Execute()\r
+{\r
+       tstringstream replyString;\r
+       replyString << TEXT("200 TLS OK\r\n");\r
+\r
+       FindInDirectory(TEXT(""), replyString);\r
+       replyString << TEXT("\r\n");\r
+\r
+       SetReplyString(replyString.str());\r
+       return true;\r
+}\r
+\r
+void TlsCommand::FindInDirectory(const tstring& dir, tstringstream& replyString) {\r
+       {       //Find files in directory\r
+               WIN32_FIND_DATA fileInfo;\r
+               caspar::utils::FindWrapper findWrapper(GetApplication()->GetTemplateFolder() + dir + TEXT("*.ft"), &fileInfo);\r
+               if(findWrapper.Success())\r
+               {\r
+                       do\r
+                       {\r
+                               if(((fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY) && ((fileInfo.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != FILE_ATTRIBUTE_HIDDEN)) {\r
+                                       tstring filename = fileInfo.cFileName;\r
+\r
+                                       transform(filename.begin(), filename.end(), filename.begin(), toupper);\r
+                                       \r
+                                       TCHAR numBuffer[32];\r
+                                       TCHAR timeBuffer[32];\r
+                                       TCHAR dateBuffer[32];\r
+\r
+                                       unsigned __int64 fileSize = fileInfo.nFileSizeHigh;\r
+                                       fileSize *= 0x100000000;\r
+                                       fileSize += fileInfo.nFileSizeLow;\r
+\r
+                                       _ui64tot_s(fileSize, numBuffer, 32, 10);\r
+\r
+                                       SYSTEMTIME lastWriteTime;\r
+                                       FileTimeToSystemTime(&(fileInfo.ftLastWriteTime), &lastWriteTime);\r
+                                       GetDateFormat(LOCALE_USER_DEFAULT, 0, &lastWriteTime, _T("yyyyMMdd"), dateBuffer, sizeof(dateBuffer));\r
+                                       GetTimeFormat(LOCALE_USER_DEFAULT, 0, &lastWriteTime, _T("HHmmss"), timeBuffer, sizeof(timeBuffer));\r
+\r
+                                       replyString << TEXT("\"") << dir << filename.substr(0, filename.size()-3) << TEXT("\" ") << numBuffer << TEXT(" ") << dateBuffer << timeBuffer << TEXT("\r\n");\r
+                               }\r
+                       }\r
+                       while(findWrapper.FindNext(&fileInfo));\r
+               }\r
+       }\r
+\r
+       {       //Find subdirectories in directory\r
+               WIN32_FIND_DATA fileInfo;\r
+               caspar::utils::FindWrapper findWrapper(GetApplication()->GetTemplateFolder() + dir + TEXT("*"), &fileInfo);\r
+               if(findWrapper.Success())\r
+               {\r
+                       do\r
+                       {\r
+                               if((fileInfo.cFileName[0] != TEXT('.')) && ((fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) && ((fileInfo.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != FILE_ATTRIBUTE_HIDDEN)) {\r
+                                       FindInDirectory(dir + fileInfo.cFileName + TEXT('\\'), replyString);\r
+                               }\r
+                       }\r
+                       while(findWrapper.FindNext(&fileInfo));\r
+               }\r
+       }\r
+}\r
+\r
+//////////\r
+// VERSION\r
+AMCPCommandCondition VersionCommand::CheckConditions()\r
+{\r
+       return ConditionGood;\r
+}\r
+\r
+bool VersionCommand::Execute()\r
+{\r
+       tstringstream replyString;\r
+       replyString << TEXT("201 VERSION OK\r\n") << GetApplication()->GetVersionString() << TEXT("\r\n");\r
+\r
+       SetReplyString(replyString.str());\r
+       return true;\r
+}\r
+\r
+//////////\r
+// BYE\r
+AMCPCommandCondition ByeCommand::CheckConditions()\r
+{\r
+       return ConditionGood;\r
+}\r
+\r
+bool ByeCommand::Execute()\r
+{\r
+       GetClientInfo()->Disconnect();\r
+       return true;\r
+}\r
+\r
+\r
+//////////\r
+// SET\r
+\r
+AMCPCommandCondition SetCommand::CheckConditions()\r
+{\r
+       return ConditionGood;\r
+}\r
+\r
+bool SetCommand::Execute()\r
+{\r
+       tstring name = _parameters[0];\r
+       std::transform(name.begin(), name.end(), name.begin(), toupper);\r
+\r
+       tstring value = _parameters[1];\r
+       std::transform(value.begin(), value.end(), value.begin(), toupper);\r
+\r
+       if(name == TEXT("MODE"))\r
+       {\r
+               if(this->GetChannel()->SetVideoFormat(value))\r
+                       this->SetReplyString(TEXT("202 SET MODE OK\r\n"));\r
+               else\r
+                       this->SetReplyString(TEXT("501 SET MODE FAILED\r\n"));\r
+       }\r
+       else\r
+       {\r
+               this->SetReplyString(TEXT("403 SET ERROR\r\n"));\r
+       }\r
+\r
+       return true;\r
+}\r
+\r
+///////////\r
+// MONITOR\r
+AMCPCommandCondition MonitorCommand::CheckConditions()\r
+{\r
+       return ConditionGood;\r
+}\r
+\r
+bool MonitorCommand::Execute()\r
+{\r
+       if(!GetChannel())\r
+               return false;\r
+\r
+       tstring cmd = _parameters[0];\r
+       std::transform(cmd.begin(), cmd.end(), cmd.begin(), toupper);\r
+\r
+       if(cmd == TEXT("START")) {\r
+               GetChannel()->GetMonitor().AddListener(GetClientInfo());\r
+               SetReplyString(TEXT("202 MONITOR START OK\r\n"));\r
+       }\r
+       else if(cmd == TEXT("STOP")) {\r
+               GetChannel()->GetMonitor().RemoveListener(GetClientInfo());\r
+               SetReplyString(TEXT("202 MONITOR STOP OK\r\n"));\r
+       }\r
+       else\r
+               SetReplyString(TEXT("403 MONITOR ERROR\r\n"));\r
+\r
+       return true;\r
+}\r
+\r
+//////////\r
+// KILL\r
+//AMCPCommandCondition KillCommand::CheckConditions()\r
+//{\r
+//     return ConditionGood;\r
+//}\r
+//\r
+//bool KillCommand::Execute()\r
+//{\r
+//     //int* pS = 0;\r
+//     //*pS = 42;\r
+//     caspar::GetApplication()->GetTerminateEvent().Set();\r
+//     return true;\r
+//}\r
+\r
+/*\r
+//////////\r
+// FLS\r
+AMCPCommandCondition FlsCommand::CheckConditions()\r
+{\r
+       return ConditionGood;\r
+}\r
+\r
+bool FlsCommand::Execute()\r
+{\r
+       tstring returnMessage = "200 FLS OK";\r
+       returnMessage += "\r\n";\r
+\r
+       tstring searchPattern = "*.*";\r
+       tstring directory = "";\r
+\r
+       if(_parameters.size() >= 1) {\r
+               tstring::size_type separatorIndex = _parameters[0].find_last_of('\\');\r
+               if(separatorIndex != tstring::npos) {\r
+                       directory = _parameters[0].substr(0, separatorIndex+1);\r
+                       if(_parameters[0].length() > (separatorIndex+1))\r
+                               searchPattern = _parameters[0].substr(separatorIndex+1);\r
+               }\r
+               else\r
+                       searchPattern = _parameters[0];\r
+       }\r
+\r
+       FindFilesInDirectory(directory, searchPattern, returnMessage);\r
+       SetReplyString(returnMessage);\r
+\r
+       return true;\r
+}\r
+\r
+void FlsCommand::FindFilesInDirectory(const tstring& dir, const tstring& pattern, tstring& result)\r
+{\r
+       WIN32_FIND_DATA fileInfo;\r
+\r
+       tstring searchPattern = pattern;\r
+       if(dir.length() > 0) {\r
+               searchPattern = dir + '\\' + pattern;\r
+       }\r
+       HANDLE hFile = FindFirstFile(searchPattern.c_str(), &fileInfo);\r
+       if(hFile != INVALID_HANDLE_VALUE)\r
+       {\r
+               do\r
+               {\r
+                       if((fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) {\r
+                               if(fileInfo.cFileName[0] != '.') {\r
+                                       tstring completeDir = fileInfo.cFileName;\r
+                                       if(dir.length() > 0) {\r
+                                               completeDir = dir + '\\' + completeDir;\r
+                                       }\r
+\r
+                                       FindFilesInDirectory(completeDir, pattern, result);\r
+                               }\r
+                       }\r
+                       else {\r
+                               tstring filename = fileInfo.cFileName;\r
+                               if(dir.length() > 0) {\r
+                                       filename = dir + '\\' + filename;\r
+                               }\r
+\r
+                               transform(filename.begin(), filename.end(), filename.begin(), toupper);\r
+                               \r
+                               char numBuffer[32];\r
+                               TCHAR timeBuffer[32];\r
+                               TCHAR dateBuffer[32];\r
+\r
+                               _itoa_s(fileInfo.nFileSizeLow, numBuffer, sizeof(numBuffer), 10);\r
+\r
+                               SYSTEMTIME lastWriteTime;\r
+                               FileTimeToSystemTime(&(fileInfo.ftLastWriteTime), &lastWriteTime);\r
+                               GetDateFormat(LOCALE_USER_DEFAULT, 0, &lastWriteTime, _T("yyyyMMdd"), dateBuffer, sizeof(dateBuffer));\r
+                               GetTimeFormat(LOCALE_USER_DEFAULT, 0, &lastWriteTime, _T("HHmmss"), timeBuffer, sizeof(timeBuffer));\r
+\r
+                               result += "\"";\r
+                               result += filename;\r
+                               result += "\" ";\r
+\r
+                               result += numBuffer;\r
+                               result += " ";\r
+                               result += dateBuffer;\r
+                               result += timeBuffer;\r
+                               result += "\r\n";\r
+                       }\r
+               }\r
+               while(FindNextFile(hFile, &fileInfo));\r
+       }\r
+       FindClose(hFile);\r
+}\r
+\r
+*/\r
+\r
+}      //namespace amcp\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/amcp/AMCPCommandsImpl.h b/server/amcp/AMCPCommandsImpl.h
new file mode 100644 (file)
index 0000000..85fec8d
--- /dev/null
@@ -0,0 +1,366 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef __AMCPCOMMANDSIMPL_H__\r
+#define __AMCPCOMMANDSIMPL_H__\r
+\r
+#include "AMCPCommand.h"\r
+\r
+namespace caspar {\r
+namespace amcp {\r
+\r
+\r
+class LoadCommand : public AMCPCommand\r
+{\r
+public:\r
+       LoadCommand() {}\r
+       virtual bool Execute();\r
+       virtual AMCPCommandCondition CheckConditions();\r
+       virtual bool NeedChannel() {\r
+               return true;\r
+       }\r
+       virtual AMCPCommandScheduling GetDefaultScheduling() {\r
+               return ImmediatelyAndClear;\r
+       }\r
+       virtual int GetMinimumParameters() {\r
+               return 1;\r
+       }\r
+};\r
+\r
+class LoadbgCommand : public AMCPCommand\r
+{\r
+public:\r
+       LoadbgCommand() {}\r
+       virtual bool Execute();\r
+       virtual AMCPCommandCondition CheckConditions();\r
+\r
+       virtual bool NeedChannel() {\r
+               return true;\r
+       }\r
+       virtual AMCPCommandScheduling GetDefaultScheduling() {\r
+               return AddToQueue;\r
+       }\r
+       virtual int GetMinimumParameters() {\r
+               return 1;\r
+       }\r
+};\r
+\r
+class PlayCommand : public AMCPCommand\r
+{\r
+public:\r
+       PlayCommand() {}\r
+       virtual bool Execute();\r
+       virtual AMCPCommandCondition CheckConditions();\r
+\r
+       virtual bool NeedChannel() {\r
+               return true;\r
+       }\r
+       virtual AMCPCommandScheduling GetDefaultScheduling() {\r
+               return AddToQueue;\r
+       }\r
+       virtual int GetMinimumParameters() {\r
+               return 0;\r
+       }\r
+};\r
+\r
+class StopCommand : public AMCPCommand\r
+{\r
+public:\r
+       StopCommand() {}\r
+       virtual bool Execute();\r
+       virtual AMCPCommandCondition CheckConditions();\r
+\r
+       virtual bool NeedChannel() {\r
+               return true;\r
+       }\r
+       virtual AMCPCommandScheduling GetDefaultScheduling() {\r
+               return ImmediatelyAndClear;\r
+       }\r
+       virtual int GetMinimumParameters() {\r
+               return 0;\r
+       }\r
+};\r
+\r
+class ClearCommand : public AMCPCommand\r
+{\r
+public:\r
+       ClearCommand() {}\r
+       virtual bool Execute();\r
+       virtual AMCPCommandCondition CheckConditions();\r
+\r
+       virtual bool NeedChannel() {\r
+               return true;\r
+       }\r
+       virtual AMCPCommandScheduling GetDefaultScheduling() {\r
+               return ImmediatelyAndClear;\r
+       }\r
+       virtual int GetMinimumParameters() {\r
+               return 0;\r
+       }\r
+};\r
+\r
+class ParamCommand : public AMCPCommand\r
+{\r
+public:\r
+       ParamCommand() {}\r
+       virtual bool Execute();\r
+       virtual AMCPCommandCondition CheckConditions();\r
+\r
+       virtual bool NeedChannel() {\r
+               return true;\r
+       }\r
+       virtual AMCPCommandScheduling GetDefaultScheduling() {\r
+               return AddToQueue;\r
+       }\r
+       virtual int GetMinimumParameters() {\r
+               return 1;\r
+       }\r
+};\r
+\r
+class CGCommand : public AMCPCommand\r
+{\r
+public:\r
+       CGCommand() {}\r
+       virtual bool Execute();\r
+       virtual AMCPCommandCondition CheckConditions();\r
+\r
+       virtual bool NeedChannel() {\r
+               return true;\r
+       }\r
+       virtual AMCPCommandScheduling GetDefaultScheduling() {\r
+               return AddToQueue;\r
+       }\r
+       virtual int GetMinimumParameters() {\r
+               return 1;\r
+       }\r
+\r
+private:\r
+       bool ValidateLayer(const tstring& layerstring);\r
+\r
+       bool ExecuteAdd();\r
+       bool ExecutePlay();\r
+       bool ExecuteStop();\r
+       bool ExecuteNext();\r
+       bool ExecuteRemove();\r
+       bool ExecuteClear();\r
+       bool ExecuteUpdate();\r
+       bool ExecuteInvoke();\r
+       bool ExecuteInfo();\r
+};\r
+\r
+class DataCommand : public AMCPCommand\r
+{\r
+public:\r
+       DataCommand() {}\r
+       virtual bool Execute();\r
+       virtual AMCPCommandCondition CheckConditions();\r
+\r
+       virtual bool NeedChannel() {\r
+               return false;\r
+       }\r
+       virtual AMCPCommandScheduling GetDefaultScheduling() {\r
+               return AddToQueue;\r
+       }\r
+       virtual int GetMinimumParameters() {\r
+               return 1;\r
+       }\r
+\r
+private:\r
+       bool ExecuteStore();\r
+       bool ExecuteRetrieve();\r
+       bool ExecuteList();\r
+};\r
+\r
+class ClsCommand : public AMCPCommand\r
+{\r
+public:\r
+       ClsCommand() {}\r
+       virtual bool Execute();\r
+       virtual AMCPCommandCondition CheckConditions();\r
+\r
+       virtual bool NeedChannel() {\r
+               return false;\r
+       }\r
+       virtual AMCPCommandScheduling GetDefaultScheduling() {\r
+               return AddToQueue;\r
+       }\r
+       virtual int GetMinimumParameters() {\r
+               return 0;\r
+       }\r
+};\r
+\r
+class TlsCommand : public AMCPCommand\r
+{\r
+public:\r
+       TlsCommand() {}\r
+       virtual bool Execute();\r
+       virtual AMCPCommandCondition CheckConditions();\r
+\r
+       virtual bool NeedChannel() {\r
+               return false;\r
+       }\r
+       virtual AMCPCommandScheduling GetDefaultScheduling() {\r
+               return AddToQueue;\r
+       }\r
+       virtual int GetMinimumParameters() {\r
+               return 0;\r
+       }\r
+\r
+private:\r
+       void FindInDirectory(const tstring& dir, tstringstream&);\r
+};\r
+\r
+class CinfCommand : public AMCPCommand\r
+{\r
+public:\r
+       CinfCommand() {}\r
+       virtual bool Execute();\r
+       virtual AMCPCommandCondition CheckConditions();\r
+\r
+       virtual bool NeedChannel() {\r
+               return false;\r
+       }\r
+       virtual AMCPCommandScheduling GetDefaultScheduling() {\r
+               return AddToQueue;\r
+       }\r
+       virtual int GetMinimumParameters() {\r
+               return 1;\r
+       }\r
+};\r
+\r
+class InfoCommand : public AMCPCommand\r
+{\r
+public:\r
+       InfoCommand() {}\r
+       virtual bool Execute();\r
+       virtual AMCPCommandCondition CheckConditions();\r
+\r
+       virtual bool NeedChannel() {\r
+               return false;\r
+       }\r
+       virtual AMCPCommandScheduling GetDefaultScheduling() {\r
+               return AddToQueue;\r
+       }\r
+       virtual int GetMinimumParameters() {\r
+               return 0;\r
+       }\r
+\r
+private:\r
+       void GenerateChannelInfo(ChannelPtr&, tstringstream&);\r
+};\r
+\r
+class VersionCommand : public AMCPCommand\r
+{\r
+public:\r
+       VersionCommand() {}\r
+       virtual bool Execute();\r
+       virtual AMCPCommandCondition CheckConditions();\r
+\r
+       virtual bool NeedChannel() {\r
+               return false;\r
+       }\r
+       virtual AMCPCommandScheduling GetDefaultScheduling() {\r
+               return AddToQueue;\r
+       }\r
+       virtual int GetMinimumParameters() {\r
+               return 0;\r
+       }\r
+};\r
+\r
+class ByeCommand : public AMCPCommand\r
+{\r
+public:\r
+       ByeCommand() {}\r
+       virtual bool Execute();\r
+       virtual AMCPCommandCondition CheckConditions();\r
+\r
+       virtual bool NeedChannel() {\r
+               return false;\r
+       }\r
+       virtual AMCPCommandScheduling GetDefaultScheduling() {\r
+               return AddToQueue;\r
+       }\r
+       virtual int GetMinimumParameters() {\r
+               return 0;\r
+       }\r
+};\r
+\r
+class SetCommand : public AMCPCommand\r
+{\r
+public:\r
+       SetCommand() \r
+       {}\r
+\r
+       virtual bool Execute();\r
+       virtual AMCPCommandCondition CheckConditions();\r
+\r
+       virtual bool NeedChannel() {\r
+               return true;\r
+       }\r
+       virtual AMCPCommandScheduling GetDefaultScheduling() {\r
+               return AddToQueue;\r
+       }\r
+       virtual int GetMinimumParameters() {\r
+               return 2;\r
+       }\r
+};\r
+\r
+class MonitorCommand : public AMCPCommand\r
+{\r
+public:\r
+       MonitorCommand() \r
+       {}\r
+\r
+       virtual bool Execute();\r
+       virtual AMCPCommandCondition CheckConditions();\r
+\r
+       virtual bool NeedChannel() {\r
+               return true;\r
+       }\r
+       virtual AMCPCommandScheduling GetDefaultScheduling() {\r
+               return AddToQueue;\r
+       }\r
+       virtual int GetMinimumParameters() {\r
+               return 1;\r
+       }\r
+};\r
+\r
+//class KillCommand : public AMCPCommand\r
+//{\r
+//public:\r
+//     KillCommand() {}\r
+//     virtual bool Execute();\r
+//     virtual AMCPCommandCondition CheckConditions();\r
+//\r
+//     virtual bool NeedChannel() {\r
+//             return false;\r
+//     }\r
+//     virtual AMCPCommandScheduling GetDefaultScheduling() {\r
+//             return AddToQueue;\r
+//     }\r
+//     virtual int GetMinimumParameters() {\r
+//             return 0;\r
+//     }\r
+//};\r
+\r
+}      //namespace amcp\r
+}      //namespace caspar\r
+\r
+#endif //__AMCPCOMMANDSIMPL_H__
\ No newline at end of file
diff --git a/server/amcp/AMCPProtocolStrategy.cpp b/server/amcp/AMCPProtocolStrategy.cpp
new file mode 100644 (file)
index 0000000..adb9903
--- /dev/null
@@ -0,0 +1,431 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\StdAfx.h"\r
+#include "..\Application.h"\r
+\r
+#include "AMCPProtocolStrategy.h"\r
+\r
+#include "..\io\AsyncEventServer.h"\r
+#include "AMCPCommandsImpl.h"\r
+#include "..\Channel.h"\r
+\r
+#include <stdio.h>\r
+#include <crtdbg.h>\r
+#include <string.h>\r
+#include <algorithm>\r
+#include <cctype>\r
+\r
+namespace caspar {\r
+namespace amcp {\r
+\r
+using namespace utils;\r
+using IO::ClientInfoPtr;\r
+\r
+const tstring AMCPProtocolStrategy::MessageDelimiter = TEXT("\r\n");\r
+\r
+AMCPProtocolStrategy::AMCPProtocolStrategy() {\r
+       AMCPCommandQueuePtr pGeneralCommandQueue(new AMCPCommandQueue());\r
+       if(!pGeneralCommandQueue->Start()) {\r
+               LOG << TEXT("Failed to start the general command-queue");\r
+\r
+               //TODO: THROW!\r
+       }\r
+       else\r
+               commandQueues_.push_back(pGeneralCommandQueue);\r
+\r
+\r
+       ChannelPtr pChannel;\r
+       unsigned int index = -1;\r
+       //Create a commandpump for each channel\r
+       while((pChannel = GetApplication()->GetChannel(++index)) != 0) {\r
+               AMCPCommandQueuePtr pChannelCommandQueue(new AMCPCommandQueue());\r
+               tstring title = TEXT("CHANNEL ");\r
+\r
+               //HACK: Perform real conversion from int to string\r
+               TCHAR num = TEXT('1')+static_cast<TCHAR>(index);\r
+               title += num;\r
+\r
+               if(!pChannelCommandQueue->Start()) {\r
+                       tstring logString = TEXT("Failed to start command-queue for ");\r
+                       logString += title;\r
+                       LOG << logString;\r
+\r
+                       //TODO: THROW!\r
+               }\r
+               else\r
+                       commandQueues_.push_back(pChannelCommandQueue);\r
+       }\r
+}\r
+\r
+AMCPProtocolStrategy::~AMCPProtocolStrategy() {\r
+}\r
+\r
+void AMCPProtocolStrategy::Parse(const TCHAR* pData, int charCount, ClientInfoPtr pClientInfo)\r
+{\r
+       size_t pos;\r
+       tstring recvData(pData, charCount);\r
+       tstring availibleData = pClientInfo->currentMessage_ + recvData;\r
+\r
+       while(true) {\r
+               pos = availibleData.find(MessageDelimiter);\r
+               if(pos != tstring::npos)\r
+               {\r
+                       tstring message = availibleData.substr(0,pos);\r
+\r
+                       //This is where a complete message gets taken care of\r
+                       if(message.length() > 0) {\r
+                               ProcessMessage(message, pClientInfo);\r
+                       }\r
+\r
+                       std::size_t nextStartPos = pos + MessageDelimiter.length();\r
+                       if(nextStartPos < availibleData.length())\r
+                               availibleData = availibleData.substr(nextStartPos);\r
+                       else {\r
+                               availibleData.clear();\r
+                               break;\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       break;\r
+               }\r
+       }\r
+       pClientInfo->currentMessage_ = availibleData;\r
+}\r
+\r
+void AMCPProtocolStrategy::ProcessMessage(const tstring& message, ClientInfoPtr& pClientInfo)\r
+{\r
+       bool bError = true;\r
+       MessageParserState state = New;\r
+\r
+       AMCPCommandPtr pCommand;\r
+\r
+       pCommand = InterpretCommandString(message, &state);\r
+\r
+       if(pCommand != 0) {\r
+               pCommand->SetClientInfo(pClientInfo);   \r
+               if(QueueCommand(pCommand))\r
+                       bError = false;\r
+               else\r
+                       state = GetChannel;\r
+       }\r
+\r
+       if(bError == true) {\r
+               tstringstream answer;\r
+               switch(state)\r
+               {\r
+               case GetCommand:\r
+                       answer << TEXT("400 ERROR\r\n") + message << "\r\n";\r
+                       break;\r
+               case GetChannel:\r
+                       answer << TEXT("401 ERROR\r\n");\r
+                       break;\r
+               case GetParameters:\r
+                       answer << TEXT("402 ERROR\r\n");\r
+                       break;\r
+               default:\r
+                       answer << TEXT("500 FAILED\r\n");\r
+                       break;\r
+               }\r
+               pClientInfo->Send(answer.str());\r
+       }\r
+}\r
+\r
+AMCPCommandPtr AMCPProtocolStrategy::InterpretCommandString(const tstring& message, MessageParserState* pOutState)\r
+{\r
+       std::vector<tstring> tokens;\r
+       unsigned int currentToken = 0;\r
+       tstring commandSwitch;\r
+\r
+       AMCPCommandPtr pCommand;\r
+       MessageParserState state = New;\r
+\r
+       LOG << message;\r
+\r
+       std::size_t tokensInMessage = TokenizeMessage(message, &tokens);\r
+\r
+       //parse the message one token at the time\r
+       while(currentToken < tokensInMessage)\r
+       {\r
+               switch(state)\r
+               {\r
+               case New:\r
+                       if(tokens[currentToken][0] == TEXT('/'))\r
+                               state = GetSwitch;\r
+                       else\r
+                               state = GetCommand;\r
+                       break;\r
+\r
+               case GetSwitch:\r
+                       commandSwitch = tokens[currentToken];\r
+                       state = GetCommand;\r
+                       ++currentToken;\r
+                       break;\r
+\r
+               case GetCommand:\r
+                       pCommand = CommandFactory(tokens[currentToken]);\r
+                       if(pCommand == 0) {\r
+                               goto ParseFinnished;\r
+                       }\r
+                       else\r
+                       {\r
+                               //Set scheduling\r
+                               if(commandSwitch.size() > 0) {\r
+                                       transform(commandSwitch.begin(), commandSwitch.end(), commandSwitch.begin(), toupper);\r
+\r
+                                       if(commandSwitch == TEXT("/APP"))\r
+                                               pCommand->SetScheduling(AddToQueue);\r
+                                       else if(commandSwitch  == TEXT("/IMMF"))\r
+                                               pCommand->SetScheduling(ImmediatelyAndClear);\r
+                               }\r
+\r
+                               if(pCommand->NeedChannel())\r
+                                       state = GetChannel;\r
+                               else\r
+                                       state = GetParameters;\r
+                       }\r
+                       ++currentToken;\r
+                       break;\r
+\r
+               case GetParameters:\r
+                       {\r
+                               _ASSERTE(pCommand != 0);\r
+                               int parameterCount=0;\r
+                               while(currentToken<tokensInMessage)\r
+                               {\r
+                                       pCommand->AddParameter(tokens[currentToken++]);\r
+                                       ++parameterCount;\r
+                               }\r
+                               if(parameterCount < pCommand->GetMinimumParameters()) {\r
+                                       goto ParseFinnished;\r
+                               }\r
+\r
+                               state = Done;\r
+                               break;\r
+                       }\r
+\r
+               case GetChannel:\r
+                       {\r
+//                             assert(pCommand != 0);\r
+\r
+                               int channelIndex = _ttoi(tokens[currentToken].c_str())-1;\r
+\r
+                               ChannelPtr pChannel = GetApplication()->GetChannel(channelIndex);\r
+                               if(pChannel == 0) {\r
+                                       goto ParseFinnished;\r
+                               }\r
+\r
+                               pCommand->SetChannel(pChannel);\r
+                               pCommand->SetChannelIndex(channelIndex);\r
+\r
+                               state = GetParameters;\r
+                               ++currentToken;\r
+                               break;\r
+                       }\r
+\r
+               default:        //Done and unexpected\r
+                       goto ParseFinnished;\r
+               }\r
+       }\r
+\r
+ParseFinnished:\r
+       if(state == GetParameters && pCommand->GetMinimumParameters()==0)\r
+               state = Done;\r
+\r
+       if(state != Done) {\r
+               pCommand.reset();\r
+       }\r
+\r
+       if(pOutState != 0) {\r
+               *pOutState = state;\r
+       }\r
+\r
+       return pCommand;\r
+}\r
+\r
+bool AMCPProtocolStrategy::QueueCommand(AMCPCommandPtr pCommand) {\r
+       if(pCommand->NeedChannel()) {\r
+               unsigned int channelIndex = pCommand->GetChannelIndex() + 1;\r
+               if(commandQueues_.size() > channelIndex) {\r
+                       commandQueues_[channelIndex]->AddCommand(pCommand);\r
+               }\r
+               else\r
+                       return false;\r
+       }\r
+       else {\r
+               commandQueues_[0]->AddCommand(pCommand);\r
+       }\r
+       return true;\r
+}\r
+\r
+AMCPCommandPtr AMCPProtocolStrategy::CommandFactory(const tstring& str)\r
+{\r
+       tstring s = str;\r
+       transform(s.begin(), s.end(), s.begin(), toupper);\r
+\r
+       AMCPCommandPtr result;\r
+\r
+       if(s == TEXT("LOAD"))\r
+       {\r
+               result = AMCPCommandPtr(new LoadCommand());\r
+       }\r
+       else if(s == TEXT("LOADBG"))\r
+       {\r
+               result = AMCPCommandPtr(new LoadbgCommand());\r
+       }\r
+       else if(s == TEXT("PLAY"))\r
+       {\r
+               result = AMCPCommandPtr(new PlayCommand());\r
+       }\r
+       else if(s == TEXT("STOP"))\r
+       {\r
+               result = AMCPCommandPtr(new StopCommand());\r
+       }\r
+       else if(s == TEXT("CLEAR"))\r
+       {\r
+               result = AMCPCommandPtr(new ClearCommand());\r
+       }\r
+       else if(s == TEXT("PARAM"))\r
+       {\r
+               result = AMCPCommandPtr(new ParamCommand());\r
+       }\r
+       else if(s == TEXT("CG"))\r
+       {\r
+               result = AMCPCommandPtr(new CGCommand());\r
+       }\r
+       else if(s == TEXT("DATA"))\r
+       {\r
+               result = AMCPCommandPtr(new DataCommand());\r
+       }\r
+       else if(s == TEXT("CINF"))\r
+       {\r
+               result = AMCPCommandPtr(new CinfCommand());\r
+       }\r
+       else if(s == TEXT("INFO"))\r
+       {\r
+               result = AMCPCommandPtr(new InfoCommand());\r
+       }\r
+       else if(s == TEXT("CLS"))\r
+       {\r
+               result = AMCPCommandPtr(new ClsCommand());\r
+       }\r
+       else if(s == TEXT("TLS"))\r
+       {\r
+               result = AMCPCommandPtr(new TlsCommand());\r
+       }\r
+       else if(s == TEXT("VERSION"))\r
+       {\r
+               result = AMCPCommandPtr(new VersionCommand());\r
+       }\r
+       else if(s == TEXT("BYE"))\r
+       {\r
+               result = AMCPCommandPtr(new ByeCommand());\r
+       }\r
+       else if(s == TEXT("SET"))\r
+       {\r
+               result = AMCPCommandPtr(new SetCommand());\r
+       }\r
+       //else if(s == TEXT("MONITOR"))\r
+       //{\r
+       //      result = AMCPCommandPtr(new MonitorCommand());\r
+       //}\r
+       //else if(s == TEXT("KILL"))\r
+       //{\r
+       //      result = AMCPCommandPtr(new KillCommand());\r
+       //}\r
+       return result;\r
+}\r
+\r
+std::size_t AMCPProtocolStrategy::TokenizeMessage(const tstring& message, std::vector<tstring>* pTokenVector)\r
+{\r
+       //split on whitespace but keep strings within quotationmarks\r
+       //treat \ as the start of an escape-sequence: the following char will indicate what to actually put in the string\r
+\r
+       tstring currentToken;\r
+\r
+       char inQuote = 0;\r
+       bool getSpecialCode = false;\r
+\r
+       for(unsigned int charIndex=0; charIndex<message.size(); ++charIndex)\r
+       {\r
+               if(getSpecialCode)\r
+               {\r
+                       //insert code-handling here\r
+                       switch(message[charIndex])\r
+                       {\r
+                       case TEXT('\\'):\r
+                currentToken += TEXT("\\");\r
+                               break;\r
+                       case TEXT('\"'):\r
+                               currentToken += TEXT("\"");\r
+                               break;\r
+                       case TEXT('n'):\r
+                               currentToken += TEXT("\n");\r
+                               break;\r
+                       default:\r
+                               break;\r
+                       };\r
+                       getSpecialCode = false;\r
+                       continue;\r
+               }\r
+\r
+               if(message[charIndex]==TEXT('\\'))\r
+               {\r
+                       getSpecialCode = true;\r
+                       continue;\r
+               }\r
+\r
+               if(message[charIndex]==' ' && inQuote==false)\r
+               {\r
+                       if(currentToken.size()>0)\r
+                       {\r
+                               pTokenVector->push_back(currentToken);\r
+                               currentToken.clear();\r
+                       }\r
+                       continue;\r
+               }\r
+\r
+               if(message[charIndex]==TEXT('\"'))\r
+               {\r
+                       inQuote ^= 1;\r
+\r
+                       if(currentToken.size()>0)\r
+                       {\r
+                               pTokenVector->push_back(currentToken);\r
+                               currentToken.clear();\r
+                       }\r
+                       continue;\r
+               }\r
+\r
+               currentToken += message[charIndex];\r
+       }\r
+\r
+       if(currentToken.size()>0)\r
+       {\r
+               pTokenVector->push_back(currentToken);\r
+               currentToken.clear();\r
+       }\r
+\r
+       return pTokenVector->size();\r
+}\r
+\r
+}      //namespace amcp\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/amcp/AMCPProtocolStrategy.h b/server/amcp/AMCPProtocolStrategy.h
new file mode 100644 (file)
index 0000000..e13c344
--- /dev/null
@@ -0,0 +1,77 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _AMCPMESSAGEHANDLER_H__\r
+#define _AMCPMESSAGEHANDLER_H__\r
+#pragma once\r
+\r
+#include <string>\r
+#include <vector>\r
+\r
+#include "..\io\protocolstrategy.h"\r
+#include "AMCPCommand.h"\r
+#include "AMCPCommandQueue.h"\r
+\r
+namespace caspar {\r
+namespace amcp {\r
+\r
+\r
+class AMCPProtocolStrategy : public caspar::IO::IProtocolStrategy\r
+{\r
+       enum MessageParserState {\r
+               New = 0,\r
+               GetSwitch,\r
+               GetCommand,\r
+               GetParameters,\r
+               GetChannel,\r
+               Done\r
+       };\r
+\r
+       AMCPProtocolStrategy(const AMCPProtocolStrategy&);\r
+       AMCPProtocolStrategy& operator=(const AMCPProtocolStrategy&);\r
+\r
+public:\r
+       AMCPProtocolStrategy();\r
+       virtual ~AMCPProtocolStrategy();\r
+\r
+       virtual void Parse(const TCHAR* pData, int charCount, caspar::IO::ClientInfoPtr pClientInfo);\r
+       virtual UINT GetCodepage() {\r
+               return CP_UTF8;\r
+       }\r
+\r
+       static AMCPCommandPtr InterpretCommandString(const tstring& str, MessageParserState* pOutState=0);\r
+\r
+private:\r
+       friend class AMCPCommand;\r
+\r
+       void ProcessMessage(const tstring& message, caspar::IO::ClientInfoPtr& pClientInfo);\r
+       static std::size_t TokenizeMessage(const tstring& message, std::vector<tstring>* pTokenVector);\r
+       static AMCPCommandPtr CommandFactory(const tstring& str);\r
+\r
+       bool QueueCommand(AMCPCommandPtr);\r
+\r
+       std::vector<AMCPCommandQueuePtr> commandQueues_;\r
+       static const tstring MessageDelimiter;\r
+};\r
+\r
+}      //namespace amcp\r
+}      //namespace caspar\r
+\r
+#endif //_AMCPMESSAGEHANDLER_H__
\ No newline at end of file
diff --git a/server/audio/AudioManager.h b/server/audio/AudioManager.h
new file mode 100644 (file)
index 0000000..879acaf
--- /dev/null
@@ -0,0 +1,86 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+\r
+#include "..\frame\Frame.h"\r
+\r
+namespace caspar {\r
+\r
+class FrameMediaController;\r
+struct MediaProducerInfo;\r
+\r
+namespace audio {\r
+\r
+class AudioDataChunk \r
+{\r
+public:\r
+       AudioDataChunk(int len) : length_(len), pData_(new char[len])\r
+       {}\r
+\r
+       ~AudioDataChunk() {\r
+               if(pData_ != 0)\r
+                       delete[] pData_;\r
+\r
+               pData_ = 0;\r
+               length_ = 0;\r
+       }\r
+\r
+       char* GetDataPtr() {\r
+               return pData_;\r
+       }\r
+       int GetLength() {\r
+               return length_;\r
+       }\r
+\r
+private:\r
+       char* pData_;\r
+       int length_;\r
+};\r
+typedef std::tr1::shared_ptr<AudioDataChunk> AudioDataChunkPtr;\r
+\r
+class ISoundBufferWorker \r
+{\r
+public:\r
+       virtual ~ISoundBufferWorker()\r
+       {}\r
+\r
+       virtual void Start() = 0;\r
+       virtual void Stop() = 0;\r
+\r
+       virtual bool PushChunk(AudioDataChunkPtr) = 0;\r
+       virtual HANDLE GetWaitHandle() = 0;\r
+};\r
+typedef std::tr1::shared_ptr<ISoundBufferWorker> SoundBufferWorkerPtr;\r
+\r
+class IAudioManager \r
+{\r
+public:\r
+       virtual ~IAudioManager()\r
+       {}\r
+\r
+       virtual bool CueAudio(FrameMediaController*) = 0;\r
+       virtual bool StartAudio(FrameMediaController*) = 0;\r
+       virtual bool StopAudio(FrameMediaController*) = 0;\r
+       virtual bool PushAudioData(FrameMediaController*, FramePtr) = 0;\r
+};\r
+\r
+}      //namespace audio\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/audio/DirectSoundManager.cpp b/server/audio/DirectSoundManager.cpp
new file mode 100644 (file)
index 0000000..09f865f
--- /dev/null
@@ -0,0 +1,488 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\StdAfx.h"\r
+\r
+#include "..\utils\thread.h"\r
+#include "..\utils\lockable.h"\r
+#include <queue>\r
+\r
+#include <mmsystem.h>\r
+#include <dsound.h>\r
+\r
+#include "..\MediaProducerInfo.h"\r
+#include "..\frame\FrameMediaController.h"\r
+#include "DirectSoundManager.h"\r
+\r
+namespace caspar {\r
+namespace directsound {\r
+\r
+using namespace audio;\r
+using namespace utils;\r
+\r
+///////////////////////////////\r
+// DirectSoundBufferWorker\r
+///////////////////////////////\r
+class DirectSoundBufferWorker : public caspar::audio::ISoundBufferWorker, private utils::IRunnable, private utils::LockableObject\r
+{\r
+       friend class DirectSoundManager;\r
+\r
+       DirectSoundBufferWorker(const DirectSoundBufferWorker&);\r
+       DirectSoundBufferWorker& operator=(const DirectSoundBufferWorker&);\r
+\r
+public:\r
+       static const int BufferLengthInFrames;\r
+\r
+       virtual ~DirectSoundBufferWorker();\r
+\r
+       void Start() {\r
+               worker_.Start(this);\r
+       }\r
+       void Stop() {\r
+               worker_.Stop();\r
+       }\r
+\r
+       bool PushChunk(AudioDataChunkPtr);\r
+\r
+       HANDLE GetWaitHandle() {\r
+               return writeEvent_;\r
+       }\r
+\r
+private:\r
+       AudioDataChunkPtr GetNextChunk();\r
+\r
+private:\r
+       explicit DirectSoundBufferWorker(LPDIRECTSOUNDBUFFER8 pDirectSound);\r
+       HRESULT InitSoundBuffer(WORD channels, WORD bits, DWORD samplesPerSec, DWORD fps);\r
+\r
+       virtual void Run(HANDLE stopEvent);\r
+       virtual bool OnUnhandledException(const std::exception&) throw();\r
+       utils::Thread worker_;\r
+\r
+\r
+       void WriteChunkToBuffer(int offset, AudioDataChunkPtr pChunk);\r
+       int IncreaseFrameIndex(int frameIndex) {\r
+               return (frameIndex+1)%BufferLengthInFrames;\r
+       }\r
+\r
+       HANDLE notificationEvents_[2];\r
+\r
+       int bytesPerFrame_;\r
+       bool bIsRunning_;\r
+\r
+       LPDIRECTSOUNDBUFFER8 pSoundBuffer_;\r
+\r
+       std::queue<AudioDataChunkPtr> chunkQueue_;\r
+       utils::Event writeEvent_;\r
+       utils::Event startPlayback_;\r
+\r
+       int soundBufferLoadIndex_;\r
+       int lastPlayIndex_;\r
+};\r
+typedef std::tr1::shared_ptr<DirectSoundBufferWorker> DirectSoundBufferWorkerPtr;\r
+\r
+\r
+///////////////////////////////\r
+//\r
+// DirectSoundManager\r
+//\r
+///////////////////////////////\r
+DirectSoundManager::DirectSoundManager() : pDirectSound_(0)\r
+{\r
+}\r
+\r
+DirectSoundManager::~DirectSoundManager()\r
+{\r
+       Destroy();\r
+}\r
+\r
+bool DirectSoundManager::Initialize(HWND hWnd, DWORD channels, DWORD samplesPerSec, DWORD bitsPerSample) {\r
+#ifndef DISABLE_AUDIO\r
+       HRESULT hr = E_FAIL;\r
+       hr = DirectSoundCreate8(NULL, &pDirectSound_, NULL);\r
+       if(FAILED(hr)) {\r
+               LOG << TEXT("DirectSound: Failed to create device.");\r
+               return false;\r
+       }\r
+\r
+       hr = pDirectSound_->SetCooperativeLevel(hWnd, DSSCL_PRIORITY);\r
+       if(FAILED(hr)) {\r
+               LOG << TEXT("DirectSound: Failed to set CooperativeLevel.");\r
+               return false;\r
+       }\r
+\r
+       hr = SetPrimaryBufferFormat(channels, samplesPerSec, bitsPerSample);\r
+       if(FAILED(hr)) {\r
+               LOG << TEXT("DirectSound: Failed to set Primarybuffer format.");\r
+               return false;\r
+       }\r
+#endif\r
+       return true;\r
+}\r
+\r
+void DirectSoundManager::Destroy() {\r
+       if(pDirectSound_ != 0) {\r
+               pDirectSound_->Release();\r
+               pDirectSound_ = 0;\r
+       }\r
+}\r
+\r
+bool DirectSoundManager::CueAudio(FrameMediaController* pController) \r
+{\r
+       MediaProducerInfo clipInfo;\r
+#ifndef DISABLE_AUDIO\r
+       if(pController->GetProducerInfo(&clipInfo) && clipInfo.HaveAudio) {\r
+               caspar::audio::SoundBufferWorkerPtr pSBW = CreateSoundBufferWorker(clipInfo.AudioChannels, clipInfo.BitsPerAudioSample, clipInfo.AudioSamplesPerSec, 25);\r
+               if(pSBW) {\r
+                       pController->AddSoundBufferWorker(pSBW);\r
+                       return true;\r
+               }\r
+       }\r
+#endif\r
+       return false;\r
+}\r
+\r
+bool DirectSoundManager::StartAudio(FrameMediaController* pController)\r
+{\r
+#ifndef DISABLE_AUDIO\r
+       SoundBufferWorkerList& sbwList = pController->GetSoundBufferWorkers();\r
+       SoundBufferWorkerList::iterator it = sbwList.begin();\r
+       SoundBufferWorkerList::iterator end = sbwList.end();\r
+       for(;it != end; ++it)\r
+       {\r
+               (*it)->Start();\r
+       }\r
+#endif\r
+       return true;\r
+}\r
+\r
+bool DirectSoundManager::StopAudio(FrameMediaController* pController)\r
+{\r
+#ifndef DISABLE_AUDIO\r
+       SoundBufferWorkerList& sbwList = pController->GetSoundBufferWorkers();\r
+       SoundBufferWorkerList::iterator it = sbwList.begin();\r
+       SoundBufferWorkerList::iterator end = sbwList.end();\r
+       for(;it != end; ++it)\r
+       {\r
+               (*it)->Stop();\r
+       }\r
+#endif\r
+       return true;\r
+}\r
+\r
+bool DirectSoundManager::PushAudioData(FrameMediaController* pController, FramePtr pFrame)\r
+{\r
+#ifndef DISABLE_AUDIO\r
+       SoundBufferWorkerList& sbwList = pController->GetSoundBufferWorkers();\r
+       AudioDataChunkList data = pFrame->GetAudioData();\r
+\r
+       SoundBufferWorkerList::iterator it = sbwList.begin();\r
+       SoundBufferWorkerList::iterator end = sbwList.end();\r
+\r
+       for(int dataIndex = 0;it != end && dataIndex < data.size(); ++it, ++dataIndex) {\r
+               if(dataIndex < pFrame->GetAudioData().size())\r
+                       (*it)->PushChunk(pFrame->GetAudioData()[dataIndex]);\r
+               else\r
+                       break;\r
+       }\r
+#endif\r
+       return true;\r
+}\r
+\r
+SoundBufferWorkerPtr DirectSoundManager::CreateSoundBufferWorker(WORD channels, WORD bits, DWORD samplesPerSec, DWORD fps) {\r
+       SoundBufferWorkerPtr result;\r
+\r
+       if(pDirectSound_ != 0) {\r
+               WAVEFORMATEX wfx;\r
+               DSBUFFERDESC bufferDesc;\r
+               LPDIRECTSOUNDBUFFER pSoundBuffer;\r
+               LPDIRECTSOUNDBUFFER8 pSoundBuffer8;\r
+\r
+               HRESULT hr;\r
+\r
+               ZeroMemory(&wfx, sizeof(wfx));\r
+               wfx.cbSize = sizeof(wfx);\r
+               wfx.wFormatTag = WAVE_FORMAT_PCM;\r
+               wfx.nChannels = channels;\r
+               wfx.wBitsPerSample = bits;\r
+               wfx.nSamplesPerSec = samplesPerSec;\r
+               wfx.nBlockAlign = (wfx.nChannels * wfx.wBitsPerSample) / 8;\r
+               wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;\r
+\r
+               int bytesPerFrame = wfx.nAvgBytesPerSec / fps;\r
+\r
+               ZeroMemory(&bufferDesc, sizeof(bufferDesc));\r
+               bufferDesc.dwSize = sizeof(bufferDesc);\r
+               bufferDesc.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLVOLUME;\r
+               bufferDesc.dwBufferBytes = bytesPerFrame * DirectSoundBufferWorker::BufferLengthInFrames;\r
+               bufferDesc.lpwfxFormat = &wfx;\r
+\r
+               hr = pDirectSound_->CreateSoundBuffer(&bufferDesc, &pSoundBuffer, NULL);\r
+               if(SUCCEEDED(hr)) {\r
+                       hr = pSoundBuffer->QueryInterface(IID_IDirectSoundBuffer8, (LPVOID*) &pSoundBuffer8);\r
+                       pSoundBuffer->Release();\r
+                       if(FAILED(hr)) {\r
+                               LOG << TEXT("DirectSound: Failed to create SoundBuffer.");\r
+                               return result;\r
+                       }\r
+               }\r
+               else {\r
+                       LOG << TEXT("DirectSound: Failed to create SoundBuffer.");\r
+                       return result;\r
+               }\r
+\r
+               DirectSoundBufferWorkerPtr pSBW(new DirectSoundBufferWorker(pSoundBuffer8));\r
+               if(FAILED(pSBW->InitSoundBuffer(channels, bits, samplesPerSec, fps))) {\r
+                       LOG << TEXT("DirectSound: Failed to init SoundBuffer.");\r
+                       return result;\r
+               }\r
+               pSBW->Start();\r
+               result = pSBW;\r
+       }\r
+\r
+       return result;\r
+}\r
+\r
+HRESULT DirectSoundManager::SetPrimaryBufferFormat(DWORD dwPrimaryChannels, DWORD dwPrimaryFreq,  DWORD dwPrimaryBitRate)\r
+{\r
+       HRESULT hr;\r
+       LPDIRECTSOUNDBUFFER pDSBPrimary = NULL;\r
+\r
+       if(pDirectSound_ == NULL )\r
+               return CO_E_NOTINITIALIZED;\r
+\r
+       // Get the primary buffer \r
+       DSBUFFERDESC dsbd;\r
+       ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) );\r
+       dsbd.dwSize        = sizeof(DSBUFFERDESC);\r
+       dsbd.dwFlags       = DSBCAPS_PRIMARYBUFFER;\r
+       dsbd.dwBufferBytes = 0;\r
+       dsbd.lpwfxFormat   = NULL;\r
+\r
+       hr = pDirectSound_->CreateSoundBuffer( &dsbd, &pDSBPrimary, NULL );\r
+       if(FAILED(hr))\r
+               return hr;\r
+\r
+       WAVEFORMATEX wfx;\r
+       ZeroMemory( &wfx, sizeof(WAVEFORMATEX) ); \r
+       wfx.wFormatTag          = (WORD) WAVE_FORMAT_PCM; \r
+       wfx.nChannels           = (WORD) dwPrimaryChannels; \r
+       wfx.nSamplesPerSec      = (DWORD) dwPrimaryFreq; \r
+       wfx.wBitsPerSample      = (WORD) dwPrimaryBitRate; \r
+       wfx.nBlockAlign         = (WORD) (wfx.wBitsPerSample / 8 * wfx.nChannels);\r
+       wfx.nAvgBytesPerSec     = (DWORD) (wfx.nSamplesPerSec * wfx.nBlockAlign);\r
+\r
+       hr = pDSBPrimary->SetFormat(&wfx);\r
+       if(FAILED(hr)) {\r
+               pDSBPrimary->Release();\r
+               pDSBPrimary = 0;\r
+               return hr;\r
+       }\r
+\r
+       pDSBPrimary->Release();\r
+       pDSBPrimary = 0;\r
+\r
+       return S_OK;\r
+}\r
+\r
+/////////////////////////////////\r
+//\r
+// DirectSoundBufferWorker Impl\r
+//\r
+/////////////////////////////////\r
+const int DirectSoundBufferWorker::BufferLengthInFrames = 3;\r
+\r
+DirectSoundBufferWorker::DirectSoundBufferWorker(LPDIRECTSOUNDBUFFER8 pSoundBuffer) : writeEvent_(TRUE, TRUE), bytesPerFrame_(0), pSoundBuffer_(pSoundBuffer), bIsRunning_(false), startPlayback_(FALSE, FALSE), soundBufferLoadIndex_(0), lastPlayIndex_(0)\r
+{\r
+       //reserve the first event for the stopEvent\r
+       notificationEvents_[0] = 0;\r
+       notificationEvents_[1] = CreateEvent(NULL, FALSE, FALSE, NULL);\r
+}\r
+\r
+DirectSoundBufferWorker::~DirectSoundBufferWorker(void) {\r
+       Stop();\r
+\r
+       pSoundBuffer_->Release();\r
+       pSoundBuffer_ = 0;\r
+\r
+       CloseHandle(notificationEvents_[1]);\r
+       notificationEvents_[1] = 0;\r
+}\r
+\r
+void DirectSoundBufferWorker::Run(HANDLE stopEvent) {\r
+       bool bQuit = false;\r
+       notificationEvents_[0] = stopEvent;\r
+\r
+       {\r
+               HANDLE waitEvents[2] = {stopEvent, startPlayback_};\r
+               HRESULT waitResult = WAIT_TIMEOUT;\r
+               while(waitResult == WAIT_TIMEOUT || waitResult == WAIT_OBJECT_0)\r
+               {\r
+                       waitResult = WaitForMultipleObjects(2, waitEvents, FALSE, 2500);\r
+                       if(waitResult == WAIT_OBJECT_0)\r
+                               goto workerloop_end;\r
+               }\r
+       }\r
+\r
+       bIsRunning_ = true;\r
+       HRESULT hr = pSoundBuffer_->Play(0, 0, DSBPLAY_LOOPING);\r
+       while(!bQuit) {\r
+               DWORD waitResult = WaitForMultipleObjects(2, notificationEvents_, FALSE, 2500);\r
+               switch(waitResult) {\r
+                       case WAIT_OBJECT_0:     //stopEvent\r
+                               bQuit = true;\r
+                               break;\r
+\r
+                       case WAIT_TIMEOUT:\r
+                               break;\r
+\r
+                       case WAIT_FAILED:\r
+                               bQuit = true;\r
+                               break;\r
+\r
+                       default:\r
+                               {\r
+                                       DWORD currentPlayCursor = 0, currentWriteCursor = 0;\r
+                                       HRESULT hr = pSoundBuffer_->GetCurrentPosition(&currentPlayCursor, &currentWriteCursor);\r
+                                       if(SUCCEEDED(hr)) {\r
+                                               int currentPlayCursorIndex = currentPlayCursor / bytesPerFrame_;\r
+                                               if(currentPlayCursorIndex != lastPlayIndex_) {\r
+                                                       AudioDataChunkPtr pChunk = GetNextChunk();\r
+                                                       int offset = lastPlayIndex_ * bytesPerFrame_;\r
+\r
+                                                       WriteChunkToBuffer(offset, pChunk);\r
+\r
+                                                       lastPlayIndex_ = currentPlayCursorIndex;\r
+                                               }\r
+                                       }\r
+                               }\r
+                               break;\r
+               }\r
+       }\r
+\r
+workerloop_end:\r
+       pSoundBuffer_->Stop();\r
+       bIsRunning_ = false;\r
+}\r
+\r
+bool DirectSoundBufferWorker::OnUnhandledException(const std::exception&) throw() {\r
+       try {\r
+               if(pSoundBuffer_ != 0)\r
+                       pSoundBuffer_->Stop();\r
+\r
+               LOG << TEXT("UNEXPECTED EXCEPTION in SoundBufferWorker.");\r
+       }\r
+       catch(...) \r
+       {}\r
+\r
+       return false;\r
+}\r
+\r
+void DirectSoundBufferWorker::WriteChunkToBuffer(int offset, AudioDataChunkPtr pChunk) {\r
+       void* pPtr;\r
+       DWORD len;\r
+\r
+       HRESULT hr = pSoundBuffer_->Lock(offset, bytesPerFrame_, &pPtr, &len, NULL, NULL, 0); \r
+       if(SUCCEEDED(hr)) {\r
+               if(pChunk != 0) {\r
+                       //len and pChunk-length SHOULD be the same, but better safe than sorry\r
+                       memcpy(pPtr, pChunk->GetDataPtr(), min(len, pChunk->GetLength()));\r
+               }\r
+               else {\r
+                       memset(pPtr, 0, len);\r
+               }\r
+\r
+               pSoundBuffer_->Unlock(pPtr, len, NULL, 0);\r
+       }\r
+}\r
+\r
+bool DirectSoundBufferWorker::PushChunk(AudioDataChunkPtr pChunk) {\r
+       Lock lock(*this);\r
+\r
+       //WaitForSingleObject(writeEvent_, 200);\r
+\r
+       if(!bIsRunning_) {\r
+               if(soundBufferLoadIndex_ < 3) {\r
+                       WriteChunkToBuffer(bytesPerFrame_ * soundBufferLoadIndex_, pChunk);\r
+                       ++soundBufferLoadIndex_;\r
+                       return true;\r
+               }\r
+               else\r
+                       startPlayback_.Set();\r
+       }\r
+\r
+       chunkQueue_.push(pChunk);\r
+\r
+       if(chunkQueue_.size() >= 5)\r
+               writeEvent_.Reset();\r
+\r
+       return true;\r
+}\r
+\r
+AudioDataChunkPtr DirectSoundBufferWorker::GetNextChunk() {\r
+       Lock lock(*this);\r
+       AudioDataChunkPtr pChunk;\r
+\r
+       if(chunkQueue_.size() > 0) {\r
+               pChunk = chunkQueue_.front();\r
+               chunkQueue_.pop();\r
+       }\r
+\r
+       if(chunkQueue_.size() < 5)\r
+               writeEvent_.Set();\r
+\r
+       return pChunk;\r
+}\r
+\r
+HRESULT DirectSoundBufferWorker::InitSoundBuffer(WORD channels, WORD bits, DWORD samplesPerSec, DWORD fps) {\r
+\r
+       bytesPerFrame_ = samplesPerSec * channels * (bits/8) / fps;\r
+       DWORD bufferSize = bytesPerFrame_ * BufferLengthInFrames;\r
+       \r
+       LPDIRECTSOUNDNOTIFY8 pBufferNotify;\r
+       HRESULT hr = pSoundBuffer_->QueryInterface(IID_IDirectSoundNotify8, (LPVOID*) &pBufferNotify);\r
+       if(SUCCEEDED(hr)) {\r
+               DSBPOSITIONNOTIFY pPositionNotifies[BufferLengthInFrames];\r
+\r
+               for(int i=0; i < BufferLengthInFrames; ++i) {\r
+                       pPositionNotifies[i].dwOffset = (i+1)*bytesPerFrame_ - 1;\r
+                       pPositionNotifies[i].hEventNotify = notificationEvents_[1];\r
+               }\r
+\r
+               hr = pBufferNotify->SetNotificationPositions(BufferLengthInFrames, &(pPositionNotifies[0]));\r
+               pBufferNotify->Release();\r
+       }\r
+       else \r
+               return hr;\r
+\r
+       //Init the buffer to silence\r
+       void* pPtr = 0;\r
+       DWORD len = 0;\r
+       hr = pSoundBuffer_->Lock(0, bufferSize, &pPtr, &len, NULL, NULL, 0); \r
+       if(SUCCEEDED(hr) && pPtr != 0) {\r
+               memset(pPtr, 0, len);\r
+               pSoundBuffer_->Unlock(pPtr, len, NULL, 0);\r
+       }\r
+\r
+       return hr;\r
+}\r
+\r
+}      //namespace directsound\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/audio/DirectSoundManager.h b/server/audio/DirectSoundManager.h
new file mode 100644 (file)
index 0000000..f67c1f3
--- /dev/null
@@ -0,0 +1,61 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+\r
+#include "AudioManager.h"\r
+\r
+struct IDirectSound8;\r
+typedef IDirectSound8* LPDIRECTSOUND8;\r
+\r
+namespace caspar {\r
+namespace directsound {\r
+\r
+class DirectSoundManager : public caspar::audio::IAudioManager\r
+{\r
+       DirectSoundManager(const DirectSoundManager&);\r
+       DirectSoundManager& operator=(const DirectSoundManager&);\r
+       DirectSoundManager();\r
+\r
+public:\r
+       static DirectSoundManager* GetInstance() {\r
+               static DirectSoundManager instance;\r
+               return &instance;\r
+       }\r
+\r
+       ~DirectSoundManager();\r
+\r
+       bool Initialize(HWND hWnd, DWORD channels, DWORD samplesPerSec, DWORD bitsPerSample);\r
+       void Destroy();\r
+\r
+       virtual bool CueAudio(FrameMediaController*);\r
+       virtual bool StartAudio(FrameMediaController*);\r
+       virtual bool StopAudio(FrameMediaController*);\r
+       virtual bool PushAudioData(FrameMediaController*, FramePtr);\r
+\r
+private:\r
+       caspar::audio::SoundBufferWorkerPtr CreateSoundBufferWorker(WORD channels, WORD bits, DWORD samplesPerSec, DWORD fps);\r
+       HRESULT SetPrimaryBufferFormat(DWORD dwPrimaryChannels, DWORD dwPrimaryFreq,  DWORD dwPrimaryBitRate);\r
+\r
+       IDirectSound8* pDirectSound_;\r
+};\r
+\r
+}      //namespace directsound\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/cg/CGControl.h b/server/cg/CGControl.h
new file mode 100644 (file)
index 0000000..97ded37
--- /dev/null
@@ -0,0 +1,47 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _CASPAR_CGCONTROL_H__\r
+#define _CASPAR_CGCONTROL_H__\r
+\r
+#pragma once\r
+\r
+namespace caspar {\r
+namespace CG { \r
+\r
+class ICGControl\r
+{\r
+public:\r
+       virtual ~ICGControl() {}\r
+\r
+       virtual void Add(int layer, const tstring& templateName, bool playOnLoad, const tstring& label, const tstring& data) = 0;\r
+       virtual void Remove(int layer) = 0;\r
+       virtual void Clear() = 0;\r
+       virtual void Play(int layer) = 0;\r
+       virtual void Stop(int layer, unsigned int mixOutDuration) = 0;\r
+       virtual void Next(int layer) = 0;\r
+       virtual void Update(int layer, const tstring& data) = 0;\r
+       virtual void Invoke(int layer, const tstring& label) = 0;\r
+};\r
+\r
+}\r
+}\r
+\r
+#endif //_CASPAR_CGCONTROL_H__
\ No newline at end of file
diff --git a/server/cg/FlashCGManager.cpp b/server/cg/FlashCGManager.cpp
new file mode 100644 (file)
index 0000000..9d59c5b
--- /dev/null
@@ -0,0 +1,184 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\StdAfx.h"\r
+\r
+#include "..\Producers\flash\FlashManager.h"\r
+#include "..\Producers\flash\FlashProducer.h"\r
+\r
+#include "..\Application.h"\r
+#include "..\transitioninfo.h"\r
+\r
+#include "FlashCGManager.h"\r
+\r
+namespace caspar {\r
+namespace CG {\r
+\r
+using namespace utils;\r
+\r
+FlashCGManager::FlashCGManager(caspar::Channel* pChannel) : pChannel_(pChannel), pFlashManager_(new caspar::FlashManager()) {\r
+}\r
+\r
+FlashCGManager::~FlashCGManager() {\r
+       if(pFlashManager_ != 0) {\r
+               delete pFlashManager_;\r
+               pFlashManager_ = 0;\r
+       }\r
+}\r
+\r
+void FlashCGManager::DisplayActive() {\r
+/*     if(pChannel_->GetActiveProducer() != activeCGProducer_) {\r
+               LOG << LogLevel::Debug << TEXT("Had to display active cg-producer");\r
+\r
+               caspar::TransitionInfo transition;\r
+               if(pChannel_->LoadBackground(activeCGProducer_, transition)){\r
+                       pChannel_->Play();\r
+               }\r
+               else {\r
+                       LOG << TEXT("Failed to display active cg-producer");\r
+               }\r
+       }*/\r
+}\r
+FlashProducerPtr FlashCGManager::CreateNewProducer()\r
+{\r
+#if TEMPLATEHOST_VERSION < 1700\r
+       return std::tr1::dynamic_pointer_cast<FlashProducer, MediaProducer>(pFlashManager_->CreateProducer(GetApplication()->GetTemplateFolder()+TEXT("CG.fth")));\r
+#else\r
+       return std::tr1::dynamic_pointer_cast<FlashProducer, MediaProducer>(pFlashManager_->CreateProducer(GetApplication()->GetTemplateFolder()+TEXT("CG.fth.17")));\r
+#endif\r
+}\r
+\r
+void FlashCGManager::Add(int layer, const tstring& templateName, unsigned int mixInDuration, bool playOnLoad, const tstring& startFromLabel, const tstring& data) {\r
+       if(activeCGProducer_ == 0 || activeCGProducer_->IsEmpty()) {\r
+               activeCGProducer_ = CreateNewProducer();\r
+               \r
+               LOG << TEXT("Created new flashproducer");\r
+       }\r
+\r
+       if(activeCGProducer_ != 0) {\r
+               tstringstream flashParam;\r
+               flashParam << TEXT("<invoke name=\"Add\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number><string>") << templateName << TEXT("</string><number>") << mixInDuration << TEXT("</number>") << (playOnLoad?TEXT("<true/>"):TEXT("<false/>")) << TEXT("<string>") << startFromLabel << TEXT("</string><string><![CDATA[ ") << data << TEXT(" ]]></string></arguments></invoke>");\r
+               DisplayActive();\r
+               activeCGProducer_->Param(flashParam.str());\r
+               LOG << LogLevel::Debug << TEXT("Invoked add-command");\r
+       }\r
+}\r
+\r
+void FlashCGManager::Remove(int layer) {\r
+       if(activeCGProducer_ != 0) {\r
+               tstringstream flashParam;\r
+#if TEMPLATEHOST_VERSION < 1700\r
+               flashParam << TEXT("<invoke name=\"Delete\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number></arguments></invoke>");\r
+#else\r
+               flashParam << TEXT("<invoke name=\"Delete\" returntype=\"xml\"><arguments><array><property id=\"0\"><number>") << layer << TEXT("</number></property></array></arguments></invoke>");\r
+#endif\r
+               activeCGProducer_->Param(flashParam.str());\r
+               DisplayActive();\r
+       }\r
+}\r
+\r
+void FlashCGManager::Clear() {\r
+       activeCGProducer_ = CreateNewProducer();\r
+       DisplayActive();\r
+}\r
+\r
+void FlashCGManager::Play(int layer) {\r
+       if(activeCGProducer_ != 0) {\r
+               tstringstream flashParam;\r
+#if TEMPLATEHOST_VERSION < 1700\r
+               flashParam << TEXT("<invoke name=\"Play\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number></arguments></invoke>");\r
+#else\r
+               flashParam << TEXT("<invoke name=\"Play\" returntype=\"xml\"><arguments><array><property id=\"0\"><number>") << layer << TEXT("</number></property></array></arguments></invoke>");\r
+#endif\r
+\r
+               activeCGProducer_->Param(flashParam.str());\r
+               LOG << LogLevel::Debug << TEXT("Invoked play-command");\r
+               DisplayActive();\r
+       }\r
+}\r
+\r
+void FlashCGManager::Stop(int layer, unsigned int mixOutDuration) {\r
+       if(activeCGProducer_ != 0) {\r
+               tstringstream flashParam;\r
+#if TEMPLATEHOST_VERSION < 1700\r
+               flashParam << TEXT("<invoke name=\"Stop\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number><number>") << mixOutDuration << TEXT("</number></arguments></invoke>");\r
+#else\r
+               flashParam << TEXT("<invoke name=\"Stop\" returntype=\"xml\"><arguments><array><property id=\"0\"><number>") << layer << TEXT("</number></property></array><number>") << mixOutDuration << TEXT("</number></arguments></invoke>");\r
+#endif\r
+               activeCGProducer_->Param(flashParam.str());\r
+               LOG << LogLevel::Debug << TEXT("Invoked stop-command");\r
+               DisplayActive();\r
+       }\r
+}\r
+\r
+void FlashCGManager::Next(int layer) {\r
+       if(activeCGProducer_ != 0) {\r
+               tstringstream flashParam;\r
+#if TEMPLATEHOST_VERSION < 1700\r
+               flashParam << TEXT("<invoke name=\"Next\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number></arguments></invoke>");\r
+#else\r
+               flashParam << TEXT("<invoke name=\"Next\" returntype=\"xml\"><arguments><array><property id=\"0\"><number>") << layer << TEXT("</number></property></array></arguments></invoke>");\r
+#endif\r
+               activeCGProducer_->Param(flashParam.str());\r
+               DisplayActive();\r
+       }\r
+}\r
+\r
+void FlashCGManager::Goto(int layer, const tstring& label) {\r
+       if(activeCGProducer_ != 0) {\r
+               tstringstream flashParam;\r
+#if TEMPLATEHOST_VERSION < 1700\r
+               flashParam << TEXT("<invoke name=\"GotoLabel\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number><string>") << label << TEXT("</string></arguments></invoke>");\r
+#else\r
+               flashParam << TEXT("<invoke name=\"GotoLabel\" returntype=\"xml\"><arguments><array><property id=\"0\"><number>") << layer << TEXT("</number></property></array><string>") << label << TEXT("</string></arguments></invoke>");\r
+#endif\r
+               activeCGProducer_->Param(flashParam.str());\r
+               DisplayActive();\r
+       }\r
+}\r
+\r
+void FlashCGManager::Update(int layer, const tstring& data) {\r
+       if(activeCGProducer_ != 0) {\r
+               tstringstream flashParam;\r
+#if TEMPLATEHOST_VERSION < 1700\r
+               flashParam << TEXT("<invoke name=\"SetData\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number><string><![CDATA[ ") << data << TEXT(" ]]></string></arguments></invoke>");\r
+#else\r
+               flashParam << TEXT("<invoke name=\"SetData\" returntype=\"xml\"><arguments><array><property id=\"0\"><number>") << layer << TEXT("</number></property></array><string><![CDATA[ ") << data << TEXT(" ]]></string></arguments></invoke>");\r
+#endif\r
+               activeCGProducer_->Param(flashParam.str());\r
+               DisplayActive();\r
+       }\r
+}\r
+\r
+void FlashCGManager::Invoke(int layer, const tstring& methodSpec) {\r
+       if(activeCGProducer_ != 0) {\r
+               tstringstream flashParam;\r
+#if TEMPLATEHOST_VERSION < 1700\r
+               flashParam << TEXT("<invoke name=\"ExecuteMethod\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number><string>") << methodSpec << TEXT("</string></arguments></invoke>");\r
+#else\r
+               flashParam << TEXT("<invoke name=\"ExecuteMethod\" returntype=\"xml\"><arguments><array><property id=\"0\"><number>") << layer << TEXT("</number></property></array><string>") << methodSpec << TEXT("</string></arguments></invoke>");\r
+#endif\r
+               activeCGProducer_->Param(flashParam.str());\r
+               DisplayActive();\r
+       }\r
+}\r
+\r
+}      //namespace CG\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/cg/FlashCGManager.h b/server/cg/FlashCGManager.h
new file mode 100644 (file)
index 0000000..e490861
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+\r
+#include "..\channel.h"\r
+#include "..\MediaManager.h"\r
+#include <string>\r
+#include <list>\r
+\r
+namespace caspar {\r
+       class Channel;\r
+       class FlashManager;\r
+       class FlashProducer;\r
+       typedef std::tr1::shared_ptr<FlashProducer> FlashProducerPtr;\r
+\r
+namespace CG {\r
+\r
+class FlashCGManager\r
+{\r
+public:\r
+       explicit FlashCGManager(caspar::Channel*);\r
+public:\r
+       virtual ~FlashCGManager();\r
+\r
+       void Add(int layer, const tstring& templateName, unsigned int mixInDuration, bool playOnLoad, const tstring& startFromLabel, const tstring& data);\r
+       void Remove(int layer);\r
+       void Clear();\r
+       void Play(int layer);\r
+       void Stop(int layer, unsigned int mixOutDuration);\r
+       void Next(int layer);\r
+       void Goto(int layer, const tstring& label);\r
+       void Update(int layer, const tstring& data);\r
+       void Invoke(int layer, const tstring& methodSpec);\r
+\r
+\r
+private:\r
+       void DisplayActive();\r
+       FlashProducerPtr CreateNewProducer();\r
+\r
+       caspar::Channel* pChannel_;\r
+\r
+       caspar::FlashManager* pFlashManager_;\r
+       FlashProducerPtr activeCGProducer_;\r
+};\r
+\r
+typedef std::tr1::shared_ptr<FlashCGManager> FlashCGManagerPtr;\r
+\r
+}      //namespace CG\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/cg/FlashCGProxy.cpp b/server/cg/FlashCGProxy.cpp
new file mode 100644 (file)
index 0000000..78f5d31
--- /dev/null
@@ -0,0 +1,320 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\StdAfx.h"\r
+\r
+#include "../producers/flash/flashproducer.h"\r
+#include "../application.h"\r
+#include "../utils/fileexists.h"\r
+#include "FlashCGProxy.h"\r
+\r
+namespace caspar {\r
+namespace CG { \r
+\r
+using namespace utils;\r
+\r
+int FlashCGProxy::cgVersion_ = 0;\r
+\r
+class FlashCGProxy16 : public FlashCGProxy\r
+{\r
+public:\r
+       FlashCGProxy16::FlashCGProxy16()\r
+       {\r
+               pFlashProducer_ = FlashProducer::Create(GetApplication()->GetTemplateFolder()+TEXT("CG.fth"));\r
+               if(!pFlashProducer_)\r
+                       throw std::exception("Failed to create flashproducer for templatehost");\r
+       }\r
+\r
+       virtual void Add(int layer, const tstring& templateName, bool playOnLoad, const tstring& label, const tstring& data) {\r
+               tstringstream flashParam;\r
+\r
+               tstring::size_type pos = templateName.find('.');\r
+               tstring filename = (pos != tstring::npos) ? templateName.substr(0, pos) : templateName;\r
+               \r
+               flashParam << TEXT("<invoke name=\"Add\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number><string>") << filename << TEXT("</string><number>0</number>") << (playOnLoad?TEXT("<true/>"):TEXT("<false/>")) << TEXT("<string>") << label << TEXT("</string><string><![CDATA[ ") << data << TEXT(" ]]></string></arguments></invoke>");\r
+               LOG << LogLevel::Debug << TEXT("Invoking add-command");\r
+               pFlashProducer_->Param(flashParam.str());\r
+       }\r
+       virtual void Remove(int layer) {\r
+               tstringstream flashParam;\r
+               flashParam << TEXT("<invoke name=\"Delete\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number></arguments></invoke>");\r
+               LOG << LogLevel::Debug << TEXT("Invoking remove-command");\r
+               pFlashProducer_->Param(flashParam.str());\r
+       }\r
+       virtual void Play(int layer) {\r
+               tstringstream flashParam;\r
+               flashParam << TEXT("<invoke name=\"Play\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number></arguments></invoke>");\r
+               LOG << LogLevel::Debug << TEXT("Invoking play-command");\r
+               pFlashProducer_->Param(flashParam.str());\r
+       }\r
+       virtual void Stop(int layer, unsigned int mixOutDuration) {\r
+               tstringstream flashParam;\r
+               flashParam << TEXT("<invoke name=\"Stop\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number><number>") << mixOutDuration << TEXT("</number></arguments></invoke>");\r
+               LOG << LogLevel::Debug << TEXT("Invoking stop-command");\r
+               pFlashProducer_->Param(flashParam.str());\r
+       }\r
+       virtual void Next(int layer) {\r
+               tstringstream flashParam;\r
+               flashParam << TEXT("<invoke name=\"Next\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number></arguments></invoke>");\r
+               LOG << LogLevel::Debug << TEXT("Invoking next-command");\r
+               pFlashProducer_->Param(flashParam.str());\r
+       }\r
+       virtual void Update(int layer, const tstring& data) {\r
+               tstringstream flashParam;\r
+               flashParam << TEXT("<invoke name=\"SetData\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number><string><![CDATA[ ") << data << TEXT(" ]]></string></arguments></invoke>");\r
+               LOG << LogLevel::Debug << TEXT("Invoking update-command");\r
+               pFlashProducer_->Param(flashParam.str());\r
+       }\r
+       virtual void Invoke(int layer, const tstring& label) {\r
+               tstringstream flashParam;\r
+               flashParam << TEXT("<invoke name=\"ExecuteMethod\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number><string>") << label << TEXT("</string></arguments></invoke>");\r
+               LOG << LogLevel::Debug << TEXT("Invoking invoke-command");\r
+               pFlashProducer_->Param(flashParam.str());\r
+       }\r
+};\r
+\r
+class FlashCGProxy17 : public FlashCGProxy\r
+{\r
+public:\r
+       FlashCGProxy17::FlashCGProxy17()\r
+       {\r
+               pFlashProducer_ = FlashProducer::Create(GetApplication()->GetTemplateFolder()+TEXT("CG.fth.17"));\r
+               if(!pFlashProducer_)\r
+                       throw std::exception("Failed to create flashproducer for templatehost");\r
+       }\r
+\r
+       virtual void Add(int layer, const tstring& templateName, bool playOnLoad, const tstring& label, const tstring& data) {\r
+               tstringstream flashParam;\r
+\r
+               tstring::size_type pos = templateName.find('.');\r
+               tstring filename = (pos != tstring::npos) ? templateName.substr(0, pos) : templateName;\r
+               \r
+               flashParam << TEXT("<invoke name=\"Add\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number><string>") << filename << TEXT("</string>") << (playOnLoad?TEXT("<true/>"):TEXT("<false/>")) << TEXT("<string>") << label << TEXT("</string><string><![CDATA[ ") << data << TEXT(" ]]></string></arguments></invoke>");\r
+               LOG << LogLevel::Debug << TEXT("Invoking add-command");\r
+               pFlashProducer_->Param(flashParam.str());\r
+       }\r
+       virtual void Remove(int layer) {\r
+               tstringstream flashParam;\r
+               flashParam << TEXT("<invoke name=\"Delete\" returntype=\"xml\"><arguments><array><property id=\"0\"><number>") << layer << TEXT("</number></property></array></arguments></invoke>");\r
+               LOG << LogLevel::Debug << TEXT("Invoking remove-command");\r
+               pFlashProducer_->Param(flashParam.str());\r
+       }\r
+       virtual void Play(int layer) {\r
+               tstringstream flashParam;\r
+               flashParam << TEXT("<invoke name=\"Play\" returntype=\"xml\"><arguments><array><property id=\"0\"><number>") << layer << TEXT("</number></property></array></arguments></invoke>");\r
+               LOG << LogLevel::Debug << TEXT("Invoking play-command");\r
+               pFlashProducer_->Param(flashParam.str());\r
+       }\r
+       virtual void Stop(int layer, unsigned int mixOutDuration) {\r
+               tstringstream flashParam;\r
+               flashParam << TEXT("<invoke name=\"Stop\" returntype=\"xml\"><arguments><array><property id=\"0\"><number>") << layer << TEXT("</number></property></array><number>") << mixOutDuration << TEXT("</number></arguments></invoke>");\r
+               LOG << LogLevel::Debug << TEXT("Invoking stop-command");\r
+               pFlashProducer_->Param(flashParam.str());\r
+       }\r
+       virtual void Next(int layer) {\r
+               tstringstream flashParam;\r
+               flashParam << TEXT("<invoke name=\"Next\" returntype=\"xml\"><arguments><array><property id=\"0\"><number>") << layer << TEXT("</number></property></array></arguments></invoke>");\r
+               LOG << LogLevel::Debug << TEXT("Invoking next-command");\r
+               pFlashProducer_->Param(flashParam.str());\r
+       }\r
+       virtual void Update(int layer, const tstring& data) {\r
+               tstringstream flashParam;\r
+               flashParam << TEXT("<invoke name=\"SetData\" returntype=\"xml\"><arguments><array><property id=\"0\"><number>") << layer << TEXT("</number></property></array><string><![CDATA[ ") << data << TEXT(" ]]></string></arguments></invoke>");\r
+               LOG << LogLevel::Debug << TEXT("Invoking update-command");\r
+               pFlashProducer_->Param(flashParam.str());\r
+       }\r
+       virtual void Invoke(int layer, const tstring& label) {\r
+               tstringstream flashParam;\r
+               flashParam << TEXT("<invoke name=\"Invoke\" returntype=\"xml\"><arguments><array><property id=\"0\"><number>") << layer << TEXT("</number></property></array><string>") << label << TEXT("</string></arguments></invoke>");\r
+               LOG << LogLevel::Debug << TEXT("Invoking invoke-command");\r
+               pFlashProducer_->Param(flashParam.str());\r
+       }\r
+};\r
+\r
+class FlashCGProxy18 : public FlashCGProxy17\r
+{\r
+public:\r
+       FlashCGProxy18::FlashCGProxy18(Monitor* pMonitor)\r
+       {\r
+               pFlashProducer_ = FlashProducer::Create(GetApplication()->GetTemplateFolder()+TEXT("CG.fth.18"), pMonitor);\r
+               if(!pFlashProducer_)\r
+                       throw std::exception("Failed to create flashproducer for templatehost");\r
+       }\r
+\r
+       virtual void Add(int layer, const tstring& templateName, bool playOnLoad, const tstring& label, const tstring& data) {\r
+               tstringstream flashParam;\r
+               flashParam << TEXT("<invoke name=\"Add\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number><string>") << templateName << TEXT("</string>") << (playOnLoad?TEXT("<true/>"):TEXT("<false/>")) << TEXT("<string>") << label << TEXT("</string><string><![CDATA[ ") << data << TEXT(" ]]></string></arguments></invoke>");\r
+               LOG << LogLevel::Debug << TEXT("Invoking add-command");\r
+               pFlashProducer_->Param(flashParam.str());\r
+       }\r
+};\r
+\r
+FlashCGProxy::FlashCGProxy()\r
+{}\r
+\r
+FlashCGProxy::~FlashCGProxy()\r
+{}\r
+\r
+FlashCGProxyPtr FlashCGProxy::Create(Monitor* pMonitor)\r
+{\r
+       FlashCGProxyPtr result;\r
+       switch(cgVersion_) {\r
+               case 18:\r
+                       result.reset(new FlashCGProxy18(pMonitor));\r
+                       break;\r
+               case 17:\r
+                       result.reset(new FlashCGProxy17());\r
+                       break;\r
+               case 16:\r
+                       result.reset(new FlashCGProxy16());\r
+                       break;\r
+\r
+               default:\r
+                       break;\r
+       }\r
+\r
+       return result;\r
+}\r
+\r
+void FlashCGProxy::SetCGVersion() {\r
+       if(exists(GetApplication()->GetTemplateFolder()+TEXT("cg.fth.18"))) {\r
+               LOG << TEXT("Running version 1.8 template graphics.");\r
+               cgVersion_ = 18;\r
+       }\r
+       else if(exists(GetApplication()->GetTemplateFolder()+TEXT("cg.fth.17"))) {\r
+               LOG << TEXT("Running version 1.7 template graphics.");\r
+               cgVersion_ = 17;\r
+       }\r
+       else if(exists(GetApplication()->GetTemplateFolder()+TEXT("cg.fth"))) {\r
+               LOG << TEXT("Running version 1.6 template graphics.");\r
+               cgVersion_ = 16;\r
+       }\r
+       else {\r
+               LOG << TEXT("No templatehost found. Template graphics will be disabled");\r
+               cgVersion_ = 0;\r
+       }\r
+}\r
+\r
+bool FlashCGProxy::Initialize(FrameManagerPtr pFrameManager) {\r
+       return pFlashProducer_->Initialize(pFrameManager);\r
+}\r
+\r
+FrameBuffer& FlashCGProxy::GetFrameBuffer() {\r
+       return pFlashProducer_->GetFrameBuffer();\r
+}\r
+\r
+bool FlashCGProxy::IsEmpty() const {\r
+       return pFlashProducer_->IsEmpty();\r
+}\r
+void FlashCGProxy::SetEmptyAlert(EmptyCallback callback) {\r
+       pFlashProducer_->SetEmptyAlert(callback);\r
+}\r
+void FlashCGProxy::Stop() {\r
+       pFlashProducer_->Stop();\r
+}\r
+\r
+void FlashCGProxy::Clear() {\r
+       pFlashProducer_->Stop();\r
+}\r
+\r
+/*\r
+void FlashCGProxy::Add(int layer, const tstring& templateName, bool playOnLoad, const tstring& label, const tstring& data) {\r
+       tstringstream flashParam;\r
+\r
+#if TEMPLATEHOST_VERSION < 1700\r
+       flashParam << TEXT("<invoke name=\"Add\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number><string>") << templateName << TEXT("</string><number>0</number>") << (playOnLoad?TEXT("<true/>"):TEXT("<false/>")) << TEXT("<string>") << label << TEXT("</string><string><![CDATA[ ") << data << TEXT(" ]]></string></arguments></invoke>");\r
+#else\r
+       flashParam << TEXT("<invoke name=\"Add\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number><string>") << templateName << TEXT("</string>") << (playOnLoad?TEXT("<true/>"):TEXT("<false/>")) << TEXT("<string>") << label << TEXT("</string><string><![CDATA[ ") << data << TEXT(" ]]></string></arguments></invoke>");\r
+#endif\r
+\r
+       LOG << LogLevel::Debug << TEXT("Invoking add-command");\r
+       pFlashProducer_->Param(flashParam.str());\r
+}\r
+\r
+void FlashCGProxy::Remove(int layer) {\r
+       tstringstream flashParam;\r
+#if TEMPLATEHOST_VERSION < 1700\r
+       flashParam << TEXT("<invoke name=\"Delete\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number></arguments></invoke>");\r
+#else\r
+       flashParam << TEXT("<invoke name=\"Delete\" returntype=\"xml\"><arguments><array><property id=\"0\"><number>") << layer << TEXT("</number></property></array></arguments></invoke>");\r
+#endif\r
+       LOG << LogLevel::Debug << TEXT("Invoking remove-command");\r
+       pFlashProducer_->Param(flashParam.str());\r
+}\r
+\r
+\r
+void FlashCGProxy::Play(int layer) {\r
+       tstringstream flashParam;\r
+#if TEMPLATEHOST_VERSION < 1700\r
+       flashParam << TEXT("<invoke name=\"Play\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number></arguments></invoke>");\r
+#else\r
+       flashParam << TEXT("<invoke name=\"Play\" returntype=\"xml\"><arguments><array><property id=\"0\"><number>") << layer << TEXT("</number></property></array></arguments></invoke>");\r
+#endif\r
+\r
+       LOG << LogLevel::Debug << TEXT("Invoking play-command");\r
+       pFlashProducer_->Param(flashParam.str());\r
+}\r
+\r
+void FlashCGProxy::Stop(int layer, unsigned int mixOutDuration) {\r
+       tstringstream flashParam;\r
+#if TEMPLATEHOST_VERSION < 1700\r
+       flashParam << TEXT("<invoke name=\"Stop\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number><number>") << mixOutDuration << TEXT("</number></arguments></invoke>");\r
+#else\r
+       flashParam << TEXT("<invoke name=\"Stop\" returntype=\"xml\"><arguments><array><property id=\"0\"><number>") << layer << TEXT("</number></property></array><number>") << mixOutDuration << TEXT("</number></arguments></invoke>");\r
+#endif\r
+       LOG << LogLevel::Debug << TEXT("Invoking stop-command");\r
+       pFlashProducer_->Param(flashParam.str());\r
+}\r
+\r
+void FlashCGProxy::Next(int layer) {\r
+       tstringstream flashParam;\r
+#if TEMPLATEHOST_VERSION < 1700\r
+       flashParam << TEXT("<invoke name=\"Next\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number></arguments></invoke>");\r
+#else\r
+       flashParam << TEXT("<invoke name=\"Next\" returntype=\"xml\"><arguments><array><property id=\"0\"><number>") << layer << TEXT("</number></property></array></arguments></invoke>");\r
+#endif\r
+       LOG << LogLevel::Debug << TEXT("Invoking next-command");\r
+       pFlashProducer_->Param(flashParam.str());\r
+}\r
+\r
+void FlashCGProxy::Update(int layer, const tstring& data) {\r
+       tstringstream flashParam;\r
+#if TEMPLATEHOST_VERSION < 1700\r
+       flashParam << TEXT("<invoke name=\"SetData\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number><string><![CDATA[ ") << data << TEXT(" ]]></string></arguments></invoke>");\r
+#else\r
+       flashParam << TEXT("<invoke name=\"SetData\" returntype=\"xml\"><arguments><array><property id=\"0\"><number>") << layer << TEXT("</number></property></array><string><![CDATA[ ") << data << TEXT(" ]]></string></arguments></invoke>");\r
+#endif\r
+       LOG << LogLevel::Debug << TEXT("Invoking update-command");\r
+       pFlashProducer_->Param(flashParam.str());\r
+}\r
+\r
+void FlashCGProxy::Invoke(int layer, const tstring& label) {\r
+       tstringstream flashParam;\r
+#if TEMPLATEHOST_VERSION < 1700\r
+       flashParam << TEXT("<invoke name=\"ExecuteMethod\" returntype=\"xml\"><arguments><number>") << layer << TEXT("</number><string>") << label << TEXT("</string></arguments></invoke>");\r
+#else\r
+       flashParam << TEXT("<invoke name=\"Invoke\" returntype=\"xml\"><arguments><array><property id=\"0\"><number>") << layer << TEXT("</number></property></array><string>") << label << TEXT("</string></arguments></invoke>");\r
+#endif\r
+       LOG << LogLevel::Debug << TEXT("Invoking invoke-command");\r
+       pFlashProducer_->Param(flashParam.str());\r
+}\r
+*/\r
+}      //namespace CG\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/cg/FlashCGProxy.h b/server/cg/FlashCGProxy.h
new file mode 100644 (file)
index 0000000..d23a563
--- /dev/null
@@ -0,0 +1,83 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _CASPAR_FLASHCGPROXY_H__\r
+#define _CASPAR_FLASHCGPROXY_H__\r
+\r
+#pragma once\r
+\r
+#include "CGControl.h"\r
+\r
+namespace caspar {\r
+\r
+class Monitor;\r
+\r
+class FlashProducer;\r
+typedef std::tr1::shared_ptr<FlashProducer> FlashProducerPtr;\r
+\r
+typedef std::tr1::function<void()> EmptyCallback;\r
+\r
+namespace CG { \r
+\r
+class FlashCGProxy;\r
+typedef std::tr1::shared_ptr<FlashCGProxy> FlashCGProxyPtr;\r
+\r
+class FlashCGProxy : public ICGControl\r
+{\r
+       static int cgVersion_;\r
+\r
+protected:\r
+       FlashCGProxy();\r
+\r
+public:\r
+       virtual ~FlashCGProxy();\r
+\r
+       static FlashCGProxyPtr Create(Monitor* pMonitor = 0);\r
+\r
+       static void SetCGVersion();\r
+\r
+       bool Initialize(FrameManagerPtr pFrameManager);\r
+       FrameBuffer& GetFrameBuffer();\r
+       bool IsEmpty() const;\r
+       void SetEmptyAlert(EmptyCallback callback);\r
+       void Stop();\r
+\r
+       //ICGControl\r
+       virtual void Clear();\r
+       virtual void Add(int layer, const tstring& templateName,  bool playOnLoad, const tstring& startFromLabel = TEXT(""), const tstring& data = TEXT("")) {}\r
+       virtual void Remove(int layer) {}\r
+       virtual void Play(int layer) {}\r
+       virtual void Stop(int layer, unsigned int mixOutDuration) {}\r
+       virtual void Next(int layer) {}\r
+       virtual void Update(int layer, const tstring& data) {}\r
+       virtual void Invoke(int layer, const tstring& label) {}\r
+       \r
+       FlashProducerPtr GetFlashProducer() {\r
+               return pFlashProducer_;\r
+       }\r
+protected:\r
+       FlashProducerPtr pFlashProducer_;\r
+};\r
+\r
+\r
+}      //namespace CG\r
+}      //namespace caspar\r
+\r
+#endif //_CASPAR_FLASHCGPROXY_H__
\ No newline at end of file
diff --git a/server/cii/CIICommand.h b/server/cii/CIICommand.h
new file mode 100644 (file)
index 0000000..53b9700
--- /dev/null
@@ -0,0 +1,41 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+\r
+#include <vector>\r
+#include <string>\r
+\r
+namespace caspar {\r
+namespace cii {\r
+\r
+class ICIICommand\r
+{\r
+public:\r
+       virtual ~ICIICommand() {}\r
+       virtual int GetMinimumParameters() = 0;\r
+       virtual void Setup(const std::vector<tstring>& parameters) = 0;\r
+\r
+       virtual void Execute() = 0;\r
+};\r
+typedef std::tr1::shared_ptr<ICIICommand> CIICommandPtr;\r
+\r
+}      //namespace cii\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/cii/CIICommandsImpl.cpp b/server/cii/CIICommandsImpl.cpp
new file mode 100644 (file)
index 0000000..bcb3336
--- /dev/null
@@ -0,0 +1,188 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\StdAfx.h"\r
+\r
+#include "CIIProtocolStrategy.h"\r
+#include "..\channel.h"\r
+#include "..\cg\cgcontrol.h"\r
+#include "CIICommandsImpl.h"\r
+#include <sstream>\r
+#include <algorithm>\r
+\r
+namespace caspar {\r
+namespace cii {\r
+\r
+/////////////////\r
+// MediaCommand\r
+void MediaCommand::Setup(const std::vector<tstring>& parameters) {\r
+       graphicProfile_ = parameters[1].substr(2);\r
+}\r
+\r
+void MediaCommand::Execute() {\r
+       pCIIStrategy_->SetProfile(graphicProfile_);\r
+}\r
+\r
+\r
+/////////////////\r
+// WriteCommand\r
+void WriteCommand::Setup(const std::vector<tstring>& parameters) {\r
+       try {\r
+               if(parameters.size()>2) {\r
+                       targetName_ = parameters[1];\r
+                       templateName_ = parameters[2];\r
+\r
+                       tstringstream dataStream;\r
+\r
+                       dataStream << TEXT("<templateData>");\r
+\r
+                       std::vector<tstring>::size_type end = parameters.size();\r
+                       for(std::vector<tstring>::size_type i = 3; i < end; ++i) {\r
+                               dataStream << TEXT("<componentData id=\"field") << i-2 << TEXT("\"><data id=\"text\" value=\"") << parameters[i] << TEXT("\" /></componentData>"); \r
+                       }\r
+\r
+                       dataStream << TEXT("</templateData>");\r
+                       xmlData_ = dataStream.str();\r
+               }\r
+       }\r
+       catch(std::exception) {\r
+       }\r
+}\r
+\r
+void WriteCommand::Execute() {\r
+       pCIIStrategy_->WriteTemplateData(templateName_, targetName_, xmlData_);\r
+}\r
+\r
+\r
+//////////////////////\r
+// ImagestoreCommand\r
+void ImagestoreCommand::Setup(const std::vector<tstring>& parameters) {\r
+       if(parameters[1] == TEXT("7") && parameters.size() > 2) {\r
+               titleName_ = parameters[2].substr(0, 4);\r
+       }\r
+}\r
+\r
+void ImagestoreCommand::Execute() {\r
+       pCIIStrategy_->DisplayTemplate(titleName_);\r
+}\r
+\r
+\r
+//////////////////////\r
+// MiscellaneousCommand\r
+void MiscellaneousCommand::Setup(const std::vector<tstring>& parameters) {\r
+       //HAWRYS:       V\5\3\1\1\namn.tga\1\r
+       //                      Display still\r
+       if((parameters.size() > 5) && parameters[1] == TEXT("5") && parameters[2] == TEXT("3")) {\r
+               filename_ = parameters[5];\r
+               filename_ = filename_.substr(0, filename_.find_last_of(TEXT('.')));\r
+               state_ = 0;\r
+               return;\r
+       }\r
+       \r
+       //NEPTUNE:      V\5\13\1\X\Template\0\TabField1\TabField2...\r
+       //                      Add Template to layer X in the active templatehost\r
+       if((parameters.size() > 5) && parameters[1] == TEXT("5") && parameters[2] == TEXT("13"))\r
+       {\r
+               layer_ = _ttoi(parameters[4].c_str());\r
+               filename_ = parameters[5];\r
+               state_ = 1;\r
+               if(parameters.size() > 7) {\r
+                       tstringstream dataStream;\r
+\r
+                       dataStream << TEXT("<templateData>");\r
+                       std::vector<tstring>::size_type end = parameters.size();\r
+                       for(std::vector<tstring>::size_type i = 7; i < end; ++i) {\r
+                               dataStream << TEXT("<componentData id=\"f") << i-7 << TEXT("\"><data id=\"text\" value=\"") << parameters[i] << TEXT("\" /></componentData>"); \r
+                       }\r
+                       dataStream << TEXT("</templateData>");\r
+\r
+                       xmlData_ = dataStream.str();\r
+               }\r
+       }\r
+\r
+       // VIDEO MODE V\5\14\MODE\r
+       if((parameters.size() > 3) && parameters[1] == TEXT("5") && parameters[2] == TEXT("14"))\r
+       {\r
+               tstring value = parameters[3];\r
+               std::transform(value.begin(), value.end(), value.begin(), toupper);\r
+\r
+               this->pCIIStrategy_->GetChannel()->SetVideoFormat(value);\r
+       }\r
+}\r
+\r
+void MiscellaneousCommand::Execute() {\r
+       if(state_ == 0)\r
+       {\r
+               pCIIStrategy_->DisplayMediaFile(filename_);\r
+       }\r
+\r
+       //TODO: Need to be checked for validity\r
+       else if(state_ == 1)\r
+               pCIIStrategy_->GetCGControl()->Add(layer_, filename_, false, TEXT(""), xmlData_);\r
+}\r
+\r
+\r
+///////////////////\r
+// KeydataCommand\r
+void KeydataCommand::Execute() {\r
+       if(state_ == 0)\r
+       {\r
+               pCIIStrategy_->DisplayTemplate(titleName_);\r
+       }\r
+\r
+       //TODO: Need to be checked for validity\r
+       else if(state_ == 1)\r
+               pCIIStrategy_->GetCGControl()->Stop(layer_, 0);\r
+       else if(state_ == 2)\r
+               pCIIStrategy_->GetCGControl()->Clear();\r
+       else if(state_ == 3)\r
+               pCIIStrategy_->GetCGControl()->Play(layer_);\r
+}\r
+\r
+void KeydataCommand::Setup(const std::vector<tstring>& parameters) {\r
+       //HAWRYS:       Y\<205><247><202><196><192><192><200><248>\r
+       //parameter[1] looks like this: "=g:XXXXh" where XXXX is the name that we want\r
+       if(parameters[1].size() > 6) {\r
+               titleName_.resize(4);\r
+               for(int i=0;i<4;++i) {\r
+                       if(parameters[1][i+3] < 176) {\r
+                               titleName_ = TEXT("");\r
+                               break;\r
+                       }\r
+                       titleName_[i] = parameters[1][i+3]-144;\r
+               }\r
+               state_ = 0;\r
+       }\r
+\r
+       if(parameters.size() > 2)\r
+       {\r
+               layer_ = _ttoi(parameters[2].c_str());\r
+       }\r
+\r
+       if(parameters[1].at(0) == 27)   //NEPTUNE:      Y\<27>\X                        Stop layer X.\r
+               state_ = 1;\r
+       else if(static_cast<unsigned char>(parameters[1].at(0)) == 254) //NEPTUNE:      Y\<254>                 Clear Canvas. \r
+               state_ = 2;\r
+       else if(static_cast<unsigned char>(parameters[1].at(0)) == 213) //NEPTUNE:      Y\<213><243>\X  Play layer X. \r
+               state_ = 3;\r
+}\r
+\r
+}      //namespace cii\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/cii/CIICommandsImpl.h b/server/cii/CIICommandsImpl.h
new file mode 100644 (file)
index 0000000..b7a2f4b
--- /dev/null
@@ -0,0 +1,137 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+\r
+#include <string>\r
+#include <vector>\r
+\r
+#include "ciicommand.h"\r
+\r
+namespace caspar {\r
+\r
+namespace cii {\r
+\r
+class CIIProtocolStrategy;\r
+\r
+class MediaCommand : public ICIICommand\r
+{\r
+public:\r
+       MediaCommand(CIIProtocolStrategy* pPS) : pCIIStrategy_(pPS)\r
+       {}\r
+\r
+       virtual int GetMinimumParameters() {\r
+               return 1;\r
+       }\r
+\r
+       virtual void Setup(const std::vector<tstring>& parameters);\r
+       virtual void Execute();\r
+\r
+private:\r
+       tstring graphicProfile_;\r
+\r
+       CIIProtocolStrategy* pCIIStrategy_;\r
+};\r
+\r
+class WriteCommand : public ICIICommand\r
+{\r
+public:\r
+       WriteCommand(CIIProtocolStrategy* pPS) : pCIIStrategy_(pPS)\r
+       {}\r
+\r
+       virtual int GetMinimumParameters() {\r
+               return 2;\r
+       }\r
+\r
+       virtual void Setup(const std::vector<tstring>& parameters);\r
+       virtual void Execute();\r
+\r
+private:\r
+       tstring targetName_;\r
+       tstring templateName_;\r
+       tstring xmlData_;\r
+\r
+       CIIProtocolStrategy* pCIIStrategy_;\r
+};\r
+\r
+class MiscellaneousCommand : public ICIICommand\r
+{\r
+public:\r
+       MiscellaneousCommand(CIIProtocolStrategy* pPS) : pCIIStrategy_(pPS), state_(-1), layer_(0)\r
+       {}\r
+\r
+       virtual int GetMinimumParameters() {\r
+               return 5;\r
+       }\r
+\r
+       virtual void Setup(const std::vector<tstring>& parameters);\r
+       virtual void Execute();\r
+\r
+private:\r
+       tstring filename_;\r
+       tstring xmlData_;\r
+       int state_;\r
+       int layer_;\r
+\r
+       CIIProtocolStrategy* pCIIStrategy_;\r
+};\r
+\r
+class ImagestoreCommand : public ICIICommand\r
+{\r
+public:\r
+       ImagestoreCommand(CIIProtocolStrategy* pPS) : pCIIStrategy_(pPS)\r
+       {}\r
+\r
+       virtual int GetMinimumParameters() {\r
+               return 1;\r
+       }\r
+\r
+       virtual void Setup(const std::vector<tstring>& parameters);\r
+       virtual void Execute();\r
+\r
+private:\r
+       tstring titleName_;\r
+\r
+       CIIProtocolStrategy* pCIIStrategy_;\r
+};\r
+\r
+class KeydataCommand : public ICIICommand\r
+{\r
+public:\r
+       KeydataCommand(CIIProtocolStrategy* pPS) : pCIIStrategy_(pPS), state_(-1), layer_(0)\r
+       {}\r
+\r
+       virtual int GetMinimumParameters() {\r
+               return 1;\r
+       }\r
+\r
+       virtual void Setup(const std::vector<tstring>& parameters);\r
+       virtual void Execute();\r
+\r
+private:\r
+       tstring titleName_;\r
+       int state_;\r
+       int layer_;\r
+\r
+       CIIProtocolStrategy* pCIIStrategy_;\r
+};\r
+\r
+}      //namespace cii\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/cii/CIIProtocolStrategy.cpp b/server/cii/CIIProtocolStrategy.cpp
new file mode 100644 (file)
index 0000000..92a6b9c
--- /dev/null
@@ -0,0 +1,296 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\StdAfx.h"\r
+\r
+#include <string>\r
+#include <sstream>\r
+#include <algorithm>\r
+#include "CIIProtocolStrategy.h"\r
+#include "CIICommandsimpl.h"\r
+#include "..\producers\flash\FlashManager.h"\r
+#include "..\application.h"\r
+#include "..\fileinfo.h"\r
+\r
+namespace caspar {\r
+namespace cii {\r
+\r
+using namespace utils;\r
+\r
+const tstring CIIProtocolStrategy::MessageDelimiter = TEXT("\r\n");\r
+const TCHAR CIIProtocolStrategy::TokenDelimiter = TEXT('\\');\r
+\r
+CIIProtocolStrategy::CIIProtocolStrategy() {\r
+       pChannel_ = GetApplication()->GetChannel(0);\r
+       pCGControl_ = pChannel_->GetCGControl();\r
+\r
+       if(!commandQueue_.Start()) {\r
+               //throw\r
+       }\r
+}\r
+\r
+CIIProtocolStrategy::~CIIProtocolStrategy() {\r
+}\r
+\r
+void CIIProtocolStrategy::Parse(const TCHAR* pData, int charCount, caspar::IO::ClientInfoPtr pClientInfo) {\r
+       std::size_t pos;\r
+       tstring msg(pData, charCount);\r
+       tstring availibleData = currentMessage_ + msg;\r
+\r
+       while(true) {\r
+               pos = availibleData.find(MessageDelimiter);\r
+               if(pos != tstring::npos)\r
+               {\r
+                       tstring message = availibleData.substr(0,pos);\r
+\r
+                       if(message.length() > 0) {\r
+                               ProcessMessage(message);\r
+                               if(pClientInfo != 0)\r
+                                       pClientInfo->Send(TEXT("*\r\n"));\r
+                       }\r
+\r
+                       std::size_t nextStartPos = pos + MessageDelimiter.length();\r
+                       if(nextStartPos < availibleData.length())\r
+                               availibleData = availibleData.substr(nextStartPos);\r
+                       else {\r
+                               availibleData.clear();\r
+                               break;\r
+                       }\r
+               }\r
+               else\r
+                       break;\r
+       }\r
+       currentMessage_ = availibleData;\r
+}\r
+\r
+void CIIProtocolStrategy::ProcessMessage(const tstring& message) {\r
+       LOG << message.c_str() << LogStream::Flush;\r
+\r
+       std::vector<tstring> tokens;\r
+       int tokenCount = TokenizeMessage(message, &tokens);\r
+\r
+       CIICommandPtr pCommand = Create(tokens[0]);\r
+       if((pCommand != 0) && (tokenCount-1) >= pCommand->GetMinimumParameters()) {\r
+               pCommand->Setup(tokens);\r
+               commandQueue_.AddCommand(pCommand);\r
+       }\r
+       else {\r
+               //report error\r
+       }\r
+}\r
+\r
+int CIIProtocolStrategy::TokenizeMessage(const tstring& message, std::vector<tstring>* pTokenVector)\r
+{\r
+       tstringstream currentToken;\r
+\r
+       for(unsigned int charIndex=0; charIndex<message.size(); ++charIndex) {\r
+               if(message[charIndex] == TokenDelimiter) {\r
+                       pTokenVector->push_back(currentToken.str());\r
+                       currentToken.str(TEXT(""));\r
+                       continue;\r
+               }\r
+\r
+               if(message[charIndex] == TEXT('\"')) {\r
+                       currentToken << TEXT("&quot;");\r
+               }\r
+               else if(message[charIndex] == TEXT('<')) {\r
+                       currentToken << TEXT("&lt;");\r
+               }\r
+               else if(message[charIndex] == TEXT('>')) {\r
+                       currentToken << TEXT("&gt;");\r
+               }\r
+               else \r
+                       currentToken << message[charIndex];\r
+       }\r
+\r
+       if(currentToken.str().size() > 0) {\r
+               pTokenVector->push_back(currentToken.str());\r
+       }\r
+\r
+       return (int)pTokenVector->size();\r
+}\r
+\r
+/************\r
+// Examples (<X> = ASCIICHAR X)\r
+\r
+I\25\3\VII\\                                                                   sätter outputtype till 'vii'\r
+I\25\4\1\\                                                                             enablar framebuffer (ignore this)\r
+\r
+M\C/SVTNEWS\\                                                                  pekar ut vilken grafisk profil som skall användas\r
+\r
+W\4009\4067\Jonas Björkman\\                                   Skriver "Jonas Björkman" till första textfältet i template 4067 och sparar den färdiga skylten som 4009\r
+\r
+T\7\4009.VII\A\\                                                               lägger ut skylt 4009\r
+\r
+Y\<205><247><202><196><192><192><200><248>\\   lägger ut skylten 4008 (<205><247><202><196><192><192><200><248> = "=g:4008h" om man drar bort 144 frÃ¥n varje asciivärde)\r
+\r
+V\5\3\1\1\namn.tga\1\\                                                 lägger ut bilden namn.tga\r
+V\0\1\D\C\10\0\0\0\\                                                   gör nÃ¥gon inställning som har med föregÃ¥ende kommando att göra.\r
+\r
+*************/\r
+\r
+/**********************\r
+New Commands to support the Netupe automation system\r
+V\5\13\1\1\Template\0\TabField1\TabField2...\\         Build. Ettan före Template indikerar vilket lager den nya templaten skall laddas in i. OBS. Skall inte visas efter det här steget\r
+Y\<27>\\                                                                                       Stop. Här kommer ett lagerID ocksÃ¥ att skickas med (<27> = ESC)\r
+Y\<254>\\                                                                                      Clear Canvas. Här kommer ett lagerID ocksÃ¥ att skickas med, utan det skall allt tömmas\r
+Y\<213><243>\\                                                                         Play. Här kommer ett lagerID ocksÃ¥ att skickas med\r
+\r
+**********************/\r
+CIICommandPtr CIIProtocolStrategy::Create(const tstring& name) {\r
+       CIICommandPtr result;\r
+\r
+       switch(name[0]) {\r
+               case TEXT('M'):\r
+                       result = CIICommandPtr(new MediaCommand(this));\r
+                       break;\r
+               case TEXT('W'):\r
+                       result = CIICommandPtr(new WriteCommand(this));\r
+                       break;\r
+               case TEXT('T'):\r
+                       result = CIICommandPtr(new ImagestoreCommand(this));\r
+                       break;\r
+               case TEXT('V'):\r
+                       result = CIICommandPtr(new MiscellaneousCommand(this));\r
+                       break;\r
+               case TEXT('Y'):\r
+                       result = CIICommandPtr(new KeydataCommand(this));\r
+                       break;\r
+\r
+               default:\r
+                       break;\r
+       }\r
+\r
+       return result;\r
+}\r
+\r
+void CIIProtocolStrategy::WriteTemplateData(const tstring& templateName, const tstring& titleName, const tstring& xmlData) {\r
+       tstring fullTemplateFilename = GetApplication()->GetTemplateFolder();\r
+       if(currentProfile_.size() > 0)\r
+       {\r
+               fullTemplateFilename += currentProfile_;\r
+               fullTemplateFilename += TEXT("\\");\r
+       }\r
+       fullTemplateFilename += templateName;\r
+\r
+       if(!GetApplication()->FindTemplate(fullTemplateFilename))\r
+       {\r
+               LOG << TEXT("Failed to save instance of ") << templateName << TEXT(" as ") << titleName << TEXT(", template ") << fullTemplateFilename << TEXT(" not found") << LogStream::Flush;\r
+               return;\r
+       }\r
+\r
+       MediaProducerPtr pFP = pFlashManager_->CreateProducer(GetApplication()->GetTemplateFolder()+TEXT("CG.fth"));\r
+       if(pFP != 0)\r
+       {\r
+               //TODO: Initialize with valid FrameFactory\r
+//             pFP->Initialize(0, false);\r
+\r
+               tstringstream flashParam;\r
+               flashParam << TEXT("<invoke name=\"Add\" returntype=\"xml\"><arguments><number>1</number><string>") << currentProfile_ << '/' <<  templateName << TEXT("</string><number>0</number><true/><string> </string><string><![CDATA[ ") << xmlData << TEXT(" ]]></string></arguments></invoke>");\r
+               pFP->Param(flashParam.str());\r
+\r
+               LOG << LogLevel::Verbose << TEXT("Saved an instance of ") << templateName << TEXT(" as ") << titleName << LogStream::Flush;\r
+\r
+               PutPreparedTemplate(titleName, pFP);\r
+       }\r
+}\r
+\r
+void CIIProtocolStrategy::DisplayTemplate(const tstring& titleName) {\r
+       MediaProducerPtr pFP = GetPreparedTemplate(titleName);\r
+       if(pFP != 0)\r
+       {\r
+               TransitionInfo transition;\r
+               if(pChannel_->LoadBackground(pFP, transition)) {\r
+                       pChannel_->Play();\r
+\r
+                       LOG << LogLevel::Verbose << TEXT("Displayed title ") << titleName << LogStream::Flush;\r
+                       return;\r
+               }\r
+       }\r
+       LOG << TEXT("Failed to display title ") << titleName << LogStream::Flush;\r
+}\r
+\r
+void CIIProtocolStrategy::DisplayMediaFile(const tstring& filename) {\r
+       caspar::FileInfo fileInfo;\r
+       MediaManagerPtr pMediaManager = GetApplication()->FindMediaFile(GetApplication()->GetMediaFolder()+filename, &fileInfo);\r
+       if(pMediaManager != 0)\r
+       {\r
+               tstring fullFilename = filename;\r
+               if(fileInfo.filetype.length()>0)\r
+               {\r
+                       fullFilename += TEXT(".");\r
+                       fullFilename += fileInfo.filetype;\r
+               }\r
+\r
+               MediaProducerPtr pFP = pMediaManager->CreateProducer(GetApplication()->GetMediaFolder()+fullFilename);\r
+               if(pFP != 0)\r
+               {\r
+                       caspar::TransitionInfo transition;\r
+                       transition.type_ = Mix;\r
+                       transition.duration_ = 12;\r
+                       if(pChannel_->LoadBackground(pFP, transition)){\r
+                               pChannel_->Play();\r
+\r
+                               LOG << LogLevel::Verbose << TEXT("Displayed ") << fullFilename << LogStream::Flush;\r
+                               return;\r
+                       }\r
+               }\r
+       }\r
+       LOG << TEXT("Failed to display ") << filename << LogStream::Flush;\r
+}\r
+\r
+MediaProducerPtr CIIProtocolStrategy::GetPreparedTemplate(const tstring& titleName) {\r
+       MediaProducerPtr result;\r
+\r
+       TitleList::iterator it = std::find(titles_.begin(), titles_.end(), titleName);\r
+       if(it != titles_.end()) {\r
+               LOG << LogLevel::Debug << TEXT("Found title with name ") << (*it).titleName << LogStream::Flush;\r
+               result = (*it).pMediaProducer;\r
+       }\r
+       else {\r
+               LOG << TEXT("Could not find title with name ") << titleName << LogStream::Flush;\r
+       }\r
+\r
+       return result;\r
+}\r
+\r
+void CIIProtocolStrategy::PutPreparedTemplate(const tstring& titleName, MediaProducerPtr& pFP) {\r
+       LOG << LogLevel::Debug << TEXT("Saved title with name ") << titleName << LogStream::Flush;\r
+\r
+       TitleList::iterator it = std::find(titles_.begin(), titles_.end(), titleName);\r
+       if(it != titles_.end()) {\r
+               titles_.remove((*it));\r
+       }\r
+\r
+       titles_.push_front(TitleHolder(titleName, pFP));\r
+\r
+       if(titles_.size() >= 6)\r
+               titles_.resize(5);\r
+}\r
+\r
+bool operator==(const CIIProtocolStrategy::TitleHolder& lhs, const tstring& rhs) {\r
+       return lhs.titleName == rhs;\r
+}\r
+bool operator==(const tstring& lhs, const CIIProtocolStrategy::TitleHolder& rhs) {\r
+       return lhs == rhs.titleName;\r
+}\r
+\r
+}      //namespace cii\r
+}      //namespace caspar\r
diff --git a/server/cii/CIIProtocolStrategy.h b/server/cii/CIIProtocolStrategy.h
new file mode 100644 (file)
index 0000000..9310886
--- /dev/null
@@ -0,0 +1,108 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+#include <vector>\r
+#include "..\io\ProtocolStrategy.h"\r
+#include "..\utils\commandqueue.h"\r
+#include "..\channel.h"\r
+#include "..\MediaManager.h"\r
+#include "CIICommand.h"\r
+\r
+namespace caspar {\r
+       namespace CG { class ICGControl; }\r
+namespace cii {\r
+\r
+class CIIProtocolStrategy : public caspar::IO::IProtocolStrategy\r
+{\r
+public:\r
+       CIIProtocolStrategy();\r
+       virtual ~CIIProtocolStrategy();\r
+\r
+       virtual void Parse(const TCHAR* pData, int charCount, caspar::IO::ClientInfoPtr pClientInfo);\r
+       virtual UINT GetCodepage() {\r
+               return 28591;   //ISO 8859-1\r
+       }\r
+\r
+       void SetProfile(const tstring& profile) {\r
+               currentProfile_ = profile;\r
+       }\r
+       caspar::CG::ICGControl* GetCGControl() const {\r
+               return pCGControl_;\r
+       }\r
+\r
+       caspar::ChannelPtr GetChannel() const\r
+       {\r
+               return this->pChannel_;\r
+       }\r
+\r
+       void DisplayMediaFile(const tstring& filename);\r
+       void DisplayTemplate(const tstring& titleName);\r
+       void WriteTemplateData(const tstring& templateName, const tstring& titleName, const tstring& xmlData);\r
+\r
+public:\r
+       struct TitleHolder\r
+       {\r
+               TitleHolder() : titleName(TEXT(""))\r
+               {}\r
+               TitleHolder(const tstring& name, MediaProducerPtr pFP) : titleName(name), pMediaProducer(pFP)\r
+               {}\r
+               TitleHolder(const TitleHolder& th) : titleName(th.titleName), pMediaProducer(th.pMediaProducer)\r
+               {}\r
+               const TitleHolder& operator=(const TitleHolder& th) {\r
+                       titleName = th.titleName;\r
+                       pMediaProducer = th.pMediaProducer;\r
+               }\r
+               bool operator==(const TitleHolder& rhs) {\r
+                       return pMediaProducer == rhs.pMediaProducer;\r
+               }\r
+\r
+               tstring titleName;\r
+               MediaProducerPtr pMediaProducer;\r
+               friend CIIProtocolStrategy;\r
+       };\r
+private:\r
+       friend TitleHolder;\r
+       friend bool operator==(const TitleHolder& lhs, const tstring& rhs);\r
+       friend bool operator==(const tstring& lhs, const TitleHolder& rhs);\r
+\r
+       typedef std::list<TitleHolder> TitleList;\r
+       TitleList titles_;\r
+       MediaProducerPtr GetPreparedTemplate(const tstring& name);\r
+       void PutPreparedTemplate(const tstring& name, MediaProducerPtr& pMediaProducer);\r
+\r
+       static const TCHAR TokenDelimiter;\r
+       static const tstring MessageDelimiter;\r
+\r
+       void ProcessMessage(const tstring& message);\r
+       int TokenizeMessage(const tstring& message, std::vector<tstring>* pTokenVector);\r
+       CIICommandPtr Create(const tstring& name);\r
+\r
+       caspar::utils::CommandQueue<CIICommandPtr> commandQueue_;\r
+       tstring currentMessage_;\r
+\r
+       tstring currentProfile_;\r
+       caspar::MediaManagerPtr pFlashManager_;\r
+       caspar::CG::ICGControl* pCGControl_;\r
+       ChannelPtr pChannel_;\r
+};\r
+\r
+}      //namespace cii\r
+}      //namespace caspar\r
diff --git a/server/consumers/Audio/AudioConsumer.cpp b/server/consumers/Audio/AudioConsumer.cpp
new file mode 100644 (file)
index 0000000..fa4335a
--- /dev/null
@@ -0,0 +1,137 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\..\stdafx.h"\r
+\r
+#include "AudioConsumer.h"\r
+#include "..\..\frame\FramePlaybackControl.h"\r
+#include "..\..\frame\SystemFrameManager.h"\r
+#include "..\..\frame\Frame.h"\r
+#include "..\..\frame\FramePlaybackStrategy.h"\r
+#include "..\..\utils\image\Image.hpp"\r
+\r
+namespace caspar {\r
+namespace audio {\r
+\r
+\r
+struct AudioConsumer::Implementation\r
+{\r
+       struct AudioPlaybackStrategy : public IFramePlaybackStrategy\r
+       {\r
+               explicit AudioPlaybackStrategy(Implementation* pConsumerImpl) : pConsumerImpl_(pConsumerImpl)\r
+               {\r
+                       lastTime_ = timeGetTime();\r
+               }\r
+\r
+               FrameManagerPtr GetFrameManager()\r
+               {\r
+                       return pConsumerImpl_->pFrameManager_;\r
+               }\r
+               FramePtr GetReservedFrame()\r
+               {\r
+                       return pConsumerImpl_->pFrameManager_->CreateFrame();\r
+               }\r
+\r
+               void DisplayFrame(Frame* pFrame)\r
+               {\r
+                       DWORD timediff = timeGetTime() - lastTime_;\r
+                       if(timediff < 30) {\r
+                               Sleep(40 - timediff);\r
+                               lastTime_ += 40;\r
+                       }\r
+                       else\r
+                               lastTime_ = timeGetTime();\r
+\r
+                       if(pFrame == NULL || pFrame->ID() == lastFrameID_)\r
+                               return;\r
+\r
+                       lastFrameID_ = pFrame->ID();\r
+               }\r
+\r
+               Implementation* pConsumerImpl_;\r
+               DWORD lastTime_;        \r
+               utils::ID lastFrameID_;\r
+       };\r
+\r
+       explicit Implementation(const FrameFormatDescription& fmtDesc) : fmtDesc_(fmtDesc)\r
+       {       \r
+               SetupDevice();\r
+       }\r
+\r
+       ~Implementation()\r
+       {\r
+               ReleaseDevice();\r
+       }\r
+\r
+       bool SetupDevice()\r
+       {\r
+               pFrameManager_.reset(new SystemFrameManager(fmtDesc_));\r
+               pPlaybackControl_.reset(new FramePlaybackControl(FramePlaybackStrategyPtr(new AudioPlaybackStrategy(this))));\r
+\r
+               pPlaybackControl_->Start();\r
+               return true;\r
+       }\r
+\r
+       bool ReleaseDevice()\r
+       {\r
+               pPlaybackControl_->Stop();\r
+               return true;\r
+       }\r
+\r
+       FramePlaybackControlPtr pPlaybackControl_;\r
+       SystemFrameManagerPtr pFrameManager_;\r
+\r
+       FrameFormatDescription fmtDesc_;\r
+};\r
+\r
+AudioConsumer::AudioConsumer(const FrameFormatDescription& fmtDesc) : pImpl_(new Implementation(fmtDesc))\r
+{}\r
+\r
+AudioConsumer::~AudioConsumer()\r
+{}\r
+\r
+IPlaybackControl* AudioConsumer::GetPlaybackControl() const\r
+{\r
+       return pImpl_->pPlaybackControl_.get();\r
+}\r
+\r
+bool AudioConsumer::SetupDevice(unsigned int deviceIndex)\r
+{\r
+       return pImpl_->SetupDevice();\r
+}\r
+\r
+bool AudioConsumer::ReleaseDevice()\r
+{\r
+       return pImpl_->ReleaseDevice();\r
+}\r
+\r
+void AudioConsumer::EnableVideoOutput(){}\r
+void AudioConsumer::DisableVideoOutput(){}\r
+\r
+const FrameFormatDescription& AudioConsumer::GetFrameFormatDescription() const {\r
+       return pImpl_->fmtDesc_;\r
+}\r
+const TCHAR* AudioConsumer::GetFormatDescription() const {\r
+       return pImpl_->fmtDesc_.name;\r
+}\r
+\r
+\r
+}      //namespace audio\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/consumers/Audio/AudioConsumer.h b/server/consumers/Audio/AudioConsumer.h
new file mode 100644 (file)
index 0000000..5253935
--- /dev/null
@@ -0,0 +1,55 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+#include "..\..\VideoConsumer.h"\r
+#include "..\..\MediaProducer.h"\r
+\r
+#include "..\..\utils\thread.h"\r
+#include "..\..\utils\lockable.h"\r
+#include "..\..\utils\Noncopyable.hpp"\r
+\r
+#include "..\..\frame\Frame.h"\r
+\r
+namespace caspar {\r
+namespace audio {\r
+\r
+class AudioConsumer : public IVideoConsumer, private utils::LockableObject, utils::Noncopyable\r
+{\r
+public:\r
+       explicit AudioConsumer(const FrameFormatDescription& fmtDesc);\r
+       virtual ~AudioConsumer();\r
+\r
+       virtual IPlaybackControl* GetPlaybackControl() const;\r
+\r
+       virtual void EnableVideoOutput();\r
+       virtual void DisableVideoOutput();\r
+       virtual bool SetupDevice(unsigned int deviceIndex);\r
+       virtual bool ReleaseDevice();\r
+       virtual const FrameFormatDescription& GetFrameFormatDescription() const;\r
+       virtual const TCHAR* GetFormatDescription() const;\r
+\r
+private:\r
+       struct Implementation;\r
+       std::tr1::shared_ptr<Implementation> pImpl_;\r
+};\r
+\r
+}      //namespace audio\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/consumers/GDI/GDIVideoConsumer.cpp b/server/consumers/GDI/GDIVideoConsumer.cpp
new file mode 100644 (file)
index 0000000..936fc0c
--- /dev/null
@@ -0,0 +1,152 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\..\stdafx.h"\r
+\r
+#include "GDIVideoConsumer.h"\r
+#include "..\..\frame\FramePlaybackControl.h"\r
+#include "..\..\frame\BitmapFrameManager.h"\r
+#include "..\..\frame\Frame.h"\r
+#include "..\..\frame\FramePlaybackStrategy.h"\r
+#include "..\..\utils\DCWrapper.h"\r
+#include "..\..\utils\BitmapHolder.h"\r
+#include "..\..\utils\image\Image.hpp"\r
+\r
+namespace caspar {\r
+namespace gdi {\r
+\r
+\r
+struct GDIVideoConsumer::Implementation\r
+{\r
+       struct GDIPlaybackStrategy : public IFramePlaybackStrategy\r
+       {\r
+               GDIPlaybackStrategy(Implementation* pConsumerImpl) : pConsumerImpl_(pConsumerImpl), pTempBitmapData_(new BitmapHolder(pConsumerImpl_->hWnd_, pConsumerImpl_->fmtDesc_.width, pConsumerImpl_->fmtDesc_.height))\r
+               {\r
+                       lastTime_ = timeGetTime();\r
+               }\r
+\r
+               FrameManagerPtr GetFrameManager()\r
+               {\r
+                       return pConsumerImpl_->pFrameManager_;\r
+               }\r
+               FramePtr GetReservedFrame()\r
+               {\r
+                       return pConsumerImpl_->pFrameManager_->CreateFrame();\r
+               }\r
+\r
+               void DisplayFrame(Frame* pFrame)\r
+               {\r
+                       DWORD timediff = timeGetTime() - lastTime_;\r
+                       if(timediff < 30) {\r
+                               Sleep(40 - timediff);\r
+                               lastTime_ += 40;\r
+                       }\r
+                       else\r
+                               lastTime_ = timeGetTime();\r
+\r
+                       if(pFrame == NULL || pFrame->ID() == lastFrameID_)\r
+                               return;\r
+\r
+                       DCWrapper hDC(pConsumerImpl_->hWnd_);\r
+\r
+                       RECT rect;\r
+                       GetClientRect(pConsumerImpl_->hWnd_, &rect);\r
+                       if(this->GetFrameManager()->Owns(*pFrame))\r
+                               BitBlt(hDC, rect.left, rect.top, rect.right, rect.bottom, reinterpret_cast<HDC>(pFrame->GetMetadata()), 0, 0, SRCCOPY);\r
+                       else {\r
+                               utils::image::Copy(pTempBitmapData_->GetPtr(), pFrame->GetDataPtr(), pFrame->GetDataSize());\r
+                               BitBlt(hDC, rect.left, rect.top, rect.right, rect.bottom, pTempBitmapData_->GetDC(), 0, 0, SRCCOPY);\r
+                       }\r
+\r
+                       lastFrameID_ = pFrame->ID();\r
+               }\r
+\r
+               Implementation* pConsumerImpl_;\r
+               BitmapHolderPtr pTempBitmapData_;               \r
+               DWORD lastTime_;        \r
+               utils::ID lastFrameID_;\r
+       };\r
+\r
+       Implementation(HWND hWnd, const FrameFormatDescription& fmtDesc) : hWnd_(hWnd), fmtDesc_(fmtDesc)\r
+       {       \r
+               SetupDevice();\r
+       }\r
+\r
+       ~Implementation()\r
+       {\r
+               ReleaseDevice();\r
+       }\r
+\r
+       bool SetupDevice()\r
+       {\r
+               pFrameManager_.reset(new BitmapFrameManager(fmtDesc_, hWnd_));\r
+               pPlaybackControl_.reset(new FramePlaybackControl(FramePlaybackStrategyPtr(new GDIPlaybackStrategy(this))));\r
+\r
+               pPlaybackControl_->Start();\r
+               return true;\r
+       }\r
+\r
+       bool ReleaseDevice()\r
+       {\r
+               pPlaybackControl_->Stop();\r
+               return true;\r
+       }\r
+\r
+       FramePlaybackControlPtr pPlaybackControl_;\r
+       BitmapFrameManagerPtr pFrameManager_;\r
+\r
+       HWND    hWnd_;\r
+       FrameFormatDescription fmtDesc_;\r
+};\r
+\r
+GDIVideoConsumer::GDIVideoConsumer(HWND hWnd, const FrameFormatDescription& fmtDesc) : pImpl_(new Implementation(hWnd, fmtDesc))\r
+{}\r
+\r
+GDIVideoConsumer::~GDIVideoConsumer()\r
+{}\r
+\r
+IPlaybackControl* GDIVideoConsumer::GetPlaybackControl() const\r
+{\r
+       return pImpl_->pPlaybackControl_.get();\r
+}\r
+\r
+bool GDIVideoConsumer::SetupDevice(unsigned int deviceIndex)\r
+{\r
+       return pImpl_->SetupDevice();\r
+}\r
+\r
+bool GDIVideoConsumer::ReleaseDevice()\r
+{\r
+       return pImpl_->ReleaseDevice();\r
+}\r
+\r
+void GDIVideoConsumer::EnableVideoOutput(){}\r
+void GDIVideoConsumer::DisableVideoOutput(){}\r
+\r
+const FrameFormatDescription& GDIVideoConsumer::GetFrameFormatDescription() const {\r
+       return pImpl_->fmtDesc_;\r
+}\r
+const TCHAR* GDIVideoConsumer::GetFormatDescription() const {\r
+       return pImpl_->fmtDesc_.name;\r
+}\r
+\r
+\r
+}      //namespace gdi\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/consumers/GDI/GDIVideoConsumer.h b/server/consumers/GDI/GDIVideoConsumer.h
new file mode 100644 (file)
index 0000000..3327686
--- /dev/null
@@ -0,0 +1,56 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+#include "..\..\VideoConsumer.h"\r
+#include "..\..\MediaProducer.h"\r
+\r
+#include "..\..\utils\thread.h"\r
+#include "..\..\utils\lockable.h"\r
+#include "..\..\utils\Noncopyable.hpp"\r
+\r
+#include "..\..\frame\BitmapFrameManager.h"\r
+#include "..\..\frame\Frame.h"\r
+\r
+namespace caspar {\r
+namespace gdi {\r
+\r
+class GDIVideoConsumer : public IVideoConsumer, private utils::LockableObject, utils::Noncopyable\r
+{\r
+public:\r
+       GDIVideoConsumer(HWND hwnd, const FrameFormatDescription& fmtDesc);\r
+       virtual ~GDIVideoConsumer();\r
+\r
+       virtual IPlaybackControl* GetPlaybackControl() const;\r
+\r
+       virtual void EnableVideoOutput();\r
+       virtual void DisableVideoOutput();\r
+       virtual bool SetupDevice(unsigned int deviceIndex);\r
+       virtual bool ReleaseDevice();\r
+       virtual const FrameFormatDescription& GetFrameFormatDescription() const;\r
+       virtual const TCHAR* GetFormatDescription() const;\r
+\r
+private:\r
+       struct Implementation;\r
+       std::tr1::shared_ptr<Implementation> pImpl_;\r
+};\r
+\r
+}      //namespace gdi\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/consumers/OGL/OGLVideoConsumer.cpp b/server/consumers/OGL/OGLVideoConsumer.cpp
new file mode 100644 (file)
index 0000000..f8437c4
--- /dev/null
@@ -0,0 +1,461 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\..\StdAfx.h"\r
+#include "OGLVideoConsumer.h"\r
+#include "..\..\frame\FramePlaybackControl.h"\r
+#include "..\..\frame\FramePlaybackStrategy.h"\r
+\r
+#include <Glee.h>\r
+\r
+namespace caspar {\r
+namespace ogl {\r
+\r
+struct OGLVideoConsumer::Implementation\r
+{\r
+       struct OGLDevice\r
+       {\r
+               OGLDevice(HWND hWnd, Stretch stretch, int screenWidth, int screenHeight) \r
+                       : hDC(NULL), \r
+                         hRC(NULL),\r
+                         width_(0), \r
+                         height_(0),\r
+                         size_(0),\r
+                         texture_(0),\r
+                         stretch_(stretch),\r
+                         screenWidth_(screenWidth),\r
+                         screenHeight_(screenHeight), \r
+                         pboIndex_(0),\r
+                         firstFrame_(true)\r
+               {                                               \r
+                       static PIXELFORMATDESCRIPTOR pfd =                              \r
+                       {\r
+                               sizeof(PIXELFORMATDESCRIPTOR),                          // Size Of This Pixel Format Descriptor\r
+                               1,                                                                                      // Version Number\r
+                               PFD_SUPPORT_OPENGL |                                            // Format Must Support OpenGL\r
+                               PFD_DOUBLEBUFFER,                                                       // Must Support Double Buffering\r
+                               PFD_TYPE_RGBA,                                                          // Request An RGBA Format\r
+                               32,                                                                                     // Select Our Color Depth\r
+                               0, 0, 0, 0, 0, 0,                                                       // Color Bits Ignored\r
+                               0,                                                                                      // No Alpha Buffer\r
+                               0,                                                                                      // Shift Bit Ignored\r
+                               0,                                                                                      // No Accumulation Buffer\r
+                               0, 0, 0, 0,                                                                     // Accumulation Bits Ignored\r
+                               0,                                                                                      // 16Bit Z-Buffer (Depth Buffer)  \r
+                               0,                                                                                      //  No Stencil Buffer\r
+                               0,                                                                                      // No Auxiliary Buffer\r
+                               PFD_MAIN_PLANE,                                                         // Main Drawing Layer\r
+                               0,                                                                                      // Reserved\r
+                               0, 0, 0                                                                         // Layer Masks Ignored\r
+                       };\r
+\r
+                       ;\r
+                       if(!(hDC = GetDC(hWnd)))\r
+                               throw std::exception("Failed To Get Device Context");\r
+\r
+                       if(!SetPixelFormat(hDC, ChoosePixelFormat(hDC, &pfd),&pfd))\r
+                               throw std::exception("Failed To Set Pixel Format");\r
+\r
+                       if(!(hRC = wglCreateContext(hDC)))\r
+                               throw std::exception("Failed To Create Render Context");\r
+\r
+                       if(!wglMakeCurrent(hDC, hRC))\r
+                               throw std::exception("Failed To Activate Render Context");\r
+\r
+                       glClearColor(0.0f, 0.0f, 0.0f, 0.0f);\r
+                       glEnable(GL_TEXTURE_2D);\r
+\r
+                       dlist_ = glGenLists(1);\r
+\r
+                       if(glGetError() != GL_NO_ERROR)\r
+                               throw std::exception("Failed To Initialize OpenGL");\r
+               }\r
+\r
+               ~OGLDevice()\r
+               {\r
+                       if (hRC)\r
+                       {\r
+                               wglMakeCurrent(NULL, NULL);\r
+                               wglDeleteContext(hRC);\r
+                               hRC = NULL;\r
+                       }\r
+\r
+                       if(texture_)\r
+                       {\r
+                               glDeleteTextures( 1, &texture_);\r
+                               texture_ = 0;\r
+                       }\r
+                       glDeleteBuffers(2, pbos_);\r
+               }\r
+\r
+               GLvoid ReSizeGLScene(GLsizei width, GLsizei height)     \r
+               {\r
+                       width_ = width;\r
+                       height_ = height;\r
+                       size_ = width_*height_*4;\r
+                       \r
+                       glViewport(0, 0, screenWidth_, screenHeight_);\r
+\r
+                       if(glGetError() != GL_NO_ERROR)\r
+                               throw std::exception("Failed To Update Viewport");\r
+\r
+                       float wratio = (float)width_/(float)width_;\r
+                       float hratio = (float)height_/(float)height_;\r
+\r
+                       std::pair<float, float> targetRatio = None();\r
+                       if(stretch_ == ogl::Fill)\r
+                               targetRatio = Fill();\r
+                       else if(stretch_ == ogl::Uniform)\r
+                               targetRatio = Uniform();\r
+                       else if(stretch_ == ogl::UniformToFill)\r
+                               targetRatio = UniformToFill();\r
+\r
+                       float wSize = targetRatio.first;\r
+                       float hSize = targetRatio.second;\r
+\r
+                       glNewList(dlist_, GL_COMPILE);\r
+                               glBegin(GL_QUADS);\r
+                                       glTexCoord2f(0.0f,       hratio);       glVertex2f(-wSize, -hSize);\r
+                                       glTexCoord2f(wratio, hratio);   glVertex2f( wSize, -hSize);\r
+                                       glTexCoord2f(wratio, 0.0f);             glVertex2f( wSize,  hSize);\r
+                                       glTexCoord2f(0.0f,       0.0f);         glVertex2f(-wSize,  hSize);\r
+                               glEnd();        \r
+                       glEndList();\r
+\r
+                       if(texture_ != 0)                       \r
+                       {\r
+                               glDeleteTextures( 1, &texture_);\r
+                               texture_ = 0;\r
+                       }\r
+                       \r
+                       glDeleteBuffers(2, pbos_);\r
+\r
+                       glGenTextures(1, &texture_);    \r
+                       glBindTexture( GL_TEXTURE_2D, texture_);\r
+\r
+                       glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );\r
+                       glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );\r
+\r
+                       glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, width_, height_, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);\r
+\r
+                       if(glGetError() != GL_NO_ERROR)\r
+                               throw std::exception("Failed To Create Texture");\r
+\r
+                       glGenBuffersARB(2, pbos_);\r
+                       GLenum error = glGetError();\r
+                       glBindBuffer(GL_PIXEL_PACK_BUFFER, pbos_[0]);\r
+                       error = glGetError();\r
+                       glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, size_, 0, GL_STREAM_DRAW);\r
+                       error = glGetError();\r
+                       glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbos_[1]);\r
+                       glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, size_, 0, GL_STREAM_DRAW);\r
+\r
+                       error = glGetError();\r
+                       if(error != GL_NO_ERROR)\r
+                               throw std::exception("Failed To Create PBOs");\r
+\r
+                       pboIndex_ = 0;\r
+               }\r
+\r
+               std::pair<float, float> None()\r
+               {\r
+                       float width = (float)width_/(float)screenWidth_;\r
+                       float height = (float)height_/(float)screenHeight_;\r
+\r
+                       return std::make_pair(width, height);\r
+               }\r
+\r
+               std::pair<float, float> Uniform()\r
+               {\r
+                       float aspect = (float)width_/(float)height_;\r
+                       float width = min(1.0f, (float)screenHeight_*aspect/(float)screenWidth_);\r
+                       float height = (float)(screenWidth_*width)/(float)(screenHeight_*aspect);\r
+\r
+                       return std::make_pair(width, height);\r
+               }\r
+\r
+               std::pair<float, float> Fill()\r
+               {\r
+                       return std::make_pair(1.0f, 1.0f);\r
+               }\r
+\r
+               std::pair<float, float> UniformToFill()\r
+               {\r
+                       float aspect = (float)width_/(float)height_;\r
+\r
+                       float wr = (float)width_/(float)screenWidth_;\r
+                       float hr = (float)height_/(float)screenHeight_;\r
+                       float r_inv = 1.0f/min(wr, hr);\r
+\r
+                       float width = wr*r_inv;\r
+                       float height = hr*r_inv;\r
+\r
+                       return std::make_pair(width, height);\r
+               }\r
+\r
+               void Render(unsigned char* data)\r
+               {                                       \r
+                       // RENDER\r
+\r
+                       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);\r
+                       glClearColor(0.0f, 0.0f, 0.0f, 0.0f);\r
+                       glLoadIdentity();\r
+       \r
+                       glBindTexture(GL_TEXTURE_2D, texture_);\r
+                       glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbos_[pboIndex_]);\r
+       \r
+                       glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width_, height_, GL_BGRA, GL_UNSIGNED_BYTE, 0);\r
+\r
+                       if(!firstFrame_)\r
+                               glCallList(dlist_);             \r
+\r
+                       // UPDATE\r
+\r
+                       int nextPboIndex = pboIndex_ ^ 1;\r
+\r
+                       glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbos_[nextPboIndex]);\r
+                       glBufferData(GL_PIXEL_UNPACK_BUFFER, size_, NULL, GL_STREAM_DRAW);\r
+                       GLubyte* ptr = (GLubyte*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);\r
+\r
+                       if(ptr != NULL)                 \r
+                       {\r
+                               memcpy(ptr, data, size_);                               \r
+                               glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);\r
+                       }\r
+\r
+                       // SWAP\r
+\r
+                       pboIndex_ = nextPboIndex;\r
+                       SwapBuffers(hDC);\r
+\r
+                       if(firstFrame_)\r
+                       {\r
+                               firstFrame_ = false;\r
+                               Render(data);\r
+                       }\r
+               }\r
+       \r
+               int screenWidth_;\r
+               int screenHeight_;\r
+\r
+               bool firstFrame_;\r
+\r
+               GLuint dlist_;\r
+               GLuint texture_;\r
+\r
+               int width_;\r
+               int height_;\r
+               int size_;\r
+\r
+               HDC       hDC;\r
+               HGLRC hRC;\r
+               \r
+               Stretch stretch_;\r
+               GLuint pbos_[2];\r
+               int pboIndex_;\r
+       };\r
+\r
+       typedef std::tr1::shared_ptr<OGLDevice> OGLDevicePtr;\r
+\r
+       struct OGLPlaybackStrategy: public IFramePlaybackStrategy\r
+       {\r
+               OGLPlaybackStrategy(Implementation* pConsumerImpl) : pConsumerImpl_(pConsumerImpl), lastTime_(timeGetTime()), lastFrameCount_(0)\r
+               {}\r
+\r
+               FrameManagerPtr GetFrameManager()\r
+               {\r
+                       return pConsumerImpl_->pFrameManager_;\r
+               }       \r
+               FramePtr GetReservedFrame()\r
+               {\r
+                       return pConsumerImpl_->pFrameManager_->CreateFrame();\r
+               }\r
+\r
+               void DisplayFrame(Frame* pFrame)\r
+               {\r
+                       DWORD timediff = timeGetTime() - lastTime_;\r
+                       if(timediff < 35)\r
+                               Sleep(40 - timediff);\r
+                       lastTime_ = timeGetTime();\r
+\r
+                       // Check if frame is valid and if it has already been rendered\r
+                       if(pFrame == NULL || (pFrame->ID() == lastFrameID_ && lastFrameCount_ > 1)) // Potential problem is that if the HDC is invalidated by external application it will stay that way, (R.N), keep or remove?\r
+                               return;         \r
+\r
+                       lastFrameCount_ = pFrame->ID() == lastFrameID_ ? ++lastFrameCount_ : 0; // Cant stop rendering until 2 frames are pushed due to doublebuffering\r
+\r
+                       if(!pOGLDevice_)\r
+                       {\r
+                               pOGLDevice_.reset(new OGLDevice(pConsumerImpl_->hWnd_, pConsumerImpl_->stretch_, pConsumerImpl_->screenWidth_, pConsumerImpl_->screenHeight_));\r
+                               pOGLDevice_->ReSizeGLScene(pConsumerImpl_->fmtDesc_.width, pConsumerImpl_->fmtDesc_.height);\r
+                       }\r
+\r
+                       pOGLDevice_->Render(pFrame->GetDataPtr());\r
+\r
+                       lastFrameID_ = pFrame->ID();\r
+               }\r
+\r
+               int lastFrameCount_;\r
+               utils::ID lastFrameID_;\r
+               OGLDevicePtr pOGLDevice_;\r
+               Implementation* pConsumerImpl_;\r
+               DWORD lastTime_;        \r
+       };\r
+       \r
+       Implementation(HWND hWnd, const FrameFormatDescription& fmtDesc, unsigned int screenIndex, Stretch stretch) \r
+               : hWnd_(hWnd), fmtDesc_(fmtDesc), pFrameManager_(new SystemFrameManager(fmtDesc_)), stretch_(stretch), screenIndex_(screenIndex)\r
+       {\r
+               bool succeeded = SetupDevice();\r
+               assert(succeeded);\r
+       }\r
+\r
+       ~Implementation()\r
+       {\r
+               bool succeeded = ReleaseDevice();\r
+               assert(succeeded);\r
+       }\r
+\r
+       bool SetupDevice()\r
+       {\r
+               DISPLAY_DEVICE dDevice;                 \r
+               memset(&dDevice,0,sizeof(dDevice));\r
+               dDevice.cb = sizeof(dDevice);\r
+\r
+               std::vector<DISPLAY_DEVICE> displayDevices;\r
+               for(int n = 0; EnumDisplayDevices(NULL, n, &dDevice, NULL); ++n)\r
+               {\r
+                       displayDevices.push_back(dDevice);\r
+                       memset(&dDevice,0,sizeof(dDevice));\r
+                       dDevice.cb = sizeof(dDevice);\r
+               }\r
+\r
+               if(screenIndex_ >= displayDevices.size())\r
+                       return false;\r
+               \r
+               if(!GetWindowRect(hWnd_, &prevRect_))\r
+                       throw std::exception("Failed to get Window Rectangle.");\r
+\r
+               DEVMODE devmode;\r
+               memset(&devmode,0,sizeof(devmode));\r
+               \r
+               if(!EnumDisplaySettings(displayDevices[screenIndex_].DeviceName, ENUM_CURRENT_SETTINGS, &devmode))\r
+               {\r
+                       std::stringstream msg;\r
+                       msg << "Failed to enumerate Display Settings for DisplayDevice " << screenIndex_ << ".";\r
+                       throw std::exception(msg.str().c_str());\r
+               }\r
+\r
+               prevMode_ = devmode;\r
+\r
+               screenWidth_ = devmode.dmPelsWidth;\r
+               screenHeight_ = devmode.dmPelsHeight;\r
+\r
+               ChangeDisplaySettings(&devmode, CDS_FULLSCREEN);\r
+\r
+               //if(result != DISP_CHANGE_SUCCESSFUL)\r
+               //      throw std::exception("Failed to change Display Settings.");\r
+\r
+               prevStyle_   = GetWindowLong(hWnd_, GWL_STYLE);\r
+               prevExStyle_ = GetWindowLong(hWnd_, GWL_EXSTYLE);\r
+       \r
+               if(!(SetWindowLong(hWnd_, GWL_STYLE, WS_POPUP) && SetWindowLong(hWnd_, GWL_EXSTYLE, WS_EX_APPWINDOW | WS_EX_TOPMOST)))\r
+                       throw std::exception("Failed to change window style.");\r
+\r
+               if(!MoveWindow(hWnd_, devmode.dmPosition.x, devmode.dmPosition.y, screenWidth_, screenHeight_, TRUE))\r
+                       throw std::exception("Failed to move window to display device.");\r
+\r
+               ShowWindow(hWnd_,SW_SHOW);                                              // Show The Window\r
+               SetForegroundWindow(hWnd_);                                             // Slightly Higher Priority\r
+               \r
+\r
+               pPlaybackControl_.reset(new FramePlaybackControl(FramePlaybackStrategyPtr(new OGLPlaybackStrategy(this))));\r
+               pPlaybackControl_->Start();\r
+\r
+               LOG << TEXT("OGL INFO: Successfully initialized device ");\r
+               return true;\r
+       }\r
+\r
+       bool ReleaseDevice()\r
+       {\r
+               pPlaybackControl_->Stop();\r
+               pPlaybackControl_.reset();\r
+\r
+               SetWindowLong(hWnd_, GWL_STYLE, prevStyle_);\r
+               SetWindowLong(hWnd_, GWL_EXSTYLE, prevExStyle_);\r
+\r
+               ChangeDisplaySettings(&prevMode_, 0);\r
+\r
+               MoveWindow(hWnd_, prevRect_.bottom, prevRect_.left, (prevRect_.right - prevRect_.left), (prevRect_.top-prevRect_.bottom), TRUE);\r
+               \r
+               LOG << TEXT("OGL INFO: Successfully released device ") << utils::LogStream::Flush;\r
+               return true;\r
+       }\r
+\r
+       unsigned int screenIndex_;\r
+       int screenWidth_;\r
+       int screenHeight_;\r
+       \r
+       DEVMODE prevMode_;\r
+       RECT  prevRect_;\r
+       DWORD prevExStyle_;\r
+       DWORD prevStyle_;\r
+\r
+       Stretch stretch_;\r
+       FrameFormatDescription fmtDesc_;\r
+       HWND hWnd_;\r
+       SystemFrameManagerPtr pFrameManager_;\r
+       FramePlaybackControlPtr pPlaybackControl_;      \r
+};\r
+\r
+OGLVideoConsumer::OGLVideoConsumer(HWND hWnd, const FrameFormatDescription& fmtDesc, unsigned int screenIndex, Stretch stretch)\r
+: pImpl_(new Implementation(hWnd, fmtDesc, screenIndex, stretch))\r
+{\r
+}\r
+\r
+OGLVideoConsumer::~OGLVideoConsumer(void)\r
+{\r
+}\r
+\r
+IPlaybackControl* OGLVideoConsumer::GetPlaybackControl() const\r
+{\r
+       return pImpl_->pPlaybackControl_.get();\r
+}\r
+\r
+void OGLVideoConsumer::EnableVideoOutput(){}\r
+\r
+void OGLVideoConsumer::DisableVideoOutput(){}\r
+\r
+bool OGLVideoConsumer::SetupDevice(unsigned int deviceIndex)\r
+{\r
+       return pImpl_->SetupDevice();\r
+}\r
+\r
+bool OGLVideoConsumer::ReleaseDevice()\r
+{\r
+       return pImpl_->ReleaseDevice();\r
+}\r
+\r
+const TCHAR* OGLVideoConsumer::GetFormatDescription() const\r
+{\r
+       return pImpl_->fmtDesc_.name;\r
+}\r
+\r
+}\r
+}
\ No newline at end of file
diff --git a/server/consumers/OGL/OGLVideoConsumer.h b/server/consumers/OGL/OGLVideoConsumer.h
new file mode 100644 (file)
index 0000000..5a9267c
--- /dev/null
@@ -0,0 +1,69 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _OGL_CONSUMER_H_\r
+#define _OGL_CONSUMER_H_\r
+\r
+#include "..\..\VideoConsumer.h"\r
+#include "..\..\MediaProducer.h"\r
+#include "..\..\frame\BitmapFrameManager.h"\r
+\r
+#include "..\..\utils\thread.h"\r
+#include "..\..\utils\lockable.h"\r
+\r
+#include <memory>\r
+\r
+namespace caspar {\r
+namespace ogl {\r
+\r
+enum Stretch\r
+{\r
+       None,\r
+       Uniform,\r
+       Fill,\r
+       UniformToFill\r
+};\r
+\r
+class OGLVideoConsumer : public IVideoConsumer, private utils::LockableObject\r
+{\r
+public:\r
+\r
+       OGLVideoConsumer(HWND hWnd, const FrameFormatDescription& fmtDesc, unsigned int screenIndex = 0, Stretch stretch = Fill);\r
+       ~OGLVideoConsumer(void);\r
+       \r
+       IPlaybackControl* GetPlaybackControl() const;\r
+       void EnableVideoOutput();\r
+       void DisableVideoOutput();\r
+       bool SetupDevice(unsigned int deviceIndex);\r
+       bool ReleaseDevice();\r
+       const TCHAR* GetFormatDescription() const;\r
+               \r
+private:\r
+       struct Implementation;\r
+       std::tr1::shared_ptr<Implementation> pImpl_;\r
+};\r
+\r
+typedef std::tr1::shared_ptr<OGLVideoConsumer> OGLVideoConsumerPtr;\r
+\r
+\r
+}\r
+}\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/consumers/bluefish/BlueFishVideoConsumer.cpp b/server/consumers/bluefish/BlueFishVideoConsumer.cpp
new file mode 100644 (file)
index 0000000..c945af2
--- /dev/null
@@ -0,0 +1,526 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\..\StdAfx.h"\r
+\r
+#include <BlueVelvet4.h>\r
+#include "..\..\application.h"\r
+#include "BlueFishVideoConsumer.h"\r
+#include "..\..\frame\FramePlaybackControl.h"\r
+#include "BluefishPlaybackStrategy.h"\r
+\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+\r
+namespace caspar {\r
+namespace bluefish {\r
+\r
+///////////////////////////////////////////\r
+// BlueFishVideoConsumer::EnumerateDevices\r
+// RETURNS: Number of identified bluefish-cards\r
+int BlueFishVideoConsumer::EnumerateDevices()\r
+{\r
+       LOG << TEXT("Bluefish SDK version: ") << BlueVelvetVersion();\r
+       BlueVelvetPtr pSDK(BlueVelvetFactory4());\r
+\r
+       if(pSDK != 0) {\r
+               int deviceCount = 0;\r
+               pSDK->device_enumerate(deviceCount);\r
+               return deviceCount;\r
+       }\r
+       else\r
+               return 0;\r
+}\r
+\r
+\r
+///////////////////////////////////////////\r
+// BlueFishVideoConsumer::Create\r
+// PARAMS: deviceIndex(index of the card that is to be wrapped in a consumer)\r
+// RETURNS: a new BlueFishVideoConsumer-object for the specified card\r
+// COMMENT: Creates and initializes a consumer that outputs video to a bluefish-card\r
+VideoConsumerPtr BlueFishVideoConsumer::Create(unsigned int deviceIndex)\r
+{\r
+       BlueFishVideoConsumerPtr card(new BlueFishVideoConsumer());\r
+       if(card != 0 && card->SetupDevice(deviceIndex) == false)\r
+               card.reset();\r
+\r
+       return card;\r
+}\r
+\r
+////////////////////////////////////////\r
+// BlueFishVideoConsumer constructor\r
+BlueFishVideoConsumer::BlueFishVideoConsumer() : pSDK_(BlueVelvetFactory4()), currentFormat_(FFormatPAL), _deviceIndex(0), hasEmbeddedAudio_(false)\r
+{}\r
+\r
+////////////////////////////////////////\r
+// BlueFishVideoConsumer destructor\r
+BlueFishVideoConsumer::~BlueFishVideoConsumer()\r
+{\r
+       ReleaseDevice();\r
+}\r
+\r
+/*******************/\r
+/**    METHODS    **/\r
+/*******************/\r
+\r
+IPlaybackControl* BlueFishVideoConsumer::GetPlaybackControl() const\r
+{\r
+       return pPlaybackControl_.get();\r
+}\r
+\r
+unsigned long BlueFishVideoConsumer::VidFmtFromFrameFormat(FrameFormat fmt) {\r
+       switch(fmt)\r
+       {\r
+       case FFormatPAL:\r
+               return VID_FMT_PAL;\r
+\r
+       case FFormatNTSC:\r
+               return VID_FMT_NTSC;\r
+\r
+       case FFormat576p2500:\r
+               return ULONG_MAX;       //not supported\r
+\r
+       case FFormat720p5000:\r
+               return VID_FMT_720P_5000;\r
+\r
+       case FFormat720p5994:\r
+               return VID_FMT_720P_5994;\r
+\r
+       case FFormat720p6000:\r
+               return VID_FMT_720P_6000;\r
+\r
+       case FFormat1080p2397:\r
+               return VID_FMT_1080P_2397;\r
+\r
+       case FFormat1080p2400:\r
+               return VID_FMT_1080P_2400;\r
+\r
+       case FFormat1080i5000:\r
+               return VID_FMT_1080I_5000;\r
+\r
+       case FFormat1080i5994:\r
+               return VID_FMT_1080I_5994;\r
+\r
+       case FFormat1080i6000:\r
+               return VID_FMT_1080I_6000;\r
+\r
+       case FFormat1080p2500:\r
+               return VID_FMT_1080P_2500;\r
+\r
+       case FFormat1080p2997:\r
+               return VID_FMT_1080P_2997;\r
+\r
+       case FFormat1080p3000:\r
+               return VID_FMT_1080P_3000;\r
+       }\r
+\r
+       return ULONG_MAX;\r
+}\r
+\r
+TCHAR* GetBluefishCardDesc(int cardType) {\r
+       switch(cardType) {\r
+       case CRD_BLUEDEEP_LT:           // D64 Lite\r
+               return TEXT("Deepblue LT");\r
+       case CRD_BLUEDEEP_SD:           // Iridium SD\r
+               return TEXT("Iridium SD");\r
+       case CRD_BLUEDEEP_AV:           // Iridium AV\r
+               return TEXT("Iridium AV");\r
+       case CRD_BLUEDEEP_IO:           // D64 Full\r
+               return TEXT("Deepblue IO");\r
+       case CRD_BLUEWILD_AV:           // D64 AV\r
+               return TEXT("Wildblue AV");\r
+       case CRD_IRIDIUM_HD:                    // * Iridium HD\r
+               return TEXT("Iridium HD");\r
+       case CRD_BLUEWILD_RT:           // D64 RT\r
+               return TEXT("Wildblue RT");\r
+       case CRD_BLUEWILD_HD:           // * BadAss G2\r
+               return TEXT("Wildblue HD");\r
+       case CRD_REDDEVIL:                      // Iridium Full\r
+               return TEXT("Iridium Full");\r
+       case CRD_BLUEDEEP_HD:           // * BadAss G2 variant, proposed, reserved\r
+       case CRD_BLUEDEEP_HDS:          // * BadAss G2 variant, proposed, reserved\r
+               return TEXT("Reserved for \"BasAss G2");\r
+       case CRD_BLUE_ENVY:                     // Mini Din \r
+               return TEXT("Blue envy");\r
+       case CRD_BLUE_PRIDE:                    //Mini Din Output \r
+               return TEXT("Blue pride");\r
+       case CRD_BLUE_GREED:\r
+               return TEXT("Blue greed");\r
+       case CRD_BLUE_INGEST:\r
+               return TEXT("Blue ingest");\r
+       case CRD_BLUE_SD_DUALLINK:\r
+               return TEXT("Blue SD duallink");\r
+       case CRD_BLUE_CATALYST:\r
+               return TEXT("Blue catalyst");\r
+       case CRD_BLUE_SD_DUALLINK_PRO:\r
+               return TEXT("Blue SD duallink pro");\r
+       case CRD_BLUE_SD_INGEST_PRO:\r
+               return TEXT("Blue SD ingest pro");\r
+       case CRD_BLUE_SD_DEEPBLUE_LITE_PRO:\r
+               return TEXT("Blue SD deepblue lite pro");\r
+       case CRD_BLUE_SD_SINGLELINK_PRO:\r
+               return TEXT("Blue SD singlelink pro");\r
+       case CRD_BLUE_SD_IRIDIUM_AV_PRO:\r
+               return TEXT("Blue SD iridium AV pro");\r
+       case CRD_BLUE_SD_FIDELITY:\r
+               return TEXT("Blue SD fidelity");\r
+       case CRD_BLUE_SD_FOCUS:\r
+               return TEXT("Blue SD focus");\r
+       case CRD_BLUE_SD_PRIME:\r
+               return TEXT("Blue SD prime");\r
+       case CRD_BLUE_EPOCH_2K_CORE:\r
+               return TEXT("Blue epoch 2k core");\r
+       case CRD_BLUE_EPOCH_2K_ULTRA:\r
+               return TEXT("Blue epoch 2k ultra");\r
+       case CRD_BLUE_EPOCH_HORIZON:\r
+               return TEXT("Blue epoch horizon");\r
+       case CRD_BLUE_EPOCH_CORE:\r
+               return TEXT("Blue epoch core");\r
+       case CRD_BLUE_EPOCH_ULTRA:\r
+               return TEXT("Blue epoch ultra");\r
+       case CRD_BLUE_CREATE_HD:\r
+               return TEXT("Blue create HD");\r
+       case CRD_BLUE_CREATE_2K:\r
+               return TEXT("Blue create 2k");\r
+       case CRD_BLUE_CREATE_2K_ULTRA:\r
+               return TEXT("Blue create 2k ultra");\r
+       default:\r
+               return TEXT("Unknown");\r
+       }\r
+}\r
+\r
+bool BlueFishVideoConsumer::SetupDevice(unsigned int deviceIndex)\r
+{\r
+       tstring strDesiredFrameFormat = caspar::GetApplication()->GetSetting(TEXT("videomode"));\r
+       return this->DoSetupDevice(deviceIndex, strDesiredFrameFormat);\r
+}\r
+\r
+/*\r
+// Original initialization code\r
+bool BlueFishVideoConsumer::DoSetupDevice(unsigned int deviceIndex, tstring strDesiredFrameFormat)\r
+{\r
+       _deviceIndex = deviceIndex;\r
+\r
+       unsigned long memFmt = MEM_FMT_ARGB_PC, updFmt = UPD_FMT_FRAME, vidFmt = VID_FMT_PAL, resFmt = RES_FMT_NORMAL;\r
+       unsigned long desiredVideoFormat = VID_FMT_PAL;\r
+       int iDummy;\r
+\r
+       int bufferIndex=0;      //Bufferindex used when initializing the buffers\r
+\r
+       if(strDesiredFrameFormat.size() == 0)\r
+               strDesiredFrameFormat = TEXT("PAL");\r
+\r
+       FrameFormat casparVideoFormat = caspar::GetVideoFormat(strDesiredFrameFormat);\r
+       desiredVideoFormat = BlueFishVideoConsumer::VidFmtFromFrameFormat(casparVideoFormat);\r
+       currentFormat_ = casparVideoFormat != FFormatInvalid ? casparVideoFormat : FFormatPAL;\r
+       if(desiredVideoFormat == ULONG_MAX) {\r
+               LOG << TEXT("BLUECARD ERROR: Unsupported videomode: ") << strDesiredFrameFormat << TEXT(". (device") << _deviceIndex << TEXT(")");\r
+               return false;\r
+       }\r
+\r
+       if(BLUE_FAIL(pSDK_->device_attach(_deviceIndex, FALSE))) {\r
+               LOG << TEXT("BLUECARD ERROR: Failed to attach device") << _deviceIndex;\r
+               return false;\r
+       }\r
+\r
+       if(desiredVideoFormat != VID_FMT_PAL) {\r
+               int videoModeCount = pSDK_->count_video_mode();\r
+               for(int videoModeIndex=1; videoModeIndex <= videoModeCount; ++videoModeIndex) {\r
+                       EVideoMode videoMode = pSDK_->enum_video_mode(videoModeIndex);\r
+                       if(videoMode == desiredVideoFormat) {\r
+                               vidFmt = videoMode;\r
+                       }\r
+               }\r
+       }\r
+\r
+       if(vidFmt == VID_FMT_PAL) {\r
+               strDesiredFrameFormat = TEXT("PAL");\r
+               currentFormat_ = FFormatPAL;\r
+       }\r
+\r
+       if(BLUE_FAIL(pSDK_->set_video_framestore_style(vidFmt, memFmt, updFmt, resFmt))) {\r
+               LOG << TEXT("BLUECARD ERROR: Failed to set videomode to ") << strDesiredFrameFormat << TEXT(". (device ") << _deviceIndex << TEXT(")");\r
+               return false;\r
+       }\r
+\r
+       LOG << TEXT("BLUECARD INFO: Successfully configured bluecard for ") << strDesiredFrameFormat << TEXT(". (device ") << _deviceIndex << TEXT(")");\r
+\r
+       if (pSDK_->has_output_key()) {\r
+               iDummy = TRUE;\r
+               int v4444 = FALSE, invert = FALSE, white = FALSE;\r
+               pSDK_->set_output_key(iDummy, v4444, invert, white);\r
+       }\r
+\r
+       if(pSDK_->GetHDCardType(_deviceIndex) != CRD_HD_INVALID) {\r
+               pSDK_->Set_DownConverterSignalType((vidFmt == VID_FMT_PAL) ? SD_SDI : HD_SDI);\r
+       }\r
+\r
+\r
+       iDummy = FALSE;\r
+       pSDK_->set_vertical_flip(iDummy);\r
+\r
+       // Get framestore parameters\r
+       if(BLUE_OK(pSDK_->render_buffer_sizeof(m_bufferCount, m_length, m_actual, m_golden))) {\r
+               LOG << TEXT("BLUECARD INFO: Buffers: ") << m_bufferCount << TEXT(", \"Length\": ") << m_length << TEXT(", Buffer size: ") << m_actual << TEXT(" (device ") << _deviceIndex << TEXT(")") << utils::LogStream::Flush;\r
+       }\r
+       else {\r
+               LOG << TEXT("BLUECARD ERROR: Failed to get framestore parameters (device ") << _deviceIndex << TEXT(")");\r
+       }\r
+\r
+       pFrameManager_ = BluefishFrameManagerPtr(new BluefishFrameManager(pSDK_, currentFormat_, m_golden));\r
+\r
+       iDummy = TRUE;\r
+       pSDK_->set_output_video(iDummy);\r
+\r
+       // Now specify video output buffer\r
+       pSDK_->render_buffer_update(0);\r
+\r
+       pPlaybackControl_.reset(new FramePlaybackControl(FramePlaybackStrategyPtr(new BluefishPlaybackStrategy(this))));\r
+       pPlaybackControl_->Start();\r
+\r
+       LOG << TEXT("BLUECARD INFO: Successfully initialized device ") << _deviceIndex;\r
+       return true;\r
+}\r
+*/\r
+\r
+//New, improved(?) initialization code. \r
+//Based on code sent from the bluefish-sdk support 2009-08-25. Email "RE: [sdk] Ang. RE: Issue with SD Lite Pro PCI-E"\r
+bool BlueFishVideoConsumer::DoSetupDevice(unsigned int deviceIndex, tstring strDesiredFrameFormat)\r
+{\r
+       _deviceIndex = deviceIndex;\r
+\r
+       unsigned long memFmt = MEM_FMT_ARGB_PC, updFmt = UPD_FMT_FRAME, vidFmt = VID_FMT_PAL, resFmt = RES_FMT_NORMAL, engineMode = VIDEO_ENGINE_FRAMESTORE;\r
+       unsigned long desiredVideoFormat = VID_FMT_PAL;\r
+       int iDummy;\r
+\r
+       int bufferIndex=0;      //Bufferindex used when initializing the buffers\r
+\r
+       if(BLUE_FAIL(pSDK_->device_attach(_deviceIndex, FALSE))) {\r
+               LOG << TEXT("BLUECARD ERROR: Failed to attach device. (device ") << _deviceIndex << TEXT(")");;\r
+               return false;\r
+       }\r
+\r
+       int videoCardType = pSDK_->has_video_cardtype();\r
+       LOG << TEXT("BLUECARD INFO: Card type: ") << GetBluefishCardDesc(videoCardType) << TEXT(". (device ") << _deviceIndex << TEXT(")");;\r
+\r
+       if(strDesiredFrameFormat.size() == 0)\r
+               strDesiredFrameFormat = TEXT("PAL");\r
+\r
+       FrameFormat casparVideoFormat = caspar::GetVideoFormat(strDesiredFrameFormat);\r
+       desiredVideoFormat = BlueFishVideoConsumer::VidFmtFromFrameFormat(casparVideoFormat);\r
+       currentFormat_ = casparVideoFormat != FFormatInvalid ? casparVideoFormat : FFormatPAL;\r
+       if(desiredVideoFormat == ULONG_MAX) {\r
+               LOG << TEXT("BLUECARD ERROR: Unsupported videomode: ") << strDesiredFrameFormat << TEXT(". (device ") << _deviceIndex << TEXT(")");\r
+               return false;\r
+       }\r
+\r
+       if(desiredVideoFormat != VID_FMT_PAL) {\r
+               int videoModeCount = pSDK_->count_video_mode();\r
+               for(int videoModeIndex=1; videoModeIndex <= videoModeCount; ++videoModeIndex) {\r
+                       EVideoMode videoMode = pSDK_->enum_video_mode(videoModeIndex);\r
+                       if(videoMode == desiredVideoFormat) {\r
+                               vidFmt = videoMode;\r
+                       }\r
+               }\r
+       }\r
+\r
+       if(vidFmt != desiredVideoFormat) {\r
+               LOG << TEXT("BLUECARD ERROR: Failed to set desired videomode: ") << strDesiredFrameFormat << TEXT(". (device ") << _deviceIndex << TEXT(")");\r
+       }\r
+\r
+       if(vidFmt == VID_FMT_PAL) {\r
+               strDesiredFrameFormat = TEXT("PAL");\r
+               currentFormat_ = FFormatPAL;\r
+       }\r
+\r
+       DisableVideoOutput();\r
+\r
+       VARIANT value;\r
+       value.vt = VT_UI4;\r
+\r
+       //Enable dual link output\r
+       value.ulVal = 1;\r
+       if(!BLUE_PASS(pSDK_->SetCardProperty(VIDEO_DUAL_LINK_OUTPUT, value))) {\r
+               LOG << TEXT("BLUECARD ERROR: Failed to enable dual link. (device ") << _deviceIndex << TEXT(")");\r
+               return false;\r
+       }\r
+\r
+       value.ulVal = Signal_FormatType_4224;\r
+       if(!BLUE_PASS(pSDK_->SetCardProperty(VIDEO_DUAL_LINK_OUTPUT_SIGNAL_FORMAT_TYPE, value))) {\r
+               LOG << TEXT("BLUECARD ERROR: Failed to set dual link format type to 4:2:2:4. (device ") << _deviceIndex << TEXT(")");\r
+               return false;\r
+       }\r
+\r
+       //Setting output Video mode\r
+       value.ulVal = vidFmt;\r
+       if(!BLUE_PASS(pSDK_->SetCardProperty(VIDEO_MODE, value))) {\r
+               LOG << TEXT("BLUECARD ERROR: Failed to set videomode. (device ") << _deviceIndex << TEXT(")");\r
+               return false;\r
+       }\r
+\r
+       //Select Update Mode for output\r
+       value.ulVal = updFmt;\r
+       if(!BLUE_PASS(pSDK_->SetCardProperty(VIDEO_UPDATE_TYPE, value))) {\r
+               LOG << TEXT("BLUECARD ERROR: Failed to set update type. (device ") << _deviceIndex << TEXT(")");\r
+               return false;\r
+       }\r
+       \r
+       //Select output memory format\r
+       value.ulVal = memFmt;\r
+       if(!BLUE_PASS(pSDK_->SetCardProperty(VIDEO_MEMORY_FORMAT, value))) {\r
+               LOG << TEXT("BLUECARD ERROR: Failed to set memory format. (device ") << _deviceIndex << TEXT(")");\r
+               return false;\r
+       }\r
+\r
+       //SELECT IMAGE ORIENTATION\r
+       value.ulVal = ImageOrientation_Normal;\r
+       if(!BLUE_PASS(pSDK_->SetCardProperty(VIDEO_IMAGE_ORIENTATION, value))) {\r
+               LOG << TEXT("BLUECARD ERROR: Failed to set image orientation to normal. (device ") << _deviceIndex << TEXT(")");\r
+       }\r
+\r
+       value.ulVal = CGR_RANGE;\r
+       if(!BLUE_PASS(pSDK_->SetCardProperty(VIDEO_RGB_DATA_RANGE, value))) {\r
+               LOG << TEXT("BLUECARD ERROR: Failed to set RGB data range to CGR. (device ") << _deviceIndex << TEXT(")");\r
+       }\r
+\r
+       value.ulVal = MATRIX_709_CGR;\r
+       if(vidFmt == VID_FMT_PAL) {\r
+               value.ulVal = MATRIX_601_CGR;\r
+       }\r
+       if(!BLUE_PASS(pSDK_->SetCardProperty(VIDEO_PREDEFINED_COLOR_MATRIX, value))) {\r
+               LOG << TEXT("BLUECARD ERROR: Failed to set colormatrix to ") << (vidFmt == VID_FMT_PAL ? TEXT("601 CGR") : TEXT("709 CGR")) << TEXT(". (device ") << _deviceIndex << TEXT(")");\r
+       }\r
+       \r
+\r
+       //Disable embedded audio\r
+       value.ulVal = 1;\r
+       if(!BLUE_PASS(pSDK_->SetCardProperty(EMBEDDED_AUDIO_OUTPUT, value))) {\r
+               LOG << TEXT("BLUECARD ERROR: Failed to enable embedded audio. (device ") << _deviceIndex << TEXT(")");\r
+       }\r
+       else {\r
+               LOG << TEXT("BLUECARD INFO: Enabled embedded audio. (device ") << _deviceIndex << TEXT(")");\r
+               hasEmbeddedAudio_ = true;\r
+       }\r
+\r
+       LOG << TEXT("BLUECARD INFO: Successfully configured bluecard for ") << strDesiredFrameFormat << TEXT(". (device ") << _deviceIndex << TEXT(")");\r
+\r
+       if (pSDK_->has_output_key()) {\r
+               iDummy = TRUE;\r
+               int v4444 = FALSE, invert = FALSE, white = FALSE;\r
+               pSDK_->set_output_key(iDummy, v4444, invert, white);\r
+       }\r
+\r
+       if(pSDK_->GetHDCardType(_deviceIndex) != CRD_HD_INVALID) {\r
+               pSDK_->Set_DownConverterSignalType((vidFmt == VID_FMT_PAL) ? SD_SDI : HD_SDI);\r
+       }\r
+\r
+       ULONG videoGolden = BlueVelvetGolden(vidFmt, memFmt, updFmt);\r
+\r
+       pFrameManager_ = BluefishFrameManagerPtr(new BluefishFrameManager(pSDK_, currentFormat_, videoGolden));\r
+\r
+       pPlaybackControl_.reset(new FramePlaybackControl(FramePlaybackStrategyPtr(new BluefishPlaybackStrategy(this))));\r
+       pPlaybackControl_->Start();\r
+\r
+       if(BLUE_FAIL(pSDK_->set_video_engine(engineMode))) {\r
+               LOG << TEXT("BLUECARD ERROR: Failed to set vido engine. (device ") << _deviceIndex << TEXT(")");\r
+               return false;\r
+       }\r
+\r
+       EnableVideoOutput();\r
+\r
+       LOG << TEXT("BLUECARD INFO: Successfully initialized device ") << _deviceIndex;\r
+       return true;\r
+}\r
+\r
+bool BlueFishVideoConsumer::ReleaseDevice()\r
+{\r
+       pPlaybackControl_.reset();\r
+\r
+       pFrameManager_.reset();\r
+       DisableVideoOutput();\r
+\r
+       if(pSDK_) {\r
+               pSDK_->device_detach();\r
+       }\r
+\r
+       LOG << TEXT("BLUECARD INFO: Successfully released device ") << _deviceIndex;\r
+       return true;\r
+}\r
+\r
+void BlueFishVideoConsumer::EnableVideoOutput()\r
+{\r
+       //Need sync. protection?\r
+       if(pSDK_)\r
+       {\r
+               VARIANT value;\r
+               value.vt = VT_UI4;\r
+\r
+               //Deactivate channel\r
+               value.ulVal = 0;\r
+               if(!BLUE_PASS(pSDK_->SetCardProperty(VIDEO_BLACKGENERATOR, value))) {\r
+                       LOG << TEXT("BLUECARD ERROR: Failed to disable video output. (device ") << _deviceIndex << TEXT(")");\r
+               }\r
+       }\r
+}\r
+\r
+void BlueFishVideoConsumer::DisableVideoOutput()\r
+{\r
+       //Need sync. protection?\r
+       if(pSDK_)\r
+       {\r
+               VARIANT value;\r
+               value.vt = VT_UI4;\r
+\r
+               //Deactivate channel\r
+               value.ulVal = 1;\r
+               if(!BLUE_PASS(pSDK_->SetCardProperty(VIDEO_BLACKGENERATOR, value))) {\r
+                       LOG << TEXT("BLUECARD ERROR: Failed to disable video output. (device ") << _deviceIndex << TEXT(")");\r
+               }\r
+       }\r
+}\r
+\r
+\r
+bool BlueFishVideoConsumer::SetVideoFormat(const tstring& strDesiredFrameFormat)\r
+{\r
+       tstring prevFrameFormat = this->GetFormatDescription();\r
+\r
+       unsigned long desiredVideoFormat = BlueFishVideoConsumer::VidFmtFromFrameFormat(caspar::GetVideoFormat(strDesiredFrameFormat));\r
+       if(desiredVideoFormat == ULONG_MAX)\r
+       {\r
+               LOG << TEXT("BLUECARD INFO: Unsupported video format. Ignored ") << strDesiredFrameFormat;\r
+               return false;\r
+       }\r
+\r
+       this->ReleaseDevice();\r
+       \r
+       if(!this->DoSetupDevice(this->_deviceIndex, strDesiredFrameFormat))\r
+       {       \r
+               LOG << TEXT("BLUECARD ERROR: Failed to set video format. Trying to revert to previous format ") << prevFrameFormat;\r
+               this->DoSetupDevice(this->_deviceIndex, prevFrameFormat);\r
+               return false;\r
+       }\r
+\r
+       LOG << TEXT("BLUECARD INFO: Successfully set video format ") << strDesiredFrameFormat;\r
+\r
+       return true;\r
+}\r
+\r
+}      //namespace bluefish\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/consumers/bluefish/BlueFishVideoConsumer.h b/server/consumers/bluefish/BlueFishVideoConsumer.h
new file mode 100644 (file)
index 0000000..cc63e3b
--- /dev/null
@@ -0,0 +1,93 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _CASPAR_BLUEFISHVIDEOCONSUMER_H__\r
+#define _CASPAR_BLUEFISHVIDEOCONSUMER_H__\r
+\r
+#pragma once\r
+\r
+#include "..\..\utils\thread.h"\r
+#include "BluefishException.h"\r
+#include "BluefishFrameManager.h"\r
+#include "..\..\VideoConsumer.h"\r
+\r
+#define TIMEOUT                        1000\r
+\r
+class CBlueVelvet4;\r
+\r
+namespace caspar {\r
+\r
+class FramePlaybackControl;\r
+typedef std::tr1::shared_ptr<FramePlaybackControl> FramePlaybackControlPtr;\r
+\r
+namespace bluefish {\r
+\r
+typedef std::tr1::shared_ptr<CBlueVelvet4> BlueVelvetPtr;\r
+\r
+class BlueFishVideoConsumer : public IVideoConsumer\r
+{\r
+       friend class BluefishPlaybackStrategy;\r
+\r
+       BlueFishVideoConsumer();\r
+       BlueFishVideoConsumer(const BlueFishVideoConsumer&);\r
+       const BlueFishVideoConsumer& operator=(const BlueFishVideoConsumer&);\r
+\r
+public:\r
+       virtual ~BlueFishVideoConsumer();\r
+\r
+       static int EnumerateDevices();\r
+       static VideoConsumerPtr Create(unsigned int deviceIndex);\r
+\r
+       virtual IPlaybackControl* GetPlaybackControl() const;\r
+\r
+       void EnableVideoOutput();\r
+       void DisableVideoOutput();\r
+       bool SetupDevice(unsigned int deviceIndex);\r
+       bool ReleaseDevice();\r
+       const TCHAR* GetFormatDescription() const {\r
+               return FrameFormatDescription::FormatDescriptions[currentFormat_].name;\r
+       }\r
+       bool SetVideoFormat(const tstring& strDesiredFrameFormat);\r
+\r
+private:\r
+\r
+       bool DoSetupDevice(unsigned int deviceIndex, tstring strDesiredFrameFormat);\r
+\r
+       BlueVelvetPtr pSDK_;\r
+       FramePlaybackControlPtr pPlaybackControl_;\r
+       BluefishFrameManagerPtr pFrameManager_;\r
+       unsigned long m_bufferCount;\r
+       unsigned long m_length;\r
+       unsigned long m_actual;\r
+       unsigned long m_golden;\r
+\r
+       unsigned long VidFmtFromFrameFormat(FrameFormat fmt);\r
+\r
+       FrameFormat currentFormat_;\r
+       unsigned int _deviceIndex;\r
+       bool hasEmbeddedAudio_;\r
+};\r
+typedef std::tr1::shared_ptr<BlueFishVideoConsumer> BlueFishVideoConsumerPtr;\r
+\r
+}      //namespace bluefish\r
+}      //namespace caspar\r
+\r
+\r
+#endif //_CASPAR_BLUEFISHVIDEOCONSUMER_H__\r
diff --git a/server/consumers/bluefish/BluefishException.h b/server/consumers/bluefish/BluefishException.h
new file mode 100644 (file)
index 0000000..4ea18eb
--- /dev/null
@@ -0,0 +1,39 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _CASPAR_BLUEFISHEXCEPTION_H__\r
+#define _CASPAR_BLUEFISHEXCEPTION_H__\r
+\r
+#include <exception>\r
+\r
+namespace caspar {\r
+namespace bluefish {\r
+\r
+class BluefishException : public std::exception\r
+{\r
+public:\r
+       explicit BluefishException(const char* msg) : std::exception(msg) {}\r
+       ~BluefishException() {}\r
+};\r
+\r
+}      //namespace bluefish\r
+}      //namespace caspar\r
+\r
+#endif //_CASPAR_BLUEFISHEXCEPTION_H__
\ No newline at end of file
diff --git a/server/consumers/bluefish/BluefishFrameManager.cpp b/server/consumers/bluefish/BluefishFrameManager.cpp
new file mode 100644 (file)
index 0000000..01d0053
--- /dev/null
@@ -0,0 +1,180 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\..\StdAfx.h"\r
+\r
+#include <BlueVelvet4.h>\r
+#include "..\..\utils\Process.h"\r
+#include "BluefishFrameManager.h"\r
+\r
+#define        BUFFER_ID_USER_BASE             (6)\r
+\r
+namespace caspar {\r
+namespace bluefish {\r
+\r
+//////////////////////\r
+// CardFrameInfo\r
+//\r
+CardFrameInfo::CardFrameInfo(BlueVelvetPtr pSDK, int dataSize, int bufferID) : pSDK_(pSDK), dataSize_(dataSize), pData_(0), bufferID_(bufferID)\r
+{\r
+       if(BLUE_FAIL(pSDK->system_buffer_map(reinterpret_cast<void**>(&pData_), bufferID)))\r
+       {\r
+               throw BluefishException("Failed to map buffer");\r
+       }\r
+}\r
+\r
+CardFrameInfo::~CardFrameInfo()\r
+{\r
+       try\r
+       {\r
+               if(pSDK_ != 0 && pData_ != 0)\r
+                       pSDK_->system_buffer_unmap(pData_);\r
+       }\r
+       catch(...) {}\r
+}\r
+\r
+\r
+//////////////////////\r
+// SystemFrameInfo\r
+//\r
+SystemFrameInfo::SystemFrameInfo(int dataSize, int bufferID) : dataSize_(dataSize), pData_(0), bufferID_(bufferID)\r
+{\r
+       pData_ = static_cast<unsigned char*>(::VirtualAlloc(NULL, dataSize_, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE));\r
+       if(pData_ == 0)\r
+       {\r
+               throw BluefishException("Failed to allocate memory for frame");\r
+       }\r
+       if(::VirtualLock(pData_, dataSize_) == 0)\r
+       {\r
+               throw BluefishException("Failed to lock memory for frame");\r
+       }\r
+}\r
+\r
+SystemFrameInfo::~SystemFrameInfo()\r
+{\r
+       try\r
+       {\r
+               if(pData_ != 0)\r
+                       ::VirtualFree(pData_, 0, MEM_RELEASE);\r
+       }\r
+       catch(...) {}\r
+}\r
+\r
+////////////////////////\r
+// BluefishVideoFrame\r
+//\r
+BluefishVideoFrame::BluefishVideoFrame(BluefishFrameManager* pFrameManager) : pFrameManager_(pFrameManager)\r
+{\r
+       if(pFrameManager_ != 0)\r
+       {\r
+               factoryID_ = pFrameManager_->ID();\r
+               pInfo_ = pFrameManager_->GetBuffer();\r
+       }\r
+}\r
+\r
+BluefishVideoFrame::~BluefishVideoFrame()\r
+{\r
+       if(pFrameManager_ != 0 && pInfo_ != 0)\r
+               pFrameManager_->ReturnBuffer(pInfo_);\r
+}\r
+\r
+//////////////////////////////\r
+// BluefishVideoFrameFactory\r
+//\r
+BluefishFrameManager::BluefishFrameManager(BlueVelvetPtr pSDK, FrameFormat fmt, unsigned long optimalLength) : pSDK_(pSDK), format_(fmt)\r
+{\r
+       const FrameFormatDescription& fmtDesc = FrameFormatDescription::FormatDescriptions[fmt];\r
+       pBackupFrameManager_.reset(new SystemFrameManager(fmtDesc));\r
+\r
+       SIZE_T workingSetMinSize = 0, workingSetMaxSize = 0;\r
+       if(utils::Process::GetCurrentProcess().GetWorkingSetSize(workingSetMinSize, workingSetMaxSize))\r
+       {\r
+               LOG << utils::LogLevel::Debug << TEXT("WorkingSet size: min = ") << workingSetMinSize << TEXT(", max = ") << workingSetMaxSize;\r
+               \r
+               workingSetMinSize += optimalLength * 6;\r
+               workingSetMaxSize += optimalLength * 6;\r
+\r
+               if(!utils::Process::GetCurrentProcess().SetWorkingSetSize(workingSetMinSize, workingSetMaxSize))\r
+               {\r
+                       LOG << utils::LogLevel::Critical << TEXT("Failed to set workingset: min = ") << workingSetMinSize << TEXT(", max = ") << workingSetMaxSize;\r
+               }\r
+       }\r
+\r
+       //for(int cardBufferIndex = 0; cardBufferIndex < 4; ++cardBufferIndex)\r
+       //{\r
+       //      frameBuffers_.push_back(VideoFrameInfoPtr(new CardFrameInfo(pSDK, optimalLength, BUFFER_ID_VIDEO0 + cardBufferIndex)));\r
+       //}\r
+       for(int systemBufferIndex = 0; systemBufferIndex < 6; ++systemBufferIndex)\r
+       {\r
+               frameBuffers_.push_back(VideoFrameInfoPtr(new SystemFrameInfo(optimalLength, BUFFER_ID_USER_BASE + systemBufferIndex)));\r
+       }\r
+\r
+       FrameInfoList::const_iterator it = frameBuffers_.begin();\r
+       FrameInfoList::const_iterator end = frameBuffers_.end();\r
+       for(; it != end; ++it)\r
+       {\r
+               if(BLUE_FAIL(pSDK_->system_buffer_assign((*it)->GetPtr(), (*it)->GetBufferID(), (*it)->GetDataSize(), BUFFER_TYPE_VIDEO)))\r
+               {\r
+                       throw BluefishException("Failed to assign buffer");\r
+               }\r
+       }\r
+}\r
+\r
+BluefishFrameManager::~BluefishFrameManager()\r
+{\r
+}\r
+\r
+FramePtr BluefishFrameManager::CreateFrame()\r
+{\r
+       FramePtr pBluefishFrame(new BluefishVideoFrame(this));\r
+       if(pBluefishFrame->HasValidDataPtr())\r
+               return pBluefishFrame;\r
+       else\r
+               return pBackupFrameManager_->CreateFrame();\r
+}\r
+\r
+const FrameFormatDescription& BluefishFrameManager::GetFrameFormatDescription() const\r
+{\r
+       return FrameFormatDescription::FormatDescriptions[format_];\r
+}\r
+\r
+VideoFrameInfoPtr BluefishFrameManager::GetBuffer()\r
+{\r
+       Lock lock(*this);\r
+       VideoFrameInfoPtr pInfo;\r
+\r
+       if(frameBuffers_.size() > 0)\r
+       {\r
+               pInfo = frameBuffers_.front();\r
+               frameBuffers_.pop_front();\r
+       }\r
+\r
+       return pInfo;\r
+}\r
+\r
+void BluefishFrameManager::ReturnBuffer(VideoFrameInfoPtr pInfo)\r
+{\r
+       Lock lock(*this);\r
+       if(pInfo != 0)\r
+               frameBuffers_.push_back(pInfo);\r
+}\r
+\r
+}      //namespace bluefish\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/consumers/bluefish/BluefishFrameManager.h b/server/consumers/bluefish/BluefishFrameManager.h
new file mode 100644 (file)
index 0000000..3f9daa8
--- /dev/null
@@ -0,0 +1,164 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _CASPAR_BLUEFISHVIDEOFRAMEFACTORY_H__\r
+#define _CASPAR_BLUEFISHVIDEOFRAMEFACTORY_H__\r
+\r
+#pragma once\r
+\r
+#include "..\..\utils\Lockable.h"\r
+#include "..\..\frame\FrameManager.h"\r
+#include "..\..\frame\SystemFrameManager.h"\r
+#include "..\..\frame\Frame.h"\r
+#include <list>\r
+#include <memory>\r
+#include "BluefishException.h"\r
+\r
+class CBlueVelvet4;\r
+\r
+namespace caspar {\r
+namespace bluefish {\r
+\r
+typedef std::tr1::shared_ptr<CBlueVelvet4> BlueVelvetPtr;\r
+\r
+class VideoFrameInfo\r
+{\r
+public:\r
+       VideoFrameInfo() {}\r
+       virtual ~VideoFrameInfo() {}\r
+\r
+       virtual unsigned char* GetPtr() const = 0;\r
+       virtual int GetBufferID() const = 0;\r
+       virtual int GetDataSize() const = 0;\r
+};\r
+typedef std::tr1::shared_ptr<VideoFrameInfo> VideoFrameInfoPtr;\r
+\r
+class CardFrameInfo : public VideoFrameInfo\r
+{\r
+public:\r
+       CardFrameInfo(BlueVelvetPtr pSDK, int dataSize, int bufferID);\r
+       ~CardFrameInfo();\r
+\r
+       unsigned char* GetPtr() const {\r
+               return pData_;\r
+       }\r
+       int GetBufferID() const {\r
+               return bufferID_;\r
+       }\r
+       int GetDataSize() const {\r
+               return dataSize_;\r
+       }\r
+\r
+private:\r
+       BlueVelvetPtr pSDK_;\r
+       unsigned char* pData_;\r
+       int bufferID_;\r
+       int dataSize_;\r
+};\r
+\r
+class SystemFrameInfo : public VideoFrameInfo\r
+{\r
+public:\r
+       SystemFrameInfo(int dataSize, int bufferID);\r
+       ~SystemFrameInfo();\r
+\r
+       unsigned char* GetPtr() const {\r
+               return pData_;\r
+       }\r
+       int GetBufferID() const {\r
+               return bufferID_;\r
+       }\r
+       int GetDataSize() const {\r
+               return dataSize_;\r
+       }\r
+\r
+private:\r
+       unsigned char* pData_;\r
+       int bufferID_;\r
+       int dataSize_;\r
+};\r
+\r
+class BluefishFrameManager : public FrameManager, private utils::LockableObject\r
+{\r
+       friend class BluefishVideoFrame;\r
+       typedef std::list<VideoFrameInfoPtr> FrameInfoList;\r
+\r
+       BluefishFrameManager(const BluefishFrameManager&);\r
+       const BluefishFrameManager& operator=(const BluefishFrameManager&);\r
+\r
+public:\r
+       BluefishFrameManager(BlueVelvetPtr pSDK, FrameFormat fmt, unsigned long optimalLength);\r
+       virtual ~BluefishFrameManager();\r
+\r
+       virtual FramePtr CreateFrame();\r
+       virtual const FrameFormatDescription& GetFrameFormatDescription() const;\r
+\r
+private:\r
+       VideoFrameInfoPtr GetBuffer();\r
+       void ReturnBuffer(VideoFrameInfoPtr);\r
+\r
+       BlueVelvetPtr pSDK_;\r
+       FrameFormat format_;\r
+       FrameInfoList frameBuffers_;\r
+       SystemFrameManagerPtr   pBackupFrameManager_;\r
+};\r
+typedef std::tr1::shared_ptr<BluefishFrameManager> BluefishFrameManagerPtr;\r
+\r
+\r
+class BluefishVideoFrame : public Frame\r
+{\r
+       friend class BluefishFrameManager;\r
+       explicit BluefishVideoFrame(BluefishFrameManager* pFrameManager);\r
+\r
+public:\r
+       virtual ~BluefishVideoFrame();\r
+\r
+       virtual unsigned char* GetDataPtr() const {\r
+               if(pInfo_ != 0) {\r
+                       HasVideo(true);\r
+                       return pInfo_->GetPtr();\r
+               }\r
+               return 0;\r
+       }\r
+       virtual bool HasValidDataPtr() const {\r
+               return (pInfo_ != 0 && pInfo_->GetPtr() != 0);\r
+       }\r
+\r
+       virtual unsigned int GetDataSize() const {\r
+               return (pInfo_ != 0) ? pInfo_->GetDataSize() : 0;\r
+       }\r
+       virtual FrameMetadata GetMetadata() const {\r
+               return (pInfo_ != 0) ? reinterpret_cast<FrameMetadata>(pInfo_->GetBufferID()) : 0;\r
+       }\r
+       const utils::ID& FactoryID() const {\r
+               return factoryID_;\r
+       }\r
+\r
+private:\r
+       VideoFrameInfoPtr pInfo_;\r
+       BluefishFrameManager* pFrameManager_;\r
+       utils::ID factoryID_;\r
+};\r
+\r
+\r
+}      //namespace bluefish\r
+}      //namespace caspar\r
+\r
+#endif //_CASPAR_BLUEFISHVIDEOFRAMEFACTORY_H__
\ No newline at end of file
diff --git a/server/consumers/bluefish/BluefishPlaybackStrategy.cpp b/server/consumers/bluefish/BluefishPlaybackStrategy.cpp
new file mode 100644 (file)
index 0000000..9826674
--- /dev/null
@@ -0,0 +1,144 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\..\StdAfx.h"\r
+\r
+#include "..\..\utils\image\Image.hpp"\r
+#include <BlueVelvet4.h>\r
+#include <BlueHancUtils.h>\r
+\r
+#include <vector>\r
+\r
+#include "BluefishPlaybackStrategy.h"\r
+#include "BluefishVideoConsumer.h"\r
+\r
+namespace caspar {\r
+namespace bluefish {\r
+\r
+using namespace caspar::utils;\r
+\r
+struct BluefishPlaybackStrategy::Implementation\r
+{\r
+       Implementation(BlueFishVideoConsumer* pConsumer) : pConsumer_(pConsumer), currentReservedFrameIndex_(0)\r
+       {\r
+               FramePtr pFrame = pConsumer->pFrameManager_->CreateFrame();\r
+               if(pFrame != 0 && pFrame->HasValidDataPtr())\r
+                       reservedFrames_.push_back(pFrame);\r
+               else {\r
+                       throw std::exception("Failed to reserve temporary bluefishframe");\r
+               }\r
+               pFrame.reset();\r
+\r
+               pFrame = pConsumer->pFrameManager_->CreateFrame();\r
+               if(pFrame != 0 && pFrame->HasValidDataPtr())\r
+                       reservedFrames_.push_back(pFrame);\r
+               else {\r
+                       throw std::exception("Failed to reserve temporary bluefishframe");\r
+               }\r
+\r
+               memset(&hancStreamInfo_, 0, sizeof(hancStreamInfo_));\r
+       }\r
+       FramePtr GetReservedFrame() {\r
+               FramePtr pFrame = reservedFrames_[currentReservedFrameIndex_];\r
+               currentReservedFrameIndex_ ^= 1;\r
+               return pFrame;\r
+       }\r
+       FrameManagerPtr GetFrameManager()\r
+       {\r
+               return pConsumer_->pFrameManager_;\r
+       }\r
+       void DisplayFrame(Frame* pFrame)\r
+       {\r
+               if(pFrame->HasValidDataPtr()) {\r
+                       if(GetFrameManager()->Owns(*pFrame)) {\r
+                               DoRender(pFrame);\r
+                       }\r
+                       else {\r
+                               FramePtr pTempFrame = reservedFrames_[currentReservedFrameIndex_];\r
+                               if(pFrame->GetDataSize() == pTempFrame->GetDataSize()) {\r
+                                       utils::image::Copy(pTempFrame->GetDataPtr(), pFrame->GetDataPtr(), pTempFrame->GetDataSize());\r
+                                       DoRender(pTempFrame.get());\r
+                               }\r
+\r
+                               currentReservedFrameIndex_ ^= 1;\r
+                       }\r
+               }\r
+               else {\r
+                       LOG << TEXT("BLUEFISH: Tried to render frame with no data");\r
+               }\r
+       }\r
+\r
+       void DoRender(Frame* pFrame) {\r
+               static bool doLog = true;\r
+               static int frameID = 0;\r
+               // video synch\r
+               unsigned long fieldCount = 0;\r
+               pConsumer_->pSDK_->wait_output_video_synch(UPD_FMT_FRAME, fieldCount);\r
+\r
+               // Host->PCI in_Frame buffer to the card buffer\r
+               pConsumer_->pSDK_->system_buffer_write_async(pFrame->GetDataPtr(), pFrame->GetDataSize(), 0, reinterpret_cast<long>(pFrame->GetMetadata()), 0);\r
+               if(BLUE_FAIL(pConsumer_->pSDK_->render_buffer_update(reinterpret_cast<long>(pFrame->GetMetadata())))) {\r
+               /*pConsumer_->pSDK_->system_buffer_write_async(pFrame->GetDataPtr(), pFrame->GetDataSize(), 0, frameID, 0);\r
+               if(BLUE_FAIL(pConsumer_->pSDK_->render_buffer_update(frameID))) {*/\r
+                       if(doLog) {\r
+                               LOG << TEXT("BLUEFISH: render_buffer_update failed");\r
+                               doLog = false;\r
+                       }\r
+               }\r
+               else\r
+                       doLog = true;\r
+\r
+               frameID = (frameID+1) & 3;\r
+       }\r
+\r
+       BlueFishVideoConsumer* pConsumer_;\r
+       std::vector<FramePtr> reservedFrames_;\r
+       int currentReservedFrameIndex_;\r
+\r
+       hanc_stream_info_struct hancStreamInfo_;\r
+};\r
+\r
+BluefishPlaybackStrategy::BluefishPlaybackStrategy(BlueFishVideoConsumer* pConsumer) : pImpl_(new Implementation(pConsumer)) \r
+{ }\r
+\r
+BluefishPlaybackStrategy::~BluefishPlaybackStrategy()\r
+{ }\r
+\r
+IVideoConsumer* BluefishPlaybackStrategy::GetConsumer()\r
+{\r
+       return pImpl_->pConsumer_;\r
+}\r
+\r
+FramePtr BluefishPlaybackStrategy::GetReservedFrame() {\r
+       return pImpl_->GetReservedFrame();\r
+}\r
+\r
+FrameManagerPtr BluefishPlaybackStrategy::GetFrameManager()\r
+{\r
+       return pImpl_->GetFrameManager();\r
+}\r
+\r
+void BluefishPlaybackStrategy::DisplayFrame(Frame* pFrame) \r
+{\r
+       return pImpl_->DisplayFrame(pFrame);\r
+}\r
+\r
+}      //namespace bluefish\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/consumers/bluefish/BluefishPlaybackStrategy.h b/server/consumers/bluefish/BluefishPlaybackStrategy.h
new file mode 100644 (file)
index 0000000..9cb0241
--- /dev/null
@@ -0,0 +1,47 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+\r
+#include "..\..\frame\FramePlaybackStrategy.h"\r
+\r
+namespace caspar {\r
+namespace bluefish {\r
+\r
+class BlueFishVideoConsumer;\r
+\r
+class BluefishPlaybackStrategy : public IFramePlaybackStrategy\r
+{\r
+       struct Implementation;\r
+       std::shared_ptr<Implementation> pImpl_;\r
+\r
+public:\r
+       explicit BluefishPlaybackStrategy(BlueFishVideoConsumer* pConsumer);\r
+       virtual ~BluefishPlaybackStrategy();\r
+\r
+       //IFramePlaybackStrategy\r
+       virtual void DisplayFrame(Frame*);\r
+       virtual IVideoConsumer* GetConsumer();\r
+       virtual FrameManagerPtr GetFrameManager();\r
+       virtual FramePtr GetReservedFrame();\r
+};\r
+\r
+}      //namespace bluefish\r
+}      //namespace caspar\r
diff --git a/server/consumers/decklink/DeckLinkAPI.idl b/server/consumers/decklink/DeckLinkAPI.idl
new file mode 100644 (file)
index 0000000..0c055f7
--- /dev/null
@@ -0,0 +1,847 @@
+/* -LICENSE-START-\r
+** Copyright (c) 2009 Blackmagic Design\r
+**\r
+** Permission is hereby granted, free of charge, to any person or organization\r
+** obtaining a copy of the software and accompanying documentation covered by\r
+** this license (the "Software") to use, reproduce, display, distribute,\r
+** execute, and transmit the Software, and to prepare derivative works of the\r
+** Software, and to permit third-parties to whom the Software is furnished to\r
+** do so, all subject to the following:\r
+** \r
+** The copyright notices in the Software and this entire statement, including\r
+** the above license grant, this restriction and the following disclaimer,\r
+** must be included in all copies of the Software, in whole or in part, and\r
+** all derivative works of the Software, unless such copies or derivative\r
+** works are solely in the form of machine-executable object code generated by\r
+** a source language processor.\r
+** \r
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT\r
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE\r
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,\r
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\r
+** DEALINGS IN THE SOFTWARE.\r
+** -LICENSE-END-\r
+*/\r
+\r
+/* DeckLinkAPI.idl */\r
+\r
+import "unknwn.idl";\r
+\r
+[uuid(D864517A-EDD5-466D-867D-C819F1C052BB),\r
+version(1.0), helpstring("DeckLink API Library")]\r
+library DeckLinkAPI\r
+{\r
+\r
+/* Type Declarations */\r
+\r
+typedef LONGLONG BMDTimeValue;\r
+typedef LONGLONG BMDTimeScale;\r
+typedef unsigned long BMDTimecodeBCD;\r
+\r
+/* End Type Declarations */\r
+\r
+/* Enumeration Mapping */\r
+\r
+cpp_quote("typedef unsigned long BMDFrameFlags;")\r
+cpp_quote("typedef unsigned long BMDVideoInputFlags;")\r
+cpp_quote("typedef unsigned long BMDVideoInputFormatChangedEvents;")\r
+cpp_quote("typedef unsigned long BMDDetectedVideoInputFormatFlags;")\r
+cpp_quote("typedef unsigned long BMDTimecodeFlags;")\r
+cpp_quote("typedef unsigned long BMDAnalogVideoFlags;")\r
+cpp_quote("#if 0")\r
+typedef enum _BMDFrameFlags BMDFrameFlags;\r
+typedef enum _BMDVideoInputFlags BMDVideoInputFlags;\r
+typedef enum _BMDVideoInputFormatChangedEvents BMDVideoInputFormatChangedEvents;\r
+typedef enum _BMDDetectedVideoInputFormatFlags BMDDetectedVideoInputFormatFlags;\r
+typedef enum _BMDTimecodeFlags BMDTimecodeFlags;\r
+typedef enum _BMDAnalogVideoFlags BMDAnalogVideoFlags;\r
+cpp_quote("#endif")\r
+\r
+/* End Enumeration Mapping */\r
+\r
+/* Enum BMDDisplayMode - Video display modes */\r
+\r
+typedef [v1_enum] enum _BMDDisplayMode {\r
+    bmdModeNTSC                                        = /* 'ntsc' */ 0x6E747363,\r
+    bmdModeNTSC2398                                    = /* 'nt23' */ 0x6E743233, // 3:2 pulldown\r
+    bmdModePAL                                         = /* 'pal ' */ 0x70616C20,\r
+\r
+    /* HD 1080 Modes */\r
+\r
+    bmdModeHD1080p2398                                 = /* '23ps' */ 0x32337073,\r
+    bmdModeHD1080p24                                   = /* '24ps' */ 0x32347073,\r
+    bmdModeHD1080p25                                   = /* 'Hp25' */ 0x48703235,\r
+    bmdModeHD1080p2997                                 = /* 'Hp29' */ 0x48703239,\r
+    bmdModeHD1080p30                                   = /* 'Hp30' */ 0x48703330,\r
+    bmdModeHD1080i50                                   = /* 'Hi50' */ 0x48693530,\r
+    bmdModeHD1080i5994                                 = /* 'Hi59' */ 0x48693539,\r
+    bmdModeHD1080i6000                                 = /* 'Hi60' */ 0x48693630, // N.B. This _really_ is 60.00 Hz.\r
+    bmdModeHD1080p50                                   = /* 'Hp50' */ 0x48703530,\r
+    bmdModeHD1080p5994                                 = /* 'Hp59' */ 0x48703539,\r
+    bmdModeHD1080p6000                                 = /* 'Hp60' */ 0x48703630, // N.B. This _really_ is 60.00 Hz.\r
+\r
+    /* HD 720 Modes */\r
+\r
+    bmdModeHD720p50                                    = /* 'hp50' */ 0x68703530,\r
+    bmdModeHD720p5994                                  = /* 'hp59' */ 0x68703539,\r
+    bmdModeHD720p60                                    = /* 'hp60' */ 0x68703630,\r
+\r
+    /* 2k Modes */\r
+\r
+    bmdMode2k2398                                      = /* '2k23' */ 0x326B3233,\r
+    bmdMode2k24                                        = /* '2k24' */ 0x326B3234,\r
+    bmdMode2k25                                        = /* '2k25' */ 0x326B3235\r
+} BMDDisplayMode;\r
+\r
+/* End Enum BMDDisplayMode */\r
+\r
+/* Enum BMDFieldDominance - Video field dominance */\r
+\r
+typedef [v1_enum] enum _BMDFieldDominance {\r
+    bmdUnknownFieldDominance                           = 0,\r
+    bmdLowerFieldFirst                                 = /* 'lowr' */ 0x6C6F7772,\r
+    bmdUpperFieldFirst                                 = /* 'uppr' */ 0x75707072,\r
+    bmdProgressiveFrame                                = /* 'prog' */ 0x70726F67,\r
+    bmdProgressiveSegmentedFrame                       = /* 'psf ' */ 0x70736620\r
+} BMDFieldDominance;\r
+\r
+/* End Enum BMDFieldDominance */\r
+\r
+/* Enum BMDPixelFormat - Video pixel formats supported for output/input */\r
+\r
+typedef [v1_enum] enum _BMDPixelFormat {\r
+    bmdFormat8BitYUV                                   = /* '2vuy' */ 0x32767579,\r
+    bmdFormat10BitYUV                                  = /* 'v210' */ 0x76323130,\r
+    bmdFormat8BitARGB                                  = 0x20,\r
+    bmdFormat8BitBGRA                                  = /* 'BGRA' */ 0x42475241,\r
+    bmdFormat10BitRGB                                  = /* 'r210' */ 0x72323130\r
+} BMDPixelFormat;\r
+\r
+/* End Enum BMDPixelFormat */\r
+\r
+/* Enum BMDVideoOutputFlags - Flags to control the output of ancillary data along with video. */\r
+\r
+typedef [v1_enum] enum _BMDVideoOutputFlags {\r
+    bmdVideoOutputFlagDefault                          = 0,\r
+    bmdVideoOutputRP188                                = 1 << 0,\r
+    bmdVideoOutputVANC                                 = 1 << 1\r
+} BMDVideoOutputFlags;\r
+\r
+/* End Enum BMDVideoOutputFlags */\r
+\r
+/* Enum BMDFrameFlags - Frame flags */\r
+\r
+[v1_enum] enum _BMDFrameFlags {\r
+    bmdFrameFlagDefault                                = 0,\r
+    bmdFrameFlagFlipVertical                           = 1 << 0,\r
+\r
+    /* Flags that are valid only for frames returned through IDeckLinkInput */\r
+\r
+    bmdFrameHasNoInputSource                           = 1 << 31\r
+};\r
+\r
+/* End Enum BMDFrameFlags */\r
+\r
+/* Enum BMDVideoInputFlags - Flags applicable to video input */\r
+\r
+[v1_enum] enum _BMDVideoInputFlags {\r
+    bmdVideoInputFlagDefault                           = 0,\r
+    bmdVideoInputEnableFormatDetection                 = 1 << 0\r
+};\r
+\r
+/* End Enum BMDVideoInputFlags */\r
+\r
+/* Enum BMDVideoInputFormatChangedEvents - Bitmask passed to the VideoInputFormatChanged notification to identify the properties of the input signal that have changed */\r
+\r
+[v1_enum] enum _BMDVideoInputFormatChangedEvents {\r
+    bmdVideoInputDisplayModeChanged                    = 1 << 0,\r
+    bmdVideoInputFieldDominanceChanged                 = 1 << 1,\r
+    bmdVideoInputColorspaceChanged                     = 1 << 2\r
+};\r
+\r
+/* End Enum BMDVideoInputFormatChangedEvents */\r
+\r
+/* Enum BMDDetectedVideoInputFormatFlags - Flags passed to the VideoInputFormatChanged notification to describe the detected video input signal */\r
+\r
+[v1_enum] enum _BMDDetectedVideoInputFormatFlags {\r
+    bmdDetectedVideoInputYCbCr422                      = 1 << 0,\r
+    bmdDetectedVideoInputRGB444                        = 1 << 1\r
+};\r
+\r
+/* End Enum BMDDetectedVideoInputFormatFlags */\r
+\r
+/* Enum BMDOutputFrameCompletionResult - Frame Completion Callback */\r
+\r
+typedef [v1_enum] enum _BMDOutputFrameCompletionResult {\r
+    bmdOutputFrameCompleted,                          \r
+    bmdOutputFrameDisplayedLate,                      \r
+    bmdOutputFrameDropped,                            \r
+    bmdOutputFrameFlushed                             \r
+} BMDOutputFrameCompletionResult;\r
+\r
+/* End Enum BMDOutputFrameCompletionResult */\r
+\r
+/* Enum BMDAudioSampleRate - Audio sample rates supported for output/input */\r
+\r
+typedef [v1_enum] enum _BMDAudioSampleRate {\r
+    bmdAudioSampleRate48kHz                            = 48000\r
+} BMDAudioSampleRate;\r
+\r
+/* End Enum BMDAudioSampleRate */\r
+\r
+/* Enum BMDAudioSampleType - Audio sample sizes supported for output/input */\r
+\r
+typedef [v1_enum] enum _BMDAudioSampleType {\r
+    bmdAudioSampleType16bitInteger                     = 16,\r
+    bmdAudioSampleType32bitInteger                     = 32\r
+} BMDAudioSampleType;\r
+\r
+/* End Enum BMDAudioSampleType */\r
+\r
+/* Enum BMDAudioOutputStreamType - Audio output stream type */\r
+\r
+typedef [v1_enum] enum _BMDAudioOutputStreamType {\r
+    bmdAudioOutputStreamContinuous,                   \r
+    bmdAudioOutputStreamContinuousDontResample,       \r
+    bmdAudioOutputStreamTimestamped                   \r
+} BMDAudioOutputStreamType;\r
+\r
+/* End Enum BMDAudioOutputStreamType */\r
+\r
+/* Enum BMDDisplayModeSupport - Output mode supported flags */\r
+\r
+typedef [v1_enum] enum _BMDDisplayModeSupport {\r
+    bmdDisplayModeNotSupported                         = 0,\r
+    bmdDisplayModeSupported,                          \r
+    bmdDisplayModeSupportedWithConversion             \r
+} BMDDisplayModeSupport;\r
+\r
+/* End Enum BMDDisplayModeSupport */\r
+\r
+/* Enum BMDTimecodeFormat - Timecode formats for frame metadata */\r
+\r
+typedef [v1_enum] enum _BMDTimecodeFormat {\r
+    bmdTimecodeRP188                                   = /* 'rp18' */ 0x72703138,\r
+    bmdTimecodeVITC                                    = /* 'vitc' */ 0x76697463,\r
+    bmdTimecodeSerial                                  = /* 'seri' */ 0x73657269\r
+} BMDTimecodeFormat;\r
+\r
+/* End Enum BMDTimecodeFormat */\r
+\r
+/* Enum BMDTimecodeFlags - Timecode flags */\r
+\r
+[v1_enum] enum _BMDTimecodeFlags {\r
+    bmdTimecodeFlagDefault                             = 0,\r
+    bmdTimecodeIsDropFrame                             = 1 << 0\r
+};\r
+\r
+/* End Enum BMDTimecodeFlags */\r
+\r
+/* Enum BMDVideoConnection - Video connection types */\r
+\r
+typedef [v1_enum] enum _BMDVideoConnection {\r
+    bmdVideoConnectionSDI                              = /* 'sdi ' */ 0x73646920,\r
+    bmdVideoConnectionHDMI                             = /* 'hdmi' */ 0x68646D69,\r
+    bmdVideoConnectionOpticalSDI                       = /* 'opti' */ 0x6F707469,\r
+    bmdVideoConnectionComponent                        = /* 'cpnt' */ 0x63706E74,\r
+    bmdVideoConnectionComposite                        = /* 'cmst' */ 0x636D7374,\r
+    bmdVideoConnectionSVideo                           = /* 'svid' */ 0x73766964\r
+} BMDVideoConnection;\r
+\r
+/* End Enum BMDVideoConnection */\r
+\r
+/* Enum BMDAnalogVideoFlags - Analog video display flags */\r
+\r
+[v1_enum] enum _BMDAnalogVideoFlags {\r
+    bmdAnalogVideoFlagCompositeSetup75                 = 1 << 0,\r
+    bmdAnalogVideoFlagComponentBetacamLevels           = 1 << 1\r
+};\r
+\r
+/* End Enum BMDAnalogVideoFlags */\r
+\r
+/* Enum BMDAudioConnection - Audio connection types */\r
+\r
+typedef [v1_enum] enum _BMDAudioConnection {\r
+    bmdAudioConnectionEmbedded                         = /* 'embd' */ 0x656D6264,\r
+    bmdAudioConnectionAESEBU                           = /* 'aes ' */ 0x61657320,\r
+    bmdAudioConnectionAnalog                           = /* 'anlg' */ 0x616E6C67\r
+} BMDAudioConnection;\r
+\r
+/* End Enum BMDAudioConnection */\r
+\r
+/* Enum BMDVideoOutputConversionMode - Video/audio conversion mode */\r
+\r
+typedef [v1_enum] enum _BMDVideoOutputConversionMode {\r
+    bmdNoVideoOutputConversion                         = /* 'none' */ 0x6E6F6E65,\r
+    bmdVideoOutputLetterboxDownonversion               = /* 'ltbx' */ 0x6C746278,\r
+    bmdVideoOutputAnamorphicDownonversion              = /* 'amph' */ 0x616D7068,\r
+    bmdVideoOutputHD720toHD1080Conversion              = /* '720c' */ 0x37323063,\r
+    bmdVideoOutputHardwareLetterboxDownconversion      = /* 'HWlb' */ 0x48576C62,\r
+    bmdVideoOutputHardwareAnamorphicDownconversion     = /* 'HWam' */ 0x4857616D,\r
+    bmdVideoOutputHardwareCenterCutDownconversion      = /* 'HWcc' */ 0x48576363\r
+} BMDVideoOutputConversionMode;\r
+\r
+/* End Enum BMDVideoOutputConversionMode */\r
+\r
+/* Enum BMDVideoInputConversionMode - Video input conversion mode */\r
+\r
+typedef [v1_enum] enum _BMDVideoInputConversionMode {\r
+    bmdNoVideoInputConversion                          = /* 'none' */ 0x6E6F6E65,\r
+    bmdVideoInputLetterboxDownconversionFromHD1080     = /* '10lb' */ 0x31306C62,\r
+    bmdVideoInputAnamorphicDownconversionFromHD1080    = /* '10am' */ 0x3130616D,\r
+    bmdVideoInputLetterboxDownconversionFromHD720      = /* '72lb' */ 0x37326C62,\r
+    bmdVideoInputAnamorphicDownconversionFromHD720     = /* '72am' */ 0x3732616D,\r
+    bmdVideoInputLetterboxUpconversion                 = /* 'lbup' */ 0x6C627570,\r
+    bmdVideoInputAnamorphicUpconversion                = /* 'amup' */ 0x616D7570\r
+} BMDVideoInputConversionMode;\r
+\r
+/* End Enum BMDVideoInputConversionMode */\r
+\r
+/* Enum BMDDeckLinkAttributeID - DeckLink Atribute ID */\r
+\r
+typedef [v1_enum] enum _BMDDeckLinkAttributeID {\r
+\r
+    /* Flags */\r
+\r
+    BMDDeckLinkSupportsInternalKeying                  = /* 'keyi' */ 0x6B657969,\r
+    BMDDeckLinkSupportsExternalKeying                  = /* 'keye' */ 0x6B657965,\r
+    BMDDeckLinkSupportsHDKeying                        = /* 'keyh' */ 0x6B657968,\r
+    BMDDeckLinkSupportsInputFormatDetection            = /* 'infd' */ 0x696E6664,\r
+    BMDDeckLinkHasSerialPort                           = /* 'hspt' */ 0x68737074,\r
+\r
+    /* Integers */\r
+\r
+    BMDDeckLinkMaximumAudioChannels                    = /* 'mach' */ 0x6D616368,\r
+\r
+    /* Strings */\r
+\r
+    BMDDeckLinkSerialPortDeviceName                    = /* 'slpn' */ 0x736C706E\r
+} BMDDeckLinkAttributeID;\r
+\r
+/* End Enum BMDDeckLinkAttributeID */\r
+\r
+/* Enum BMDDeckLinkAPIInformationID - DeckLinkAPI information ID */\r
+\r
+typedef [v1_enum] enum _BMDDeckLinkAPIInformationID {\r
+    BMDDeckLinkAPIVersion                              = /* 'vers' */ 0x76657273\r
+} BMDDeckLinkAPIInformationID;\r
+\r
+/* End Enum BMDDeckLinkAPIInformationID */\r
+\r
+/* Forward Declarations */\r
+\r
+interface IDeckLinkVideoOutputCallback;\r
+interface IDeckLinkInputCallback;\r
+interface IDeckLinkMemoryAllocator;\r
+interface IDeckLinkAudioOutputCallback;\r
+interface IDeckLinkIterator;\r
+interface IDeckLinkAPIInformation;\r
+interface IDeckLinkDisplayModeIterator;\r
+interface IDeckLinkDisplayMode;\r
+interface IDeckLink;\r
+interface IDeckLinkOutput;\r
+interface IDeckLinkInput;\r
+interface IDeckLinkTimecode;\r
+interface IDeckLinkVideoFrame;\r
+interface IDeckLinkMutableVideoFrame;\r
+interface IDeckLinkVideoInputFrame;\r
+interface IDeckLinkVideoFrameAncillary;\r
+interface IDeckLinkAudioInputPacket;\r
+interface IDeckLinkScreenPreviewCallback;\r
+interface IDeckLinkGLScreenPreviewHelper;\r
+interface IDeckLinkConfiguration;\r
+interface IDeckLinkAttributes;\r
+interface IDeckLinkKeyer;\r
+\r
+/* End Forward Declarations */\r
+\r
+/* Interface IDeckLinkVideoOutputCallback - Frame completion callback. */\r
+\r
+[\r
+    object,\r
+    uuid(E763A626-4A3C-49D1-BF13-E7AD3692AE52),\r
+    helpstring("Frame completion callback.")\r
+] interface IDeckLinkVideoOutputCallback : IUnknown\r
+{\r
+    HRESULT ScheduledFrameCompleted([in] IDeckLinkVideoFrame *completedFrame, [in] BMDOutputFrameCompletionResult result);\r
+    HRESULT ScheduledPlaybackHasStopped(void);\r
+};\r
+\r
+/* End Interface IDeckLinkVideoOutputCallback */\r
+\r
+/* Interface IDeckLinkInputCallback - Frame arrival callback. */\r
+\r
+[\r
+    object,\r
+    uuid(31D28EE7-88B6-4CB1-897A-CDBF79A26414),\r
+    helpstring("Frame arrival callback.")\r
+] interface IDeckLinkInputCallback : IUnknown\r
+{\r
+    HRESULT VideoInputFormatChanged([in] BMDVideoInputFormatChangedEvents notificationEvents, [in] IDeckLinkDisplayMode *newDisplayMode, [in] BMDDetectedVideoInputFormatFlags detectedSignalFlags);\r
+    HRESULT VideoInputFrameArrived([in] IDeckLinkVideoInputFrame *videoFrame, [in] IDeckLinkAudioInputPacket *audioPacket);\r
+};\r
+\r
+/* End Interface IDeckLinkInputCallback */\r
+\r
+/* Interface IDeckLinkMemoryAllocator - Memory allocator for video frames. */\r
+\r
+[\r
+    object,\r
+    uuid(B36EB6E7-9D29-4AA8-92EF-843B87A289E8),\r
+    local, \r
+    helpstring("Memory allocator for video frames.")\r
+] interface IDeckLinkMemoryAllocator : IUnknown\r
+{\r
+    HRESULT AllocateBuffer(unsigned long bufferSize, [out] void **allocatedBuffer);\r
+    HRESULT ReleaseBuffer([in] void *buffer);\r
+\r
+    HRESULT Commit(void);\r
+    HRESULT Decommit(void);\r
+};\r
+\r
+/* End Interface IDeckLinkMemoryAllocator */\r
+\r
+/* Interface IDeckLinkAudioOutputCallback - Optional callback to allow audio samples to be pulled as required. */\r
+\r
+[\r
+    object,\r
+    uuid(403C681B-7F46-4A12-B993-2BB127084EE6),\r
+    local, \r
+    helpstring("Optional callback to allow audio samples to be pulled as required.")\r
+] interface IDeckLinkAudioOutputCallback : IUnknown\r
+{\r
+    HRESULT RenderAudioSamples(BOOL preroll);\r
+};\r
+\r
+/* End Interface IDeckLinkAudioOutputCallback */\r
+\r
+/* Interface IDeckLinkIterator - enumerates installed DeckLink hardware */\r
+\r
+[\r
+    object,\r
+    uuid(74E936FC-CC28-4A67-81A0-1E94E52D4E69),\r
+    helpstring("enumerates installed DeckLink hardware")\r
+] interface IDeckLinkIterator : IUnknown\r
+{\r
+    HRESULT Next([out] IDeckLink **deckLinkInstance);\r
+};\r
+\r
+/* End Interface IDeckLinkIterator */\r
+\r
+/* Interface IDeckLinkAPIInformation - DeckLinkAPI attribute interface */\r
+\r
+[\r
+    object,\r
+    uuid(7BEA3C68-730D-4322-AF34-8A7152B532A4),\r
+    helpstring("DeckLinkAPI attribute interface")\r
+] interface IDeckLinkAPIInformation : IUnknown\r
+{\r
+    HRESULT GetFlag([in] BMDDeckLinkAPIInformationID cfgID, [out] BOOL *value);\r
+    HRESULT GetInt([in] BMDDeckLinkAPIInformationID cfgID, [out] LONGLONG *value);\r
+    HRESULT GetFloat([in] BMDDeckLinkAPIInformationID cfgID, [out] double *value);\r
+    HRESULT GetString([in] BMDDeckLinkAPIInformationID cfgID, [out] BSTR *value);\r
+};\r
+\r
+/* End Interface IDeckLinkAPIInformation */\r
+\r
+/* Interface IDeckLinkDisplayModeIterator - enumerates over supported input/output display modes. */\r
+\r
+[\r
+    object,\r
+    uuid(455D741F-1779-4800-86F5-0B5D13D79751),\r
+    helpstring("enumerates over supported input/output display modes.")\r
+] interface IDeckLinkDisplayModeIterator : IUnknown\r
+{\r
+    HRESULT Next([out] IDeckLinkDisplayMode **deckLinkDisplayMode);\r
+};\r
+\r
+/* End Interface IDeckLinkDisplayModeIterator */\r
+\r
+/* Interface IDeckLinkDisplayMode - represents a display mode */\r
+\r
+[\r
+    object,\r
+    uuid(87451E84-2B7E-439E-A629-4393EA4A8550),\r
+    helpstring("represents a display mode")\r
+] interface IDeckLinkDisplayMode : IUnknown\r
+{\r
+    HRESULT GetName([out] BSTR *name);\r
+    BMDDisplayMode GetDisplayMode(void);\r
+    long GetWidth(void);\r
+    long GetHeight(void);\r
+    HRESULT GetFrameRate([out] BMDTimeValue *frameDuration, [out] BMDTimeScale *timeScale);\r
+    BMDFieldDominance GetFieldDominance(void);\r
+};\r
+\r
+/* End Interface IDeckLinkDisplayMode */\r
+\r
+/* Interface IDeckLink - represents a DeckLink device */\r
+\r
+[\r
+    object,\r
+    uuid(62BFF75D-6569-4E55-8D4D-66AA03829ABC),\r
+    helpstring("represents a DeckLink device")\r
+] interface IDeckLink : IUnknown\r
+{\r
+    HRESULT GetModelName([out] BSTR *modelName);\r
+};\r
+\r
+/* End Interface IDeckLink */\r
+\r
+/* Interface IDeckLinkOutput - Created by QueryInterface from IDeckLink. */\r
+\r
+[\r
+    object,\r
+    uuid(29228142-EB8C-4141-A621-F74026450955),\r
+    local, \r
+    helpstring("Created by QueryInterface from IDeckLink.")\r
+] interface IDeckLinkOutput : IUnknown\r
+{\r
+    HRESULT DoesSupportVideoMode(BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, [out] BMDDisplayModeSupport *result);\r
+    HRESULT GetDisplayModeIterator([out] IDeckLinkDisplayModeIterator **iterator);\r
+\r
+    HRESULT SetScreenPreviewCallback([in] IDeckLinkScreenPreviewCallback *previewCallback);\r
+\r
+    /* Video Output */\r
+\r
+    HRESULT EnableVideoOutput(BMDDisplayMode displayMode, BMDVideoOutputFlags flags);\r
+    HRESULT DisableVideoOutput(void);\r
+\r
+    HRESULT SetVideoOutputFrameMemoryAllocator([in] IDeckLinkMemoryAllocator *theAllocator);\r
+    HRESULT CreateVideoFrame(long width, long height, long rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, [out] IDeckLinkMutableVideoFrame **outFrame);\r
+    HRESULT CreateAncillaryData(BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, [out] IDeckLinkVideoFrameAncillary **outBuffer);\r
+\r
+    HRESULT DisplayVideoFrameSync([in] IDeckLinkVideoFrame *theFrame);\r
+    HRESULT ScheduleVideoFrame([in] IDeckLinkVideoFrame *theFrame, BMDTimeValue displayTime, BMDTimeValue displayDuration, BMDTimeScale timeScale);\r
+    HRESULT SetScheduledFrameCompletionCallback([in] IDeckLinkVideoOutputCallback *theCallback);\r
+    HRESULT GetBufferedVideoFrameCount([out] unsigned long *bufferedFrameCount);\r
+\r
+    /* Audio Output */\r
+\r
+    HRESULT EnableAudioOutput(BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, unsigned long channelCount, BMDAudioOutputStreamType streamType);\r
+    HRESULT DisableAudioOutput(void);\r
+\r
+    HRESULT WriteAudioSamplesSync([in] void *buffer, unsigned long sampleFrameCount, [out] unsigned long *sampleFramesWritten);\r
+\r
+    HRESULT BeginAudioPreroll(void);\r
+    HRESULT EndAudioPreroll(void);\r
+    HRESULT ScheduleAudioSamples([in] void *buffer, unsigned long sampleFrameCount, BMDTimeValue streamTime, BMDTimeScale timeScale, [out] unsigned long *sampleFramesWritten);\r
+\r
+    HRESULT GetBufferedAudioSampleFrameCount([out] unsigned long *bufferedSampleFrameCount);\r
+    HRESULT FlushBufferedAudioSamples(void);\r
+\r
+    HRESULT SetAudioCallback([in] IDeckLinkAudioOutputCallback *theCallback);\r
+\r
+    /* Output Control */\r
+\r
+    HRESULT StartScheduledPlayback(BMDTimeValue playbackStartTime, BMDTimeScale timeScale, double playbackSpeed);\r
+    HRESULT StopScheduledPlayback(BMDTimeValue stopPlaybackAtTime, [out] BMDTimeValue *actualStopTime, BMDTimeScale timeScale);\r
+    HRESULT IsScheduledPlaybackRunning([out] BOOL *active);\r
+    HRESULT GetScheduledStreamTime(BMDTimeScale desiredTimeScale, [out] BMDTimeValue *streamTime, [out] double *playbackSpeed);\r
+\r
+    /* Hardware Timing */\r
+\r
+    HRESULT GetHardwareReferenceClock(BMDTimeScale desiredTimeScale, [out] BMDTimeValue *hardwareTime, [out] BMDTimeValue *timeInFrame, [out] BMDTimeValue *ticksPerFrame);\r
+};\r
+\r
+/* End Interface IDeckLinkOutput */\r
+\r
+/* Interface IDeckLinkInput - Created by QueryInterface from IDeckLink. */\r
+\r
+[\r
+    object,\r
+    uuid(300C135A-9F43-48E2-9906-6D7911D93CF1),\r
+    helpstring("Created by QueryInterface from IDeckLink.")\r
+] interface IDeckLinkInput : IUnknown\r
+{\r
+    HRESULT DoesSupportVideoMode(BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, [out] BMDDisplayModeSupport *result);\r
+    HRESULT GetDisplayModeIterator([out] IDeckLinkDisplayModeIterator **iterator);\r
+\r
+    HRESULT SetScreenPreviewCallback([in] IDeckLinkScreenPreviewCallback *previewCallback);\r
+\r
+    /* Video Input */\r
+\r
+    HRESULT EnableVideoInput(BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDVideoInputFlags flags);\r
+    HRESULT DisableVideoInput(void);\r
+    HRESULT GetAvailableVideoFrameCount([out] unsigned long *availableFrameCount);\r
+\r
+    /* Audio Input */\r
+\r
+    HRESULT EnableAudioInput(BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, unsigned long channelCount);\r
+    HRESULT DisableAudioInput(void);\r
+    HRESULT GetAvailableAudioSampleFrameCount([out] unsigned long *availableSampleFrameCount);\r
+\r
+    /* Input Control */\r
+\r
+    HRESULT StartStreams(void);\r
+    HRESULT StopStreams(void);\r
+    HRESULT PauseStreams(void);\r
+    HRESULT FlushStreams(void);\r
+    HRESULT SetCallback([in] IDeckLinkInputCallback *theCallback);\r
+\r
+    /* Hardware Timing */\r
+\r
+    HRESULT GetHardwareReferenceClock(BMDTimeScale desiredTimeScale, [out] BMDTimeValue *hardwareTime, [out] BMDTimeValue *timeInFrame, [out] BMDTimeValue *ticksPerFrame);\r
+};\r
+\r
+/* End Interface IDeckLinkInput */\r
+\r
+/* Interface IDeckLinkTimecode - Used for video frame timecode representation. */\r
+\r
+[\r
+    object,\r
+    uuid(EFB9BCA6-A521-44F7-BD69-2332F24D9EE6),\r
+    helpstring("Used for video frame timecode representation.")\r
+] interface IDeckLinkTimecode : IUnknown\r
+{\r
+    BMDTimecodeBCD GetBCD(void);\r
+    HRESULT GetComponents([out] unsigned char *hours, [out] unsigned char *minutes, [out] unsigned char *seconds, [out] unsigned char *frames);\r
+    HRESULT GetString([out] BSTR *timecode);\r
+    BMDTimecodeFlags GetFlags(void);\r
+};\r
+\r
+/* End Interface IDeckLinkTimecode */\r
+\r
+/* Interface IDeckLinkVideoFrame - Interface to encapsulate a video frame; can be caller-implemented. */\r
+\r
+[\r
+    object,\r
+    uuid(A8D8238E-6B18-4196-99E1-5AF717B83D32),\r
+    local, \r
+    helpstring("Interface to encapsulate a video frame; can be caller-implemented.")\r
+] interface IDeckLinkVideoFrame : IUnknown\r
+{\r
+    long GetWidth(void);\r
+    long GetHeight(void);\r
+    long GetRowBytes(void);\r
+    BMDPixelFormat GetPixelFormat(void);\r
+    BMDFrameFlags GetFlags(void);\r
+    HRESULT GetBytes([out] void **buffer);\r
+\r
+    HRESULT GetTimecode(BMDTimecodeFormat format, [out] IDeckLinkTimecode **timecode);\r
+    HRESULT GetAncillaryData([out] IDeckLinkVideoFrameAncillary **ancillary);\r
+};\r
+\r
+/* End Interface IDeckLinkVideoFrame */\r
+\r
+/* Interface IDeckLinkMutableVideoFrame - Created by IDeckLinkOutput::CreateVideoFrame. */\r
+\r
+[\r
+    object,\r
+    uuid(46FCEE00-B4E6-43D0-91C0-023A7FCEB34F),\r
+    local, \r
+    helpstring("Created by IDeckLinkOutput::CreateVideoFrame.")\r
+] interface IDeckLinkMutableVideoFrame : IDeckLinkVideoFrame\r
+{\r
+    HRESULT SetFlags(BMDFrameFlags newFlags);\r
+\r
+    HRESULT SetTimecode(BMDTimecodeFormat format, [in] IDeckLinkTimecode *timecode);\r
+    HRESULT SetTimecodeFromComponents(BMDTimecodeFormat format, unsigned char hours, unsigned char minutes, unsigned char seconds, unsigned char frames, BMDTimecodeFlags flags);\r
+    HRESULT SetAncillaryData([in] IDeckLinkVideoFrameAncillary *ancillary);\r
+};\r
+\r
+/* End Interface IDeckLinkMutableVideoFrame */\r
+\r
+/* Interface IDeckLinkVideoInputFrame - Provided by the IDeckLinkVideoInput frame arrival callback. */\r
+\r
+[\r
+    object,\r
+    uuid(9A74FA41-AE9F-47AC-8CF4-01F42DD59965),\r
+    local, \r
+    helpstring("Provided by the IDeckLinkVideoInput frame arrival callback.")\r
+] interface IDeckLinkVideoInputFrame : IDeckLinkVideoFrame\r
+{\r
+    HRESULT GetStreamTime([out] BMDTimeValue *frameTime, [out] BMDTimeValue *frameDuration, BMDTimeScale timeScale);\r
+    HRESULT GetHardwareReferenceTimestamp(BMDTimeScale timeScale, [out] BMDTimeValue *frameTime, [out] BMDTimeValue *frameDuration);\r
+};\r
+\r
+/* End Interface IDeckLinkVideoInputFrame */\r
+\r
+/* Interface IDeckLinkVideoFrameAncillary - Obtained through QueryInterface() on an IDeckLinkVideoFrame object. */\r
+\r
+[\r
+    object,\r
+    uuid(732E723C-D1A4-4E29-9E8E-4A88797A0004),\r
+    local, \r
+    helpstring("Obtained through QueryInterface() on an IDeckLinkVideoFrame object.")\r
+] interface IDeckLinkVideoFrameAncillary : IUnknown\r
+{\r
+\r
+    HRESULT GetBufferForVerticalBlankingLine(unsigned long lineNumber, [out] void **buffer);\r
+    BMDPixelFormat GetPixelFormat(void);\r
+    BMDDisplayMode GetDisplayMode(void);\r
+};\r
+\r
+/* End Interface IDeckLinkVideoFrameAncillary */\r
+\r
+/* Interface IDeckLinkAudioInputPacket - Provided by the IDeckLinkInput callback. */\r
+\r
+[\r
+    object,\r
+    uuid(E43D5870-2894-11DE-8C30-0800200C9A66),\r
+    local, \r
+    helpstring("Provided by the IDeckLinkInput callback.")\r
+] interface IDeckLinkAudioInputPacket : IUnknown\r
+{\r
+    long GetSampleFrameCount(void);\r
+    HRESULT GetBytes([out] void **buffer);\r
+    HRESULT GetPacketTime([out] BMDTimeValue *packetTime, BMDTimeScale timeScale);\r
+};\r
+\r
+/* End Interface IDeckLinkAudioInputPacket */\r
+\r
+/* Interface IDeckLinkScreenPreviewCallback - Screen preview callback */\r
+\r
+[\r
+    object,\r
+    uuid(373F499D-4B4D-4518-AD22-6354E5A5825E),\r
+    local, \r
+    helpstring("Screen preview callback")\r
+] interface IDeckLinkScreenPreviewCallback : IUnknown\r
+{\r
+    HRESULT DrawFrame([in] IDeckLinkVideoFrame *theFrame);\r
+};\r
+\r
+/* End Interface IDeckLinkScreenPreviewCallback */\r
+\r
+/* Interface IDeckLinkGLScreenPreviewHelper - Created with CoCreateInstance(). */\r
+\r
+[\r
+    object,\r
+    uuid(BA575CD9-A15E-497B-B2C2-F9AFE7BE4EBA),\r
+    local, \r
+    helpstring("Created with CoCreateInstance().")\r
+] interface IDeckLinkGLScreenPreviewHelper : IUnknown\r
+{\r
+\r
+    /* Methods must be called with OpenGL context set */\r
+\r
+    HRESULT InitializeGL(void);\r
+    HRESULT PaintGL(void);\r
+    HRESULT SetFrame([in] IDeckLinkVideoFrame *theFrame);\r
+};\r
+\r
+/* End Interface IDeckLinkGLScreenPreviewHelper */\r
+\r
+/* Interface IDeckLinkConfiguration - Created by QueryInterface from IDeckLink. */\r
+\r
+[\r
+    object,\r
+    uuid(B8EAD569-B764-47F0-A73F-AE40DF6CBF10),\r
+    helpstring("Created by QueryInterface from IDeckLink.")\r
+] interface IDeckLinkConfiguration : IUnknown\r
+{\r
+    HRESULT GetConfigurationValidator([out] IDeckLinkConfiguration **configObject);\r
+    HRESULT WriteConfigurationToPreferences(void);\r
+\r
+    /* Video Output Configuration */\r
+\r
+    HRESULT SetVideoOutputFormat(BMDVideoConnection videoOutputConnection);\r
+    HRESULT IsVideoOutputActive(BMDVideoConnection videoOutputConnection, [out] BOOL *active);\r
+\r
+    HRESULT SetAnalogVideoOutputFlags(BMDAnalogVideoFlags analogVideoFlags);\r
+    HRESULT GetAnalogVideoOutputFlags([out] BMDAnalogVideoFlags *analogVideoFlags);\r
+\r
+    HRESULT EnableFieldFlickerRemovalWhenPaused(BOOL enable);\r
+    HRESULT IsEnabledFieldFlickerRemovalWhenPaused([out] BOOL *enabled);\r
+\r
+    HRESULT Set444And3GBpsVideoOutput(BOOL enable444VideoOutput, BOOL enable3GbsOutput);\r
+    HRESULT Get444And3GBpsVideoOutput([out] BOOL *is444VideoOutputEnabled, [out] BOOL *threeGbsOutputEnabled);\r
+\r
+    HRESULT SetVideoOutputConversionMode(BMDVideoOutputConversionMode conversionMode);\r
+    HRESULT GetVideoOutputConversionMode([out] BMDVideoOutputConversionMode *conversionMode);\r
+\r
+    HRESULT Set_HD1080p24_to_HD1080i5994_Conversion(BOOL enable);\r
+    HRESULT Get_HD1080p24_to_HD1080i5994_Conversion([out] BOOL *enabled);\r
+\r
+    /* Video Input Configuration */\r
+\r
+    HRESULT SetVideoInputFormat(BMDVideoConnection videoInputFormat);\r
+    HRESULT GetVideoInputFormat([out] BMDVideoConnection *videoInputFormat);\r
+\r
+    HRESULT SetAnalogVideoInputFlags(BMDAnalogVideoFlags analogVideoFlags);\r
+    HRESULT GetAnalogVideoInputFlags([out] BMDAnalogVideoFlags *analogVideoFlags);\r
+\r
+    HRESULT SetVideoInputConversionMode(BMDVideoInputConversionMode conversionMode);\r
+    HRESULT GetVideoInputConversionMode([out] BMDVideoInputConversionMode *conversionMode);\r
+\r
+    HRESULT SetBlackVideoOutputDuringCapture(BOOL blackOutInCapture);\r
+    HRESULT GetBlackVideoOutputDuringCapture([out] BOOL *blackOutInCapture);\r
+\r
+    HRESULT Set32PulldownSequenceInitialTimecodeFrame(unsigned long aFrameTimecode);\r
+    HRESULT Get32PulldownSequenceInitialTimecodeFrame([out] unsigned long *aFrameTimecode);\r
+\r
+    HRESULT SetVancSourceLineMapping(unsigned long activeLine1VANCsource, unsigned long activeLine2VANCsource, unsigned long activeLine3VANCsource);\r
+    HRESULT GetVancSourceLineMapping([out] unsigned long *activeLine1VANCsource, [out] unsigned long *activeLine2VANCsource, [out] unsigned long *activeLine3VANCsource);\r
+\r
+    /* Audio Input Configuration */\r
+\r
+    HRESULT SetAudioInputFormat(BMDAudioConnection audioInputFormat);\r
+    HRESULT GetAudioInputFormat([out] BMDAudioConnection *audioInputFormat);\r
+};\r
+\r
+/* End Interface IDeckLinkConfiguration */\r
+\r
+/* Interface IDeckLinkAttributes - DeckLink Attribute interface */\r
+\r
+[\r
+    object,\r
+    uuid(ABC11843-D966-44CB-96E2-A1CB5D3135C4),\r
+    local, \r
+    helpstring("DeckLink Attribute interface")\r
+] interface IDeckLinkAttributes : IUnknown\r
+{\r
+    HRESULT GetFlag([in] BMDDeckLinkAttributeID cfgID, [out] BOOL *value);\r
+    HRESULT GetInt([in] BMDDeckLinkAttributeID cfgID, [out] LONGLONG *value);\r
+    HRESULT GetFloat([in] BMDDeckLinkAttributeID cfgID, [out] double *value);\r
+    HRESULT GetString([in] BMDDeckLinkAttributeID cfgID, [out] BSTR *value);\r
+};\r
+\r
+/* End Interface IDeckLinkAttributes */\r
+\r
+/* Interface IDeckLinkKeyer - DeckLink Keyer interface */\r
+\r
+[\r
+    object,\r
+    uuid(89AFCAF5-65F8-421E-98F7-96FE5F5BFBA3),\r
+    local, \r
+    helpstring("DeckLink Keyer interface")\r
+] interface IDeckLinkKeyer : IUnknown\r
+{\r
+    HRESULT Enable([in] BOOL isExternal);\r
+    HRESULT SetLevel([in] unsigned char level);\r
+    HRESULT RampUp([in] unsigned long numberOfFrames);\r
+    HRESULT RampDown([in] unsigned long numberOfFrames);\r
+    HRESULT Disable(void);\r
+};\r
+\r
+/* End Interface IDeckLinkKeyer */\r
+\r
+/* Coclasses */\r
+\r
+importlib("stdole2.tlb");\r
+\r
+[\r
+    uuid(D9EDA3B3-2887-41FA-B724-017CF1EB1D37),\r
+    helpstring("CDeckLinkIterator Class")\r
+] coclass CDeckLinkIterator\r
+{\r
+    [default] interface IDeckLinkIterator;\r
+};\r
+\r
+[\r
+    uuid(D398CEE7-4434-4CA3-9BA6-5AE34556B905),\r
+    helpstring("CDeckLinkGLScreenPreviewHelper Class")\r
+] coclass CDeckLinkGLScreenPreviewHelper\r
+{\r
+    [default] interface IDeckLinkGLScreenPreviewHelper;\r
+};\r
+\r
+/* End Coclasses */\r
+\r
+// import deprecated interfaces\r
+#include "DeckLinkAPI_v7_1.idl"\r
+#include "DeckLinkAPI_v7_3.idl"\r
+};\r
diff --git a/server/consumers/decklink/DeckLinkAPI_h.h b/server/consumers/decklink/DeckLinkAPI_h.h
new file mode 100644 (file)
index 0000000..1321b07
--- /dev/null
@@ -0,0 +1,5584 @@
+\r
+\r
+/* this ALWAYS GENERATED file contains the definitions for the interfaces */\r
+\r
+\r
+ /* File created by MIDL compiler version 7.00.0500 */\r
+/* at Wed Jan 13 09:58:01 2010\r
+ */\r
+/* Compiler settings for .\consumers\declink\DeckLinkAPI.idl:\r
+    Oicf, W1, Zp8, env=Win32 (32b run)\r
+    protocol : dce , ms_ext, c_ext, robust\r
+    error checks: allocation ref bounds_check enum stub_data \r
+    VC __declspec() decoration level: \r
+         __declspec(uuid()), __declspec(selectany), __declspec(novtable)\r
+         DECLSPEC_UUID(), MIDL_INTERFACE()\r
+*/\r
+//@@MIDL_FILE_HEADING(  )\r
+\r
+#pragma warning( disable: 4049 )  /* more than 64k source lines */\r
+\r
+\r
+/* verify that the <rpcndr.h> version is high enough to compile this file*/\r
+#ifndef __REQUIRED_RPCNDR_H_VERSION__\r
+#define __REQUIRED_RPCNDR_H_VERSION__ 475\r
+#endif\r
+\r
+#include "rpc.h"\r
+#include "rpcndr.h"\r
+\r
+#ifndef __RPCNDR_H_VERSION__\r
+#error this stub requires an updated version of <rpcndr.h>\r
+#endif // __RPCNDR_H_VERSION__\r
+\r
+\r
+#ifndef __DeckLinkAPI_h_h__\r
+#define __DeckLinkAPI_h_h__\r
+\r
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)\r
+#pragma once\r
+#endif\r
+\r
+/* Forward Declarations */ \r
+\r
+#ifndef __IDeckLinkVideoOutputCallback_FWD_DEFINED__\r
+#define __IDeckLinkVideoOutputCallback_FWD_DEFINED__\r
+typedef interface IDeckLinkVideoOutputCallback IDeckLinkVideoOutputCallback;\r
+#endif         /* __IDeckLinkVideoOutputCallback_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkInputCallback_FWD_DEFINED__\r
+#define __IDeckLinkInputCallback_FWD_DEFINED__\r
+typedef interface IDeckLinkInputCallback IDeckLinkInputCallback;\r
+#endif         /* __IDeckLinkInputCallback_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkMemoryAllocator_FWD_DEFINED__\r
+#define __IDeckLinkMemoryAllocator_FWD_DEFINED__\r
+typedef interface IDeckLinkMemoryAllocator IDeckLinkMemoryAllocator;\r
+#endif         /* __IDeckLinkMemoryAllocator_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkAudioOutputCallback_FWD_DEFINED__\r
+#define __IDeckLinkAudioOutputCallback_FWD_DEFINED__\r
+typedef interface IDeckLinkAudioOutputCallback IDeckLinkAudioOutputCallback;\r
+#endif         /* __IDeckLinkAudioOutputCallback_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkIterator_FWD_DEFINED__\r
+#define __IDeckLinkIterator_FWD_DEFINED__\r
+typedef interface IDeckLinkIterator IDeckLinkIterator;\r
+#endif         /* __IDeckLinkIterator_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkAPIInformation_FWD_DEFINED__\r
+#define __IDeckLinkAPIInformation_FWD_DEFINED__\r
+typedef interface IDeckLinkAPIInformation IDeckLinkAPIInformation;\r
+#endif         /* __IDeckLinkAPIInformation_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkDisplayModeIterator_FWD_DEFINED__\r
+#define __IDeckLinkDisplayModeIterator_FWD_DEFINED__\r
+typedef interface IDeckLinkDisplayModeIterator IDeckLinkDisplayModeIterator;\r
+#endif         /* __IDeckLinkDisplayModeIterator_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkDisplayMode_FWD_DEFINED__\r
+#define __IDeckLinkDisplayMode_FWD_DEFINED__\r
+typedef interface IDeckLinkDisplayMode IDeckLinkDisplayMode;\r
+#endif         /* __IDeckLinkDisplayMode_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLink_FWD_DEFINED__\r
+#define __IDeckLink_FWD_DEFINED__\r
+typedef interface IDeckLink IDeckLink;\r
+#endif         /* __IDeckLink_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkOutput_FWD_DEFINED__\r
+#define __IDeckLinkOutput_FWD_DEFINED__\r
+typedef interface IDeckLinkOutput IDeckLinkOutput;\r
+#endif         /* __IDeckLinkOutput_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkInput_FWD_DEFINED__\r
+#define __IDeckLinkInput_FWD_DEFINED__\r
+typedef interface IDeckLinkInput IDeckLinkInput;\r
+#endif         /* __IDeckLinkInput_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkTimecode_FWD_DEFINED__\r
+#define __IDeckLinkTimecode_FWD_DEFINED__\r
+typedef interface IDeckLinkTimecode IDeckLinkTimecode;\r
+#endif         /* __IDeckLinkTimecode_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkVideoFrame_FWD_DEFINED__\r
+#define __IDeckLinkVideoFrame_FWD_DEFINED__\r
+typedef interface IDeckLinkVideoFrame IDeckLinkVideoFrame;\r
+#endif         /* __IDeckLinkVideoFrame_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkMutableVideoFrame_FWD_DEFINED__\r
+#define __IDeckLinkMutableVideoFrame_FWD_DEFINED__\r
+typedef interface IDeckLinkMutableVideoFrame IDeckLinkMutableVideoFrame;\r
+#endif         /* __IDeckLinkMutableVideoFrame_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkVideoInputFrame_FWD_DEFINED__\r
+#define __IDeckLinkVideoInputFrame_FWD_DEFINED__\r
+typedef interface IDeckLinkVideoInputFrame IDeckLinkVideoInputFrame;\r
+#endif         /* __IDeckLinkVideoInputFrame_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkVideoFrameAncillary_FWD_DEFINED__\r
+#define __IDeckLinkVideoFrameAncillary_FWD_DEFINED__\r
+typedef interface IDeckLinkVideoFrameAncillary IDeckLinkVideoFrameAncillary;\r
+#endif         /* __IDeckLinkVideoFrameAncillary_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkAudioInputPacket_FWD_DEFINED__\r
+#define __IDeckLinkAudioInputPacket_FWD_DEFINED__\r
+typedef interface IDeckLinkAudioInputPacket IDeckLinkAudioInputPacket;\r
+#endif         /* __IDeckLinkAudioInputPacket_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkScreenPreviewCallback_FWD_DEFINED__\r
+#define __IDeckLinkScreenPreviewCallback_FWD_DEFINED__\r
+typedef interface IDeckLinkScreenPreviewCallback IDeckLinkScreenPreviewCallback;\r
+#endif         /* __IDeckLinkScreenPreviewCallback_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkGLScreenPreviewHelper_FWD_DEFINED__\r
+#define __IDeckLinkGLScreenPreviewHelper_FWD_DEFINED__\r
+typedef interface IDeckLinkGLScreenPreviewHelper IDeckLinkGLScreenPreviewHelper;\r
+#endif         /* __IDeckLinkGLScreenPreviewHelper_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkConfiguration_FWD_DEFINED__\r
+#define __IDeckLinkConfiguration_FWD_DEFINED__\r
+typedef interface IDeckLinkConfiguration IDeckLinkConfiguration;\r
+#endif         /* __IDeckLinkConfiguration_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkAttributes_FWD_DEFINED__\r
+#define __IDeckLinkAttributes_FWD_DEFINED__\r
+typedef interface IDeckLinkAttributes IDeckLinkAttributes;\r
+#endif         /* __IDeckLinkAttributes_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkKeyer_FWD_DEFINED__\r
+#define __IDeckLinkKeyer_FWD_DEFINED__\r
+typedef interface IDeckLinkKeyer IDeckLinkKeyer;\r
+#endif         /* __IDeckLinkKeyer_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __CDeckLinkIterator_FWD_DEFINED__\r
+#define __CDeckLinkIterator_FWD_DEFINED__\r
+\r
+#ifdef __cplusplus\r
+typedef class CDeckLinkIterator CDeckLinkIterator;\r
+#else\r
+typedef struct CDeckLinkIterator CDeckLinkIterator;\r
+#endif /* __cplusplus */\r
+\r
+#endif         /* __CDeckLinkIterator_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __CDeckLinkGLScreenPreviewHelper_FWD_DEFINED__\r
+#define __CDeckLinkGLScreenPreviewHelper_FWD_DEFINED__\r
+\r
+#ifdef __cplusplus\r
+typedef class CDeckLinkGLScreenPreviewHelper CDeckLinkGLScreenPreviewHelper;\r
+#else\r
+typedef struct CDeckLinkGLScreenPreviewHelper CDeckLinkGLScreenPreviewHelper;\r
+#endif /* __cplusplus */\r
+\r
+#endif         /* __CDeckLinkGLScreenPreviewHelper_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkDisplayModeIterator_v7_1_FWD_DEFINED__\r
+#define __IDeckLinkDisplayModeIterator_v7_1_FWD_DEFINED__\r
+typedef interface IDeckLinkDisplayModeIterator_v7_1 IDeckLinkDisplayModeIterator_v7_1;\r
+#endif         /* __IDeckLinkDisplayModeIterator_v7_1_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkDisplayMode_v7_1_FWD_DEFINED__\r
+#define __IDeckLinkDisplayMode_v7_1_FWD_DEFINED__\r
+typedef interface IDeckLinkDisplayMode_v7_1 IDeckLinkDisplayMode_v7_1;\r
+#endif         /* __IDeckLinkDisplayMode_v7_1_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkVideoFrame_v7_1_FWD_DEFINED__\r
+#define __IDeckLinkVideoFrame_v7_1_FWD_DEFINED__\r
+typedef interface IDeckLinkVideoFrame_v7_1 IDeckLinkVideoFrame_v7_1;\r
+#endif         /* __IDeckLinkVideoFrame_v7_1_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkVideoInputFrame_v7_1_FWD_DEFINED__\r
+#define __IDeckLinkVideoInputFrame_v7_1_FWD_DEFINED__\r
+typedef interface IDeckLinkVideoInputFrame_v7_1 IDeckLinkVideoInputFrame_v7_1;\r
+#endif         /* __IDeckLinkVideoInputFrame_v7_1_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkAudioInputPacket_v7_1_FWD_DEFINED__\r
+#define __IDeckLinkAudioInputPacket_v7_1_FWD_DEFINED__\r
+typedef interface IDeckLinkAudioInputPacket_v7_1 IDeckLinkAudioInputPacket_v7_1;\r
+#endif         /* __IDeckLinkAudioInputPacket_v7_1_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkVideoOutputCallback_v7_1_FWD_DEFINED__\r
+#define __IDeckLinkVideoOutputCallback_v7_1_FWD_DEFINED__\r
+typedef interface IDeckLinkVideoOutputCallback_v7_1 IDeckLinkVideoOutputCallback_v7_1;\r
+#endif         /* __IDeckLinkVideoOutputCallback_v7_1_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkInputCallback_v7_1_FWD_DEFINED__\r
+#define __IDeckLinkInputCallback_v7_1_FWD_DEFINED__\r
+typedef interface IDeckLinkInputCallback_v7_1 IDeckLinkInputCallback_v7_1;\r
+#endif         /* __IDeckLinkInputCallback_v7_1_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkOutput_v7_1_FWD_DEFINED__\r
+#define __IDeckLinkOutput_v7_1_FWD_DEFINED__\r
+typedef interface IDeckLinkOutput_v7_1 IDeckLinkOutput_v7_1;\r
+#endif         /* __IDeckLinkOutput_v7_1_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkInput_v7_1_FWD_DEFINED__\r
+#define __IDeckLinkInput_v7_1_FWD_DEFINED__\r
+typedef interface IDeckLinkInput_v7_1 IDeckLinkInput_v7_1;\r
+#endif         /* __IDeckLinkInput_v7_1_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkInputCallback_v7_3_FWD_DEFINED__\r
+#define __IDeckLinkInputCallback_v7_3_FWD_DEFINED__\r
+typedef interface IDeckLinkInputCallback_v7_3 IDeckLinkInputCallback_v7_3;\r
+#endif         /* __IDeckLinkInputCallback_v7_3_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkOutput_v7_3_FWD_DEFINED__\r
+#define __IDeckLinkOutput_v7_3_FWD_DEFINED__\r
+typedef interface IDeckLinkOutput_v7_3 IDeckLinkOutput_v7_3;\r
+#endif         /* __IDeckLinkOutput_v7_3_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkInput_v7_3_FWD_DEFINED__\r
+#define __IDeckLinkInput_v7_3_FWD_DEFINED__\r
+typedef interface IDeckLinkInput_v7_3 IDeckLinkInput_v7_3;\r
+#endif         /* __IDeckLinkInput_v7_3_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkVideoInputFrame_v7_3_FWD_DEFINED__\r
+#define __IDeckLinkVideoInputFrame_v7_3_FWD_DEFINED__\r
+typedef interface IDeckLinkVideoInputFrame_v7_3 IDeckLinkVideoInputFrame_v7_3;\r
+#endif         /* __IDeckLinkVideoInputFrame_v7_3_FWD_DEFINED__ */\r
+\r
+\r
+/* header files for imported files */\r
+#include "unknwn.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C"{\r
+#endif \r
+\r
+\r
+\r
+#ifndef __DeckLinkAPI_LIBRARY_DEFINED__\r
+#define __DeckLinkAPI_LIBRARY_DEFINED__\r
+\r
+/* library DeckLinkAPI */\r
+/* [helpstring][version][uuid] */ \r
+\r
+typedef LONGLONG BMDTimeValue;\r
+\r
+typedef LONGLONG BMDTimeScale;\r
+\r
+typedef unsigned long BMDTimecodeBCD;\r
+\r
+typedef unsigned long BMDFrameFlags;\r
+typedef unsigned long BMDVideoInputFlags;\r
+typedef unsigned long BMDVideoInputFormatChangedEvents;\r
+typedef unsigned long BMDDetectedVideoInputFormatFlags;\r
+typedef unsigned long BMDTimecodeFlags;\r
+typedef unsigned long BMDAnalogVideoFlags;\r
+#if 0\r
+typedef enum _BMDFrameFlags BMDFrameFlags;\r
+\r
+typedef enum _BMDVideoInputFlags BMDVideoInputFlags;\r
+\r
+typedef enum _BMDVideoInputFormatChangedEvents BMDVideoInputFormatChangedEvents;\r
+\r
+typedef enum _BMDDetectedVideoInputFormatFlags BMDDetectedVideoInputFormatFlags;\r
+\r
+typedef enum _BMDTimecodeFlags BMDTimecodeFlags;\r
+\r
+typedef enum _BMDAnalogVideoFlags BMDAnalogVideoFlags;\r
+\r
+#endif\r
+typedef /* [v1_enum] */ \r
+enum _BMDDisplayMode\r
+    {  bmdModeNTSC     = 0x6e747363,\r
+       bmdModeNTSC2398 = 0x6e743233,\r
+       bmdModePAL      = 0x70616c20,\r
+       bmdModeHD1080p2398      = 0x32337073,\r
+       bmdModeHD1080p24        = 0x32347073,\r
+       bmdModeHD1080p25        = 0x48703235,\r
+       bmdModeHD1080p2997      = 0x48703239,\r
+       bmdModeHD1080p30        = 0x48703330,\r
+       bmdModeHD1080i50        = 0x48693530,\r
+       bmdModeHD1080i5994      = 0x48693539,\r
+       bmdModeHD1080i6000      = 0x48693630,\r
+       bmdModeHD1080p50        = 0x48703530,\r
+       bmdModeHD1080p5994      = 0x48703539,\r
+       bmdModeHD1080p6000      = 0x48703630,\r
+       bmdModeHD720p50 = 0x68703530,\r
+       bmdModeHD720p5994       = 0x68703539,\r
+       bmdModeHD720p60 = 0x68703630,\r
+       bmdMode2k2398   = 0x326b3233,\r
+       bmdMode2k24     = 0x326b3234,\r
+       bmdMode2k25     = 0x326b3235\r
+    }  BMDDisplayMode;\r
+\r
+typedef /* [v1_enum] */ \r
+enum _BMDFieldDominance\r
+    {  bmdUnknownFieldDominance        = 0,\r
+       bmdLowerFieldFirst      = 0x6c6f7772,\r
+       bmdUpperFieldFirst      = 0x75707072,\r
+       bmdProgressiveFrame     = 0x70726f67,\r
+       bmdProgressiveSegmentedFrame    = 0x70736620\r
+    }  BMDFieldDominance;\r
+\r
+typedef /* [v1_enum] */ \r
+enum _BMDPixelFormat\r
+    {  bmdFormat8BitYUV        = 0x32767579,\r
+       bmdFormat10BitYUV       = 0x76323130,\r
+       bmdFormat8BitARGB       = 0x20,\r
+       bmdFormat8BitBGRA       = 0x42475241,\r
+       bmdFormat10BitRGB       = 0x72323130\r
+    }  BMDPixelFormat;\r
+\r
+typedef /* [v1_enum] */ \r
+enum _BMDVideoOutputFlags\r
+    {  bmdVideoOutputFlagDefault       = 0,\r
+       bmdVideoOutputRP188     = ( 1 << 0 ) ,\r
+       bmdVideoOutputVANC      = ( 1 << 1 ) \r
+    }  BMDVideoOutputFlags;\r
+\r
+/* [v1_enum] */ \r
+enum _BMDFrameFlags\r
+    {  bmdFrameFlagDefault     = 0,\r
+       bmdFrameFlagFlipVertical        = ( 1 << 0 ) ,\r
+       bmdFrameHasNoInputSource        = ( 1 << 31 ) \r
+    } ;\r
+/* [v1_enum] */ \r
+enum _BMDVideoInputFlags\r
+    {  bmdVideoInputFlagDefault        = 0,\r
+       bmdVideoInputEnableFormatDetection      = ( 1 << 0 ) \r
+    } ;\r
+/* [v1_enum] */ \r
+enum _BMDVideoInputFormatChangedEvents\r
+    {  bmdVideoInputDisplayModeChanged = ( 1 << 0 ) ,\r
+       bmdVideoInputFieldDominanceChanged      = ( 1 << 1 ) ,\r
+       bmdVideoInputColorspaceChanged  = ( 1 << 2 ) \r
+    } ;\r
+/* [v1_enum] */ \r
+enum _BMDDetectedVideoInputFormatFlags\r
+    {  bmdDetectedVideoInputYCbCr422   = ( 1 << 0 ) ,\r
+       bmdDetectedVideoInputRGB444     = ( 1 << 1 ) \r
+    } ;\r
+typedef /* [v1_enum] */ \r
+enum _BMDOutputFrameCompletionResult\r
+    {  bmdOutputFrameCompleted = 0,\r
+       bmdOutputFrameDisplayedLate     = ( bmdOutputFrameCompleted + 1 ) ,\r
+       bmdOutputFrameDropped   = ( bmdOutputFrameDisplayedLate + 1 ) ,\r
+       bmdOutputFrameFlushed   = ( bmdOutputFrameDropped + 1 ) \r
+    }  BMDOutputFrameCompletionResult;\r
+\r
+typedef /* [v1_enum] */ \r
+enum _BMDAudioSampleRate\r
+    {  bmdAudioSampleRate48kHz = 48000\r
+    }  BMDAudioSampleRate;\r
+\r
+typedef /* [v1_enum] */ \r
+enum _BMDAudioSampleType\r
+    {  bmdAudioSampleType16bitInteger  = 16,\r
+       bmdAudioSampleType32bitInteger  = 32\r
+    }  BMDAudioSampleType;\r
+\r
+typedef /* [v1_enum] */ \r
+enum _BMDAudioOutputStreamType\r
+    {  bmdAudioOutputStreamContinuous  = 0,\r
+       bmdAudioOutputStreamContinuousDontResample      = ( bmdAudioOutputStreamContinuous + 1 ) ,\r
+       bmdAudioOutputStreamTimestamped = ( bmdAudioOutputStreamContinuousDontResample + 1 ) \r
+    }  BMDAudioOutputStreamType;\r
+\r
+typedef /* [v1_enum] */ \r
+enum _BMDDisplayModeSupport\r
+    {  bmdDisplayModeNotSupported      = 0,\r
+       bmdDisplayModeSupported = ( bmdDisplayModeNotSupported + 1 ) ,\r
+       bmdDisplayModeSupportedWithConversion   = ( bmdDisplayModeSupported + 1 ) \r
+    }  BMDDisplayModeSupport;\r
+\r
+typedef /* [v1_enum] */ \r
+enum _BMDTimecodeFormat\r
+    {  bmdTimecodeRP188        = 0x72703138,\r
+       bmdTimecodeVITC = 0x76697463,\r
+       bmdTimecodeSerial       = 0x73657269\r
+    }  BMDTimecodeFormat;\r
+\r
+/* [v1_enum] */ \r
+enum _BMDTimecodeFlags\r
+    {  bmdTimecodeFlagDefault  = 0,\r
+       bmdTimecodeIsDropFrame  = ( 1 << 0 ) \r
+    } ;\r
+typedef /* [v1_enum] */ \r
+enum _BMDVideoConnection\r
+    {  bmdVideoConnectionSDI   = 0x73646920,\r
+       bmdVideoConnectionHDMI  = 0x68646d69,\r
+       bmdVideoConnectionOpticalSDI    = 0x6f707469,\r
+       bmdVideoConnectionComponent     = 0x63706e74,\r
+       bmdVideoConnectionComposite     = 0x636d7374,\r
+       bmdVideoConnectionSVideo        = 0x73766964\r
+    }  BMDVideoConnection;\r
+\r
+/* [v1_enum] */ \r
+enum _BMDAnalogVideoFlags\r
+    {  bmdAnalogVideoFlagCompositeSetup75      = ( 1 << 0 ) ,\r
+       bmdAnalogVideoFlagComponentBetacamLevels        = ( 1 << 1 ) \r
+    } ;\r
+typedef /* [v1_enum] */ \r
+enum _BMDAudioConnection\r
+    {  bmdAudioConnectionEmbedded      = 0x656d6264,\r
+       bmdAudioConnectionAESEBU        = 0x61657320,\r
+       bmdAudioConnectionAnalog        = 0x616e6c67\r
+    }  BMDAudioConnection;\r
+\r
+typedef /* [v1_enum] */ \r
+enum _BMDVideoOutputConversionMode\r
+    {  bmdNoVideoOutputConversion      = 0x6e6f6e65,\r
+       bmdVideoOutputLetterboxDownonversion    = 0x6c746278,\r
+       bmdVideoOutputAnamorphicDownonversion   = 0x616d7068,\r
+       bmdVideoOutputHD720toHD1080Conversion   = 0x37323063,\r
+       bmdVideoOutputHardwareLetterboxDownconversion   = 0x48576c62,\r
+       bmdVideoOutputHardwareAnamorphicDownconversion  = 0x4857616d,\r
+       bmdVideoOutputHardwareCenterCutDownconversion   = 0x48576363\r
+    }  BMDVideoOutputConversionMode;\r
+\r
+typedef /* [v1_enum] */ \r
+enum _BMDVideoInputConversionMode\r
+    {  bmdNoVideoInputConversion       = 0x6e6f6e65,\r
+       bmdVideoInputLetterboxDownconversionFromHD1080  = 0x31306c62,\r
+       bmdVideoInputAnamorphicDownconversionFromHD1080 = 0x3130616d,\r
+       bmdVideoInputLetterboxDownconversionFromHD720   = 0x37326c62,\r
+       bmdVideoInputAnamorphicDownconversionFromHD720  = 0x3732616d,\r
+       bmdVideoInputLetterboxUpconversion      = 0x6c627570,\r
+       bmdVideoInputAnamorphicUpconversion     = 0x616d7570\r
+    }  BMDVideoInputConversionMode;\r
+\r
+typedef /* [v1_enum] */ \r
+enum _BMDDeckLinkAttributeID\r
+    {  BMDDeckLinkSupportsInternalKeying       = 0x6b657969,\r
+       BMDDeckLinkSupportsExternalKeying       = 0x6b657965,\r
+       BMDDeckLinkSupportsHDKeying     = 0x6b657968,\r
+       BMDDeckLinkSupportsInputFormatDetection = 0x696e6664,\r
+       BMDDeckLinkHasSerialPort        = 0x68737074,\r
+       BMDDeckLinkMaximumAudioChannels = 0x6d616368,\r
+       BMDDeckLinkSerialPortDeviceName = 0x736c706e\r
+    }  BMDDeckLinkAttributeID;\r
+\r
+typedef /* [v1_enum] */ \r
+enum _BMDDeckLinkAPIInformationID\r
+    {  BMDDeckLinkAPIVersion   = 0x76657273\r
+    }  BMDDeckLinkAPIInformationID;\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+EXTERN_C const IID LIBID_DeckLinkAPI;\r
+\r
+#ifndef __IDeckLinkVideoOutputCallback_INTERFACE_DEFINED__\r
+#define __IDeckLinkVideoOutputCallback_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkVideoOutputCallback */\r
+/* [helpstring][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkVideoOutputCallback;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("E763A626-4A3C-49D1-BF13-E7AD3692AE52")\r
+    IDeckLinkVideoOutputCallback : public IUnknown\r
+    {\r
+    public:\r
+        virtual HRESULT STDMETHODCALLTYPE ScheduledFrameCompleted( \r
+            /* [in] */ IDeckLinkVideoFrame *completedFrame,\r
+            /* [in] */ BMDOutputFrameCompletionResult result) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE ScheduledPlaybackHasStopped( void) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkVideoOutputCallbackVtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkVideoOutputCallback * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkVideoOutputCallback * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkVideoOutputCallback * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *ScheduledFrameCompleted )( \r
+            IDeckLinkVideoOutputCallback * This,\r
+            /* [in] */ IDeckLinkVideoFrame *completedFrame,\r
+            /* [in] */ BMDOutputFrameCompletionResult result);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *ScheduledPlaybackHasStopped )( \r
+            IDeckLinkVideoOutputCallback * This);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkVideoOutputCallbackVtbl;\r
+\r
+    interface IDeckLinkVideoOutputCallback\r
+    {\r
+        CONST_VTBL struct IDeckLinkVideoOutputCallbackVtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkVideoOutputCallback_QueryInterface(This,riid,ppvObject)       \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkVideoOutputCallback_AddRef(This)      \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkVideoOutputCallback_Release(This)     \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkVideoOutputCallback_ScheduledFrameCompleted(This,completedFrame,result)       \\r
+    ( (This)->lpVtbl -> ScheduledFrameCompleted(This,completedFrame,result) ) \r
+\r
+#define IDeckLinkVideoOutputCallback_ScheduledPlaybackHasStopped(This) \\r
+    ( (This)->lpVtbl -> ScheduledPlaybackHasStopped(This) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkVideoOutputCallback_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkInputCallback_INTERFACE_DEFINED__\r
+#define __IDeckLinkInputCallback_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkInputCallback */\r
+/* [helpstring][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkInputCallback;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("31D28EE7-88B6-4CB1-897A-CDBF79A26414")\r
+    IDeckLinkInputCallback : public IUnknown\r
+    {\r
+    public:\r
+        virtual HRESULT STDMETHODCALLTYPE VideoInputFormatChanged( \r
+            /* [in] */ BMDVideoInputFormatChangedEvents notificationEvents,\r
+            /* [in] */ IDeckLinkDisplayMode *newDisplayMode,\r
+            /* [in] */ BMDDetectedVideoInputFormatFlags detectedSignalFlags) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE VideoInputFrameArrived( \r
+            /* [in] */ IDeckLinkVideoInputFrame *videoFrame,\r
+            /* [in] */ IDeckLinkAudioInputPacket *audioPacket) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkInputCallbackVtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkInputCallback * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkInputCallback * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkInputCallback * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *VideoInputFormatChanged )( \r
+            IDeckLinkInputCallback * This,\r
+            /* [in] */ BMDVideoInputFormatChangedEvents notificationEvents,\r
+            /* [in] */ IDeckLinkDisplayMode *newDisplayMode,\r
+            /* [in] */ BMDDetectedVideoInputFormatFlags detectedSignalFlags);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *VideoInputFrameArrived )( \r
+            IDeckLinkInputCallback * This,\r
+            /* [in] */ IDeckLinkVideoInputFrame *videoFrame,\r
+            /* [in] */ IDeckLinkAudioInputPacket *audioPacket);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkInputCallbackVtbl;\r
+\r
+    interface IDeckLinkInputCallback\r
+    {\r
+        CONST_VTBL struct IDeckLinkInputCallbackVtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkInputCallback_QueryInterface(This,riid,ppvObject)     \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkInputCallback_AddRef(This)    \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkInputCallback_Release(This)   \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkInputCallback_VideoInputFormatChanged(This,notificationEvents,newDisplayMode,detectedSignalFlags)     \\r
+    ( (This)->lpVtbl -> VideoInputFormatChanged(This,notificationEvents,newDisplayMode,detectedSignalFlags) ) \r
+\r
+#define IDeckLinkInputCallback_VideoInputFrameArrived(This,videoFrame,audioPacket)     \\r
+    ( (This)->lpVtbl -> VideoInputFrameArrived(This,videoFrame,audioPacket) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkInputCallback_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkMemoryAllocator_INTERFACE_DEFINED__\r
+#define __IDeckLinkMemoryAllocator_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkMemoryAllocator */\r
+/* [helpstring][local][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkMemoryAllocator;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("B36EB6E7-9D29-4AA8-92EF-843B87A289E8")\r
+    IDeckLinkMemoryAllocator : public IUnknown\r
+    {\r
+    public:\r
+        virtual HRESULT STDMETHODCALLTYPE AllocateBuffer( \r
+            unsigned long bufferSize,\r
+            /* [out] */ void **allocatedBuffer) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE ReleaseBuffer( \r
+            /* [in] */ void *buffer) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE Commit( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE Decommit( void) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkMemoryAllocatorVtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkMemoryAllocator * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkMemoryAllocator * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkMemoryAllocator * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *AllocateBuffer )( \r
+            IDeckLinkMemoryAllocator * This,\r
+            unsigned long bufferSize,\r
+            /* [out] */ void **allocatedBuffer);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *ReleaseBuffer )( \r
+            IDeckLinkMemoryAllocator * This,\r
+            /* [in] */ void *buffer);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *Commit )( \r
+            IDeckLinkMemoryAllocator * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *Decommit )( \r
+            IDeckLinkMemoryAllocator * This);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkMemoryAllocatorVtbl;\r
+\r
+    interface IDeckLinkMemoryAllocator\r
+    {\r
+        CONST_VTBL struct IDeckLinkMemoryAllocatorVtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkMemoryAllocator_QueryInterface(This,riid,ppvObject)   \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkMemoryAllocator_AddRef(This)  \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkMemoryAllocator_Release(This) \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkMemoryAllocator_AllocateBuffer(This,bufferSize,allocatedBuffer)       \\r
+    ( (This)->lpVtbl -> AllocateBuffer(This,bufferSize,allocatedBuffer) ) \r
+\r
+#define IDeckLinkMemoryAllocator_ReleaseBuffer(This,buffer)    \\r
+    ( (This)->lpVtbl -> ReleaseBuffer(This,buffer) ) \r
+\r
+#define IDeckLinkMemoryAllocator_Commit(This)  \\r
+    ( (This)->lpVtbl -> Commit(This) ) \r
+\r
+#define IDeckLinkMemoryAllocator_Decommit(This)        \\r
+    ( (This)->lpVtbl -> Decommit(This) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkMemoryAllocator_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkAudioOutputCallback_INTERFACE_DEFINED__\r
+#define __IDeckLinkAudioOutputCallback_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkAudioOutputCallback */\r
+/* [helpstring][local][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkAudioOutputCallback;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("403C681B-7F46-4A12-B993-2BB127084EE6")\r
+    IDeckLinkAudioOutputCallback : public IUnknown\r
+    {\r
+    public:\r
+        virtual HRESULT STDMETHODCALLTYPE RenderAudioSamples( \r
+            BOOL preroll) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkAudioOutputCallbackVtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkAudioOutputCallback * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkAudioOutputCallback * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkAudioOutputCallback * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *RenderAudioSamples )( \r
+            IDeckLinkAudioOutputCallback * This,\r
+            BOOL preroll);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkAudioOutputCallbackVtbl;\r
+\r
+    interface IDeckLinkAudioOutputCallback\r
+    {\r
+        CONST_VTBL struct IDeckLinkAudioOutputCallbackVtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkAudioOutputCallback_QueryInterface(This,riid,ppvObject)       \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkAudioOutputCallback_AddRef(This)      \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkAudioOutputCallback_Release(This)     \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkAudioOutputCallback_RenderAudioSamples(This,preroll)  \\r
+    ( (This)->lpVtbl -> RenderAudioSamples(This,preroll) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkAudioOutputCallback_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkIterator_INTERFACE_DEFINED__\r
+#define __IDeckLinkIterator_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkIterator */\r
+/* [helpstring][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkIterator;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("74E936FC-CC28-4A67-81A0-1E94E52D4E69")\r
+    IDeckLinkIterator : public IUnknown\r
+    {\r
+    public:\r
+        virtual HRESULT STDMETHODCALLTYPE Next( \r
+            /* [out] */ IDeckLink **deckLinkInstance) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkIteratorVtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkIterator * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkIterator * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkIterator * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *Next )( \r
+            IDeckLinkIterator * This,\r
+            /* [out] */ IDeckLink **deckLinkInstance);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkIteratorVtbl;\r
+\r
+    interface IDeckLinkIterator\r
+    {\r
+        CONST_VTBL struct IDeckLinkIteratorVtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkIterator_QueryInterface(This,riid,ppvObject)  \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkIterator_AddRef(This) \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkIterator_Release(This)        \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkIterator_Next(This,deckLinkInstance)  \\r
+    ( (This)->lpVtbl -> Next(This,deckLinkInstance) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkIterator_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkAPIInformation_INTERFACE_DEFINED__\r
+#define __IDeckLinkAPIInformation_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkAPIInformation */\r
+/* [helpstring][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkAPIInformation;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("7BEA3C68-730D-4322-AF34-8A7152B532A4")\r
+    IDeckLinkAPIInformation : public IUnknown\r
+    {\r
+    public:\r
+        virtual HRESULT STDMETHODCALLTYPE GetFlag( \r
+            /* [in] */ BMDDeckLinkAPIInformationID cfgID,\r
+            /* [out] */ BOOL *value) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetInt( \r
+            /* [in] */ BMDDeckLinkAPIInformationID cfgID,\r
+            /* [out] */ LONGLONG *value) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetFloat( \r
+            /* [in] */ BMDDeckLinkAPIInformationID cfgID,\r
+            /* [out] */ double *value) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetString( \r
+            /* [in] */ BMDDeckLinkAPIInformationID cfgID,\r
+            /* [out] */ BSTR *value) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkAPIInformationVtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkAPIInformation * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkAPIInformation * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkAPIInformation * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetFlag )( \r
+            IDeckLinkAPIInformation * This,\r
+            /* [in] */ BMDDeckLinkAPIInformationID cfgID,\r
+            /* [out] */ BOOL *value);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetInt )( \r
+            IDeckLinkAPIInformation * This,\r
+            /* [in] */ BMDDeckLinkAPIInformationID cfgID,\r
+            /* [out] */ LONGLONG *value);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetFloat )( \r
+            IDeckLinkAPIInformation * This,\r
+            /* [in] */ BMDDeckLinkAPIInformationID cfgID,\r
+            /* [out] */ double *value);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetString )( \r
+            IDeckLinkAPIInformation * This,\r
+            /* [in] */ BMDDeckLinkAPIInformationID cfgID,\r
+            /* [out] */ BSTR *value);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkAPIInformationVtbl;\r
+\r
+    interface IDeckLinkAPIInformation\r
+    {\r
+        CONST_VTBL struct IDeckLinkAPIInformationVtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkAPIInformation_QueryInterface(This,riid,ppvObject)    \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkAPIInformation_AddRef(This)   \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkAPIInformation_Release(This)  \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkAPIInformation_GetFlag(This,cfgID,value)      \\r
+    ( (This)->lpVtbl -> GetFlag(This,cfgID,value) ) \r
+\r
+#define IDeckLinkAPIInformation_GetInt(This,cfgID,value)       \\r
+    ( (This)->lpVtbl -> GetInt(This,cfgID,value) ) \r
+\r
+#define IDeckLinkAPIInformation_GetFloat(This,cfgID,value)     \\r
+    ( (This)->lpVtbl -> GetFloat(This,cfgID,value) ) \r
+\r
+#define IDeckLinkAPIInformation_GetString(This,cfgID,value)    \\r
+    ( (This)->lpVtbl -> GetString(This,cfgID,value) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkAPIInformation_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkDisplayModeIterator_INTERFACE_DEFINED__\r
+#define __IDeckLinkDisplayModeIterator_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkDisplayModeIterator */\r
+/* [helpstring][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkDisplayModeIterator;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("455D741F-1779-4800-86F5-0B5D13D79751")\r
+    IDeckLinkDisplayModeIterator : public IUnknown\r
+    {\r
+    public:\r
+        virtual HRESULT STDMETHODCALLTYPE Next( \r
+            /* [out] */ IDeckLinkDisplayMode **deckLinkDisplayMode) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkDisplayModeIteratorVtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkDisplayModeIterator * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkDisplayModeIterator * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkDisplayModeIterator * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *Next )( \r
+            IDeckLinkDisplayModeIterator * This,\r
+            /* [out] */ IDeckLinkDisplayMode **deckLinkDisplayMode);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkDisplayModeIteratorVtbl;\r
+\r
+    interface IDeckLinkDisplayModeIterator\r
+    {\r
+        CONST_VTBL struct IDeckLinkDisplayModeIteratorVtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkDisplayModeIterator_QueryInterface(This,riid,ppvObject)       \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkDisplayModeIterator_AddRef(This)      \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkDisplayModeIterator_Release(This)     \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkDisplayModeIterator_Next(This,deckLinkDisplayMode)    \\r
+    ( (This)->lpVtbl -> Next(This,deckLinkDisplayMode) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkDisplayModeIterator_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkDisplayMode_INTERFACE_DEFINED__\r
+#define __IDeckLinkDisplayMode_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkDisplayMode */\r
+/* [helpstring][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkDisplayMode;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("87451E84-2B7E-439E-A629-4393EA4A8550")\r
+    IDeckLinkDisplayMode : public IUnknown\r
+    {\r
+    public:\r
+        virtual HRESULT STDMETHODCALLTYPE GetName( \r
+            /* [out] */ BSTR *name) = 0;\r
+        \r
+        virtual BMDDisplayMode STDMETHODCALLTYPE GetDisplayMode( void) = 0;\r
+        \r
+        virtual long STDMETHODCALLTYPE GetWidth( void) = 0;\r
+        \r
+        virtual long STDMETHODCALLTYPE GetHeight( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetFrameRate( \r
+            /* [out] */ BMDTimeValue *frameDuration,\r
+            /* [out] */ BMDTimeScale *timeScale) = 0;\r
+        \r
+        virtual BMDFieldDominance STDMETHODCALLTYPE GetFieldDominance( void) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkDisplayModeVtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkDisplayMode * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkDisplayMode * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkDisplayMode * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetName )( \r
+            IDeckLinkDisplayMode * This,\r
+            /* [out] */ BSTR *name);\r
+        \r
+        BMDDisplayMode ( STDMETHODCALLTYPE *GetDisplayMode )( \r
+            IDeckLinkDisplayMode * This);\r
+        \r
+        long ( STDMETHODCALLTYPE *GetWidth )( \r
+            IDeckLinkDisplayMode * This);\r
+        \r
+        long ( STDMETHODCALLTYPE *GetHeight )( \r
+            IDeckLinkDisplayMode * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetFrameRate )( \r
+            IDeckLinkDisplayMode * This,\r
+            /* [out] */ BMDTimeValue *frameDuration,\r
+            /* [out] */ BMDTimeScale *timeScale);\r
+        \r
+        BMDFieldDominance ( STDMETHODCALLTYPE *GetFieldDominance )( \r
+            IDeckLinkDisplayMode * This);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkDisplayModeVtbl;\r
+\r
+    interface IDeckLinkDisplayMode\r
+    {\r
+        CONST_VTBL struct IDeckLinkDisplayModeVtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkDisplayMode_QueryInterface(This,riid,ppvObject)       \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkDisplayMode_AddRef(This)      \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkDisplayMode_Release(This)     \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkDisplayMode_GetName(This,name)        \\r
+    ( (This)->lpVtbl -> GetName(This,name) ) \r
+\r
+#define IDeckLinkDisplayMode_GetDisplayMode(This)      \\r
+    ( (This)->lpVtbl -> GetDisplayMode(This) ) \r
+\r
+#define IDeckLinkDisplayMode_GetWidth(This)    \\r
+    ( (This)->lpVtbl -> GetWidth(This) ) \r
+\r
+#define IDeckLinkDisplayMode_GetHeight(This)   \\r
+    ( (This)->lpVtbl -> GetHeight(This) ) \r
+\r
+#define IDeckLinkDisplayMode_GetFrameRate(This,frameDuration,timeScale)        \\r
+    ( (This)->lpVtbl -> GetFrameRate(This,frameDuration,timeScale) ) \r
+\r
+#define IDeckLinkDisplayMode_GetFieldDominance(This)   \\r
+    ( (This)->lpVtbl -> GetFieldDominance(This) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkDisplayMode_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLink_INTERFACE_DEFINED__\r
+#define __IDeckLink_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLink */\r
+/* [helpstring][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLink;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("62BFF75D-6569-4E55-8D4D-66AA03829ABC")\r
+    IDeckLink : public IUnknown\r
+    {\r
+    public:\r
+        virtual HRESULT STDMETHODCALLTYPE GetModelName( \r
+            /* [out] */ BSTR *modelName) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkVtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLink * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLink * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLink * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetModelName )( \r
+            IDeckLink * This,\r
+            /* [out] */ BSTR *modelName);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkVtbl;\r
+\r
+    interface IDeckLink\r
+    {\r
+        CONST_VTBL struct IDeckLinkVtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLink_QueryInterface(This,riid,ppvObject)  \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLink_AddRef(This) \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLink_Release(This)        \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLink_GetModelName(This,modelName) \\r
+    ( (This)->lpVtbl -> GetModelName(This,modelName) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLink_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkOutput_INTERFACE_DEFINED__\r
+#define __IDeckLinkOutput_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkOutput */\r
+/* [helpstring][local][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkOutput;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("29228142-EB8C-4141-A621-F74026450955")\r
+    IDeckLinkOutput : public IUnknown\r
+    {\r
+    public:\r
+        virtual HRESULT STDMETHODCALLTYPE DoesSupportVideoMode( \r
+            BMDDisplayMode displayMode,\r
+            BMDPixelFormat pixelFormat,\r
+            /* [out] */ BMDDisplayModeSupport *result) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetDisplayModeIterator( \r
+            /* [out] */ IDeckLinkDisplayModeIterator **iterator) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE SetScreenPreviewCallback( \r
+            /* [in] */ IDeckLinkScreenPreviewCallback *previewCallback) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE EnableVideoOutput( \r
+            BMDDisplayMode displayMode,\r
+            BMDVideoOutputFlags flags) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE DisableVideoOutput( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE SetVideoOutputFrameMemoryAllocator( \r
+            /* [in] */ IDeckLinkMemoryAllocator *theAllocator) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE CreateVideoFrame( \r
+            long width,\r
+            long height,\r
+            long rowBytes,\r
+            BMDPixelFormat pixelFormat,\r
+            BMDFrameFlags flags,\r
+            /* [out] */ IDeckLinkMutableVideoFrame **outFrame) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE CreateAncillaryData( \r
+            BMDDisplayMode displayMode,\r
+            BMDPixelFormat pixelFormat,\r
+            /* [out] */ IDeckLinkVideoFrameAncillary **outBuffer) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE DisplayVideoFrameSync( \r
+            /* [in] */ IDeckLinkVideoFrame *theFrame) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE ScheduleVideoFrame( \r
+            /* [in] */ IDeckLinkVideoFrame *theFrame,\r
+            BMDTimeValue displayTime,\r
+            BMDTimeValue displayDuration,\r
+            BMDTimeScale timeScale) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE SetScheduledFrameCompletionCallback( \r
+            /* [in] */ IDeckLinkVideoOutputCallback *theCallback) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetBufferedVideoFrameCount( \r
+            /* [out] */ unsigned long *bufferedFrameCount) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE EnableAudioOutput( \r
+            BMDAudioSampleRate sampleRate,\r
+            BMDAudioSampleType sampleType,\r
+            unsigned long channelCount,\r
+            BMDAudioOutputStreamType streamType) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE DisableAudioOutput( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE WriteAudioSamplesSync( \r
+            /* [in] */ void *buffer,\r
+            unsigned long sampleFrameCount,\r
+            /* [out] */ unsigned long *sampleFramesWritten) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE BeginAudioPreroll( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE EndAudioPreroll( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE ScheduleAudioSamples( \r
+            /* [in] */ void *buffer,\r
+            unsigned long sampleFrameCount,\r
+            BMDTimeValue streamTime,\r
+            BMDTimeScale timeScale,\r
+            /* [out] */ unsigned long *sampleFramesWritten) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetBufferedAudioSampleFrameCount( \r
+            /* [out] */ unsigned long *bufferedSampleFrameCount) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE FlushBufferedAudioSamples( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE SetAudioCallback( \r
+            /* [in] */ IDeckLinkAudioOutputCallback *theCallback) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE StartScheduledPlayback( \r
+            BMDTimeValue playbackStartTime,\r
+            BMDTimeScale timeScale,\r
+            double playbackSpeed) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE StopScheduledPlayback( \r
+            BMDTimeValue stopPlaybackAtTime,\r
+            /* [out] */ BMDTimeValue *actualStopTime,\r
+            BMDTimeScale timeScale) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE IsScheduledPlaybackRunning( \r
+            /* [out] */ BOOL *active) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetScheduledStreamTime( \r
+            BMDTimeScale desiredTimeScale,\r
+            /* [out] */ BMDTimeValue *streamTime,\r
+            /* [out] */ double *playbackSpeed) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetHardwareReferenceClock( \r
+            BMDTimeScale desiredTimeScale,\r
+            /* [out] */ BMDTimeValue *hardwareTime,\r
+            /* [out] */ BMDTimeValue *timeInFrame,\r
+            /* [out] */ BMDTimeValue *ticksPerFrame) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkOutputVtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkOutput * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkOutput * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkOutput * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *DoesSupportVideoMode )( \r
+            IDeckLinkOutput * This,\r
+            BMDDisplayMode displayMode,\r
+            BMDPixelFormat pixelFormat,\r
+            /* [out] */ BMDDisplayModeSupport *result);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetDisplayModeIterator )( \r
+            IDeckLinkOutput * This,\r
+            /* [out] */ IDeckLinkDisplayModeIterator **iterator);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetScreenPreviewCallback )( \r
+            IDeckLinkOutput * This,\r
+            /* [in] */ IDeckLinkScreenPreviewCallback *previewCallback);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *EnableVideoOutput )( \r
+            IDeckLinkOutput * This,\r
+            BMDDisplayMode displayMode,\r
+            BMDVideoOutputFlags flags);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *DisableVideoOutput )( \r
+            IDeckLinkOutput * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetVideoOutputFrameMemoryAllocator )( \r
+            IDeckLinkOutput * This,\r
+            /* [in] */ IDeckLinkMemoryAllocator *theAllocator);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *CreateVideoFrame )( \r
+            IDeckLinkOutput * This,\r
+            long width,\r
+            long height,\r
+            long rowBytes,\r
+            BMDPixelFormat pixelFormat,\r
+            BMDFrameFlags flags,\r
+            /* [out] */ IDeckLinkMutableVideoFrame **outFrame);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *CreateAncillaryData )( \r
+            IDeckLinkOutput * This,\r
+            BMDDisplayMode displayMode,\r
+            BMDPixelFormat pixelFormat,\r
+            /* [out] */ IDeckLinkVideoFrameAncillary **outBuffer);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *DisplayVideoFrameSync )( \r
+            IDeckLinkOutput * This,\r
+            /* [in] */ IDeckLinkVideoFrame *theFrame);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *ScheduleVideoFrame )( \r
+            IDeckLinkOutput * This,\r
+            /* [in] */ IDeckLinkVideoFrame *theFrame,\r
+            BMDTimeValue displayTime,\r
+            BMDTimeValue displayDuration,\r
+            BMDTimeScale timeScale);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetScheduledFrameCompletionCallback )( \r
+            IDeckLinkOutput * This,\r
+            /* [in] */ IDeckLinkVideoOutputCallback *theCallback);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetBufferedVideoFrameCount )( \r
+            IDeckLinkOutput * This,\r
+            /* [out] */ unsigned long *bufferedFrameCount);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *EnableAudioOutput )( \r
+            IDeckLinkOutput * This,\r
+            BMDAudioSampleRate sampleRate,\r
+            BMDAudioSampleType sampleType,\r
+            unsigned long channelCount,\r
+            BMDAudioOutputStreamType streamType);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *DisableAudioOutput )( \r
+            IDeckLinkOutput * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *WriteAudioSamplesSync )( \r
+            IDeckLinkOutput * This,\r
+            /* [in] */ void *buffer,\r
+            unsigned long sampleFrameCount,\r
+            /* [out] */ unsigned long *sampleFramesWritten);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *BeginAudioPreroll )( \r
+            IDeckLinkOutput * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *EndAudioPreroll )( \r
+            IDeckLinkOutput * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *ScheduleAudioSamples )( \r
+            IDeckLinkOutput * This,\r
+            /* [in] */ void *buffer,\r
+            unsigned long sampleFrameCount,\r
+            BMDTimeValue streamTime,\r
+            BMDTimeScale timeScale,\r
+            /* [out] */ unsigned long *sampleFramesWritten);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetBufferedAudioSampleFrameCount )( \r
+            IDeckLinkOutput * This,\r
+            /* [out] */ unsigned long *bufferedSampleFrameCount);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *FlushBufferedAudioSamples )( \r
+            IDeckLinkOutput * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetAudioCallback )( \r
+            IDeckLinkOutput * This,\r
+            /* [in] */ IDeckLinkAudioOutputCallback *theCallback);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *StartScheduledPlayback )( \r
+            IDeckLinkOutput * This,\r
+            BMDTimeValue playbackStartTime,\r
+            BMDTimeScale timeScale,\r
+            double playbackSpeed);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *StopScheduledPlayback )( \r
+            IDeckLinkOutput * This,\r
+            BMDTimeValue stopPlaybackAtTime,\r
+            /* [out] */ BMDTimeValue *actualStopTime,\r
+            BMDTimeScale timeScale);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *IsScheduledPlaybackRunning )( \r
+            IDeckLinkOutput * This,\r
+            /* [out] */ BOOL *active);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetScheduledStreamTime )( \r
+            IDeckLinkOutput * This,\r
+            BMDTimeScale desiredTimeScale,\r
+            /* [out] */ BMDTimeValue *streamTime,\r
+            /* [out] */ double *playbackSpeed);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetHardwareReferenceClock )( \r
+            IDeckLinkOutput * This,\r
+            BMDTimeScale desiredTimeScale,\r
+            /* [out] */ BMDTimeValue *hardwareTime,\r
+            /* [out] */ BMDTimeValue *timeInFrame,\r
+            /* [out] */ BMDTimeValue *ticksPerFrame);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkOutputVtbl;\r
+\r
+    interface IDeckLinkOutput\r
+    {\r
+        CONST_VTBL struct IDeckLinkOutputVtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkOutput_QueryInterface(This,riid,ppvObject)    \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkOutput_AddRef(This)   \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkOutput_Release(This)  \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkOutput_DoesSupportVideoMode(This,displayMode,pixelFormat,result)      \\r
+    ( (This)->lpVtbl -> DoesSupportVideoMode(This,displayMode,pixelFormat,result) ) \r
+\r
+#define IDeckLinkOutput_GetDisplayModeIterator(This,iterator)  \\r
+    ( (This)->lpVtbl -> GetDisplayModeIterator(This,iterator) ) \r
+\r
+#define IDeckLinkOutput_SetScreenPreviewCallback(This,previewCallback) \\r
+    ( (This)->lpVtbl -> SetScreenPreviewCallback(This,previewCallback) ) \r
+\r
+#define IDeckLinkOutput_EnableVideoOutput(This,displayMode,flags)      \\r
+    ( (This)->lpVtbl -> EnableVideoOutput(This,displayMode,flags) ) \r
+\r
+#define IDeckLinkOutput_DisableVideoOutput(This)       \\r
+    ( (This)->lpVtbl -> DisableVideoOutput(This) ) \r
+\r
+#define IDeckLinkOutput_SetVideoOutputFrameMemoryAllocator(This,theAllocator)  \\r
+    ( (This)->lpVtbl -> SetVideoOutputFrameMemoryAllocator(This,theAllocator) ) \r
+\r
+#define IDeckLinkOutput_CreateVideoFrame(This,width,height,rowBytes,pixelFormat,flags,outFrame)        \\r
+    ( (This)->lpVtbl -> CreateVideoFrame(This,width,height,rowBytes,pixelFormat,flags,outFrame) ) \r
+\r
+#define IDeckLinkOutput_CreateAncillaryData(This,displayMode,pixelFormat,outBuffer)    \\r
+    ( (This)->lpVtbl -> CreateAncillaryData(This,displayMode,pixelFormat,outBuffer) ) \r
+\r
+#define IDeckLinkOutput_DisplayVideoFrameSync(This,theFrame)   \\r
+    ( (This)->lpVtbl -> DisplayVideoFrameSync(This,theFrame) ) \r
+\r
+#define IDeckLinkOutput_ScheduleVideoFrame(This,theFrame,displayTime,displayDuration,timeScale)        \\r
+    ( (This)->lpVtbl -> ScheduleVideoFrame(This,theFrame,displayTime,displayDuration,timeScale) ) \r
+\r
+#define IDeckLinkOutput_SetScheduledFrameCompletionCallback(This,theCallback)  \\r
+    ( (This)->lpVtbl -> SetScheduledFrameCompletionCallback(This,theCallback) ) \r
+\r
+#define IDeckLinkOutput_GetBufferedVideoFrameCount(This,bufferedFrameCount)    \\r
+    ( (This)->lpVtbl -> GetBufferedVideoFrameCount(This,bufferedFrameCount) ) \r
+\r
+#define IDeckLinkOutput_EnableAudioOutput(This,sampleRate,sampleType,channelCount,streamType)  \\r
+    ( (This)->lpVtbl -> EnableAudioOutput(This,sampleRate,sampleType,channelCount,streamType) ) \r
+\r
+#define IDeckLinkOutput_DisableAudioOutput(This)       \\r
+    ( (This)->lpVtbl -> DisableAudioOutput(This) ) \r
+\r
+#define IDeckLinkOutput_WriteAudioSamplesSync(This,buffer,sampleFrameCount,sampleFramesWritten)        \\r
+    ( (This)->lpVtbl -> WriteAudioSamplesSync(This,buffer,sampleFrameCount,sampleFramesWritten) ) \r
+\r
+#define IDeckLinkOutput_BeginAudioPreroll(This)        \\r
+    ( (This)->lpVtbl -> BeginAudioPreroll(This) ) \r
+\r
+#define IDeckLinkOutput_EndAudioPreroll(This)  \\r
+    ( (This)->lpVtbl -> EndAudioPreroll(This) ) \r
+\r
+#define IDeckLinkOutput_ScheduleAudioSamples(This,buffer,sampleFrameCount,streamTime,timeScale,sampleFramesWritten)    \\r
+    ( (This)->lpVtbl -> ScheduleAudioSamples(This,buffer,sampleFrameCount,streamTime,timeScale,sampleFramesWritten) ) \r
+\r
+#define IDeckLinkOutput_GetBufferedAudioSampleFrameCount(This,bufferedSampleFrameCount)        \\r
+    ( (This)->lpVtbl -> GetBufferedAudioSampleFrameCount(This,bufferedSampleFrameCount) ) \r
+\r
+#define IDeckLinkOutput_FlushBufferedAudioSamples(This)        \\r
+    ( (This)->lpVtbl -> FlushBufferedAudioSamples(This) ) \r
+\r
+#define IDeckLinkOutput_SetAudioCallback(This,theCallback)     \\r
+    ( (This)->lpVtbl -> SetAudioCallback(This,theCallback) ) \r
+\r
+#define IDeckLinkOutput_StartScheduledPlayback(This,playbackStartTime,timeScale,playbackSpeed) \\r
+    ( (This)->lpVtbl -> StartScheduledPlayback(This,playbackStartTime,timeScale,playbackSpeed) ) \r
+\r
+#define IDeckLinkOutput_StopScheduledPlayback(This,stopPlaybackAtTime,actualStopTime,timeScale)        \\r
+    ( (This)->lpVtbl -> StopScheduledPlayback(This,stopPlaybackAtTime,actualStopTime,timeScale) ) \r
+\r
+#define IDeckLinkOutput_IsScheduledPlaybackRunning(This,active)        \\r
+    ( (This)->lpVtbl -> IsScheduledPlaybackRunning(This,active) ) \r
+\r
+#define IDeckLinkOutput_GetScheduledStreamTime(This,desiredTimeScale,streamTime,playbackSpeed) \\r
+    ( (This)->lpVtbl -> GetScheduledStreamTime(This,desiredTimeScale,streamTime,playbackSpeed) ) \r
+\r
+#define IDeckLinkOutput_GetHardwareReferenceClock(This,desiredTimeScale,hardwareTime,timeInFrame,ticksPerFrame)        \\r
+    ( (This)->lpVtbl -> GetHardwareReferenceClock(This,desiredTimeScale,hardwareTime,timeInFrame,ticksPerFrame) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkOutput_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkInput_INTERFACE_DEFINED__\r
+#define __IDeckLinkInput_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkInput */\r
+/* [helpstring][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkInput;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("300C135A-9F43-48E2-9906-6D7911D93CF1")\r
+    IDeckLinkInput : public IUnknown\r
+    {\r
+    public:\r
+        virtual HRESULT STDMETHODCALLTYPE DoesSupportVideoMode( \r
+            BMDDisplayMode displayMode,\r
+            BMDPixelFormat pixelFormat,\r
+            /* [out] */ BMDDisplayModeSupport *result) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetDisplayModeIterator( \r
+            /* [out] */ IDeckLinkDisplayModeIterator **iterator) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE SetScreenPreviewCallback( \r
+            /* [in] */ IDeckLinkScreenPreviewCallback *previewCallback) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE EnableVideoInput( \r
+            BMDDisplayMode displayMode,\r
+            BMDPixelFormat pixelFormat,\r
+            BMDVideoInputFlags flags) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE DisableVideoInput( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetAvailableVideoFrameCount( \r
+            /* [out] */ unsigned long *availableFrameCount) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE EnableAudioInput( \r
+            BMDAudioSampleRate sampleRate,\r
+            BMDAudioSampleType sampleType,\r
+            unsigned long channelCount) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE DisableAudioInput( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetAvailableAudioSampleFrameCount( \r
+            /* [out] */ unsigned long *availableSampleFrameCount) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE StartStreams( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE StopStreams( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE PauseStreams( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE FlushStreams( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE SetCallback( \r
+            /* [in] */ IDeckLinkInputCallback *theCallback) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetHardwareReferenceClock( \r
+            BMDTimeScale desiredTimeScale,\r
+            /* [out] */ BMDTimeValue *hardwareTime,\r
+            /* [out] */ BMDTimeValue *timeInFrame,\r
+            /* [out] */ BMDTimeValue *ticksPerFrame) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkInputVtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkInput * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkInput * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkInput * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *DoesSupportVideoMode )( \r
+            IDeckLinkInput * This,\r
+            BMDDisplayMode displayMode,\r
+            BMDPixelFormat pixelFormat,\r
+            /* [out] */ BMDDisplayModeSupport *result);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetDisplayModeIterator )( \r
+            IDeckLinkInput * This,\r
+            /* [out] */ IDeckLinkDisplayModeIterator **iterator);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetScreenPreviewCallback )( \r
+            IDeckLinkInput * This,\r
+            /* [in] */ IDeckLinkScreenPreviewCallback *previewCallback);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *EnableVideoInput )( \r
+            IDeckLinkInput * This,\r
+            BMDDisplayMode displayMode,\r
+            BMDPixelFormat pixelFormat,\r
+            BMDVideoInputFlags flags);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *DisableVideoInput )( \r
+            IDeckLinkInput * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetAvailableVideoFrameCount )( \r
+            IDeckLinkInput * This,\r
+            /* [out] */ unsigned long *availableFrameCount);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *EnableAudioInput )( \r
+            IDeckLinkInput * This,\r
+            BMDAudioSampleRate sampleRate,\r
+            BMDAudioSampleType sampleType,\r
+            unsigned long channelCount);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *DisableAudioInput )( \r
+            IDeckLinkInput * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetAvailableAudioSampleFrameCount )( \r
+            IDeckLinkInput * This,\r
+            /* [out] */ unsigned long *availableSampleFrameCount);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *StartStreams )( \r
+            IDeckLinkInput * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *StopStreams )( \r
+            IDeckLinkInput * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *PauseStreams )( \r
+            IDeckLinkInput * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *FlushStreams )( \r
+            IDeckLinkInput * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetCallback )( \r
+            IDeckLinkInput * This,\r
+            /* [in] */ IDeckLinkInputCallback *theCallback);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetHardwareReferenceClock )( \r
+            IDeckLinkInput * This,\r
+            BMDTimeScale desiredTimeScale,\r
+            /* [out] */ BMDTimeValue *hardwareTime,\r
+            /* [out] */ BMDTimeValue *timeInFrame,\r
+            /* [out] */ BMDTimeValue *ticksPerFrame);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkInputVtbl;\r
+\r
+    interface IDeckLinkInput\r
+    {\r
+        CONST_VTBL struct IDeckLinkInputVtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkInput_QueryInterface(This,riid,ppvObject)     \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkInput_AddRef(This)    \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkInput_Release(This)   \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkInput_DoesSupportVideoMode(This,displayMode,pixelFormat,result)       \\r
+    ( (This)->lpVtbl -> DoesSupportVideoMode(This,displayMode,pixelFormat,result) ) \r
+\r
+#define IDeckLinkInput_GetDisplayModeIterator(This,iterator)   \\r
+    ( (This)->lpVtbl -> GetDisplayModeIterator(This,iterator) ) \r
+\r
+#define IDeckLinkInput_SetScreenPreviewCallback(This,previewCallback)  \\r
+    ( (This)->lpVtbl -> SetScreenPreviewCallback(This,previewCallback) ) \r
+\r
+#define IDeckLinkInput_EnableVideoInput(This,displayMode,pixelFormat,flags)    \\r
+    ( (This)->lpVtbl -> EnableVideoInput(This,displayMode,pixelFormat,flags) ) \r
+\r
+#define IDeckLinkInput_DisableVideoInput(This) \\r
+    ( (This)->lpVtbl -> DisableVideoInput(This) ) \r
+\r
+#define IDeckLinkInput_GetAvailableVideoFrameCount(This,availableFrameCount)   \\r
+    ( (This)->lpVtbl -> GetAvailableVideoFrameCount(This,availableFrameCount) ) \r
+\r
+#define IDeckLinkInput_EnableAudioInput(This,sampleRate,sampleType,channelCount)       \\r
+    ( (This)->lpVtbl -> EnableAudioInput(This,sampleRate,sampleType,channelCount) ) \r
+\r
+#define IDeckLinkInput_DisableAudioInput(This) \\r
+    ( (This)->lpVtbl -> DisableAudioInput(This) ) \r
+\r
+#define IDeckLinkInput_GetAvailableAudioSampleFrameCount(This,availableSampleFrameCount)       \\r
+    ( (This)->lpVtbl -> GetAvailableAudioSampleFrameCount(This,availableSampleFrameCount) ) \r
+\r
+#define IDeckLinkInput_StartStreams(This)      \\r
+    ( (This)->lpVtbl -> StartStreams(This) ) \r
+\r
+#define IDeckLinkInput_StopStreams(This)       \\r
+    ( (This)->lpVtbl -> StopStreams(This) ) \r
+\r
+#define IDeckLinkInput_PauseStreams(This)      \\r
+    ( (This)->lpVtbl -> PauseStreams(This) ) \r
+\r
+#define IDeckLinkInput_FlushStreams(This)      \\r
+    ( (This)->lpVtbl -> FlushStreams(This) ) \r
+\r
+#define IDeckLinkInput_SetCallback(This,theCallback)   \\r
+    ( (This)->lpVtbl -> SetCallback(This,theCallback) ) \r
+\r
+#define IDeckLinkInput_GetHardwareReferenceClock(This,desiredTimeScale,hardwareTime,timeInFrame,ticksPerFrame) \\r
+    ( (This)->lpVtbl -> GetHardwareReferenceClock(This,desiredTimeScale,hardwareTime,timeInFrame,ticksPerFrame) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkInput_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkTimecode_INTERFACE_DEFINED__\r
+#define __IDeckLinkTimecode_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkTimecode */\r
+/* [helpstring][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkTimecode;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("EFB9BCA6-A521-44F7-BD69-2332F24D9EE6")\r
+    IDeckLinkTimecode : public IUnknown\r
+    {\r
+    public:\r
+        virtual BMDTimecodeBCD STDMETHODCALLTYPE GetBCD( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetComponents( \r
+            /* [out] */ unsigned char *hours,\r
+            /* [out] */ unsigned char *minutes,\r
+            /* [out] */ unsigned char *seconds,\r
+            /* [out] */ unsigned char *frames) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetString( \r
+            /* [out] */ BSTR *timecode) = 0;\r
+        \r
+        virtual BMDTimecodeFlags STDMETHODCALLTYPE GetFlags( void) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkTimecodeVtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkTimecode * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkTimecode * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkTimecode * This);\r
+        \r
+        BMDTimecodeBCD ( STDMETHODCALLTYPE *GetBCD )( \r
+            IDeckLinkTimecode * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetComponents )( \r
+            IDeckLinkTimecode * This,\r
+            /* [out] */ unsigned char *hours,\r
+            /* [out] */ unsigned char *minutes,\r
+            /* [out] */ unsigned char *seconds,\r
+            /* [out] */ unsigned char *frames);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetString )( \r
+            IDeckLinkTimecode * This,\r
+            /* [out] */ BSTR *timecode);\r
+        \r
+        BMDTimecodeFlags ( STDMETHODCALLTYPE *GetFlags )( \r
+            IDeckLinkTimecode * This);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkTimecodeVtbl;\r
+\r
+    interface IDeckLinkTimecode\r
+    {\r
+        CONST_VTBL struct IDeckLinkTimecodeVtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkTimecode_QueryInterface(This,riid,ppvObject)  \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkTimecode_AddRef(This) \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkTimecode_Release(This)        \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkTimecode_GetBCD(This) \\r
+    ( (This)->lpVtbl -> GetBCD(This) ) \r
+\r
+#define IDeckLinkTimecode_GetComponents(This,hours,minutes,seconds,frames)     \\r
+    ( (This)->lpVtbl -> GetComponents(This,hours,minutes,seconds,frames) ) \r
+\r
+#define IDeckLinkTimecode_GetString(This,timecode)     \\r
+    ( (This)->lpVtbl -> GetString(This,timecode) ) \r
+\r
+#define IDeckLinkTimecode_GetFlags(This)       \\r
+    ( (This)->lpVtbl -> GetFlags(This) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkTimecode_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkVideoFrame_INTERFACE_DEFINED__\r
+#define __IDeckLinkVideoFrame_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkVideoFrame */\r
+/* [helpstring][local][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkVideoFrame;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("A8D8238E-6B18-4196-99E1-5AF717B83D32")\r
+    IDeckLinkVideoFrame : public IUnknown\r
+    {\r
+    public:\r
+        virtual long STDMETHODCALLTYPE GetWidth( void) = 0;\r
+        \r
+        virtual long STDMETHODCALLTYPE GetHeight( void) = 0;\r
+        \r
+        virtual long STDMETHODCALLTYPE GetRowBytes( void) = 0;\r
+        \r
+        virtual BMDPixelFormat STDMETHODCALLTYPE GetPixelFormat( void) = 0;\r
+        \r
+        virtual BMDFrameFlags STDMETHODCALLTYPE GetFlags( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetBytes( \r
+            /* [out] */ void **buffer) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetTimecode( \r
+            BMDTimecodeFormat format,\r
+            /* [out] */ IDeckLinkTimecode **timecode) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetAncillaryData( \r
+            /* [out] */ IDeckLinkVideoFrameAncillary **ancillary) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkVideoFrameVtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkVideoFrame * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkVideoFrame * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkVideoFrame * This);\r
+        \r
+        long ( STDMETHODCALLTYPE *GetWidth )( \r
+            IDeckLinkVideoFrame * This);\r
+        \r
+        long ( STDMETHODCALLTYPE *GetHeight )( \r
+            IDeckLinkVideoFrame * This);\r
+        \r
+        long ( STDMETHODCALLTYPE *GetRowBytes )( \r
+            IDeckLinkVideoFrame * This);\r
+        \r
+        BMDPixelFormat ( STDMETHODCALLTYPE *GetPixelFormat )( \r
+            IDeckLinkVideoFrame * This);\r
+        \r
+        BMDFrameFlags ( STDMETHODCALLTYPE *GetFlags )( \r
+            IDeckLinkVideoFrame * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetBytes )( \r
+            IDeckLinkVideoFrame * This,\r
+            /* [out] */ void **buffer);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetTimecode )( \r
+            IDeckLinkVideoFrame * This,\r
+            BMDTimecodeFormat format,\r
+            /* [out] */ IDeckLinkTimecode **timecode);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetAncillaryData )( \r
+            IDeckLinkVideoFrame * This,\r
+            /* [out] */ IDeckLinkVideoFrameAncillary **ancillary);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkVideoFrameVtbl;\r
+\r
+    interface IDeckLinkVideoFrame\r
+    {\r
+        CONST_VTBL struct IDeckLinkVideoFrameVtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkVideoFrame_QueryInterface(This,riid,ppvObject)        \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkVideoFrame_AddRef(This)       \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkVideoFrame_Release(This)      \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkVideoFrame_GetWidth(This)     \\r
+    ( (This)->lpVtbl -> GetWidth(This) ) \r
+\r
+#define IDeckLinkVideoFrame_GetHeight(This)    \\r
+    ( (This)->lpVtbl -> GetHeight(This) ) \r
+\r
+#define IDeckLinkVideoFrame_GetRowBytes(This)  \\r
+    ( (This)->lpVtbl -> GetRowBytes(This) ) \r
+\r
+#define IDeckLinkVideoFrame_GetPixelFormat(This)       \\r
+    ( (This)->lpVtbl -> GetPixelFormat(This) ) \r
+\r
+#define IDeckLinkVideoFrame_GetFlags(This)     \\r
+    ( (This)->lpVtbl -> GetFlags(This) ) \r
+\r
+#define IDeckLinkVideoFrame_GetBytes(This,buffer)      \\r
+    ( (This)->lpVtbl -> GetBytes(This,buffer) ) \r
+\r
+#define IDeckLinkVideoFrame_GetTimecode(This,format,timecode)  \\r
+    ( (This)->lpVtbl -> GetTimecode(This,format,timecode) ) \r
+\r
+#define IDeckLinkVideoFrame_GetAncillaryData(This,ancillary)   \\r
+    ( (This)->lpVtbl -> GetAncillaryData(This,ancillary) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkVideoFrame_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkMutableVideoFrame_INTERFACE_DEFINED__\r
+#define __IDeckLinkMutableVideoFrame_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkMutableVideoFrame */\r
+/* [helpstring][local][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkMutableVideoFrame;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("46FCEE00-B4E6-43D0-91C0-023A7FCEB34F")\r
+    IDeckLinkMutableVideoFrame : public IDeckLinkVideoFrame\r
+    {\r
+    public:\r
+        virtual HRESULT STDMETHODCALLTYPE SetFlags( \r
+            BMDFrameFlags newFlags) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE SetTimecode( \r
+            BMDTimecodeFormat format,\r
+            /* [in] */ IDeckLinkTimecode *timecode) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE SetTimecodeFromComponents( \r
+            BMDTimecodeFormat format,\r
+            unsigned char hours,\r
+            unsigned char minutes,\r
+            unsigned char seconds,\r
+            unsigned char frames,\r
+            BMDTimecodeFlags flags) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE SetAncillaryData( \r
+            /* [in] */ IDeckLinkVideoFrameAncillary *ancillary) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkMutableVideoFrameVtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkMutableVideoFrame * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkMutableVideoFrame * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkMutableVideoFrame * This);\r
+        \r
+        long ( STDMETHODCALLTYPE *GetWidth )( \r
+            IDeckLinkMutableVideoFrame * This);\r
+        \r
+        long ( STDMETHODCALLTYPE *GetHeight )( \r
+            IDeckLinkMutableVideoFrame * This);\r
+        \r
+        long ( STDMETHODCALLTYPE *GetRowBytes )( \r
+            IDeckLinkMutableVideoFrame * This);\r
+        \r
+        BMDPixelFormat ( STDMETHODCALLTYPE *GetPixelFormat )( \r
+            IDeckLinkMutableVideoFrame * This);\r
+        \r
+        BMDFrameFlags ( STDMETHODCALLTYPE *GetFlags )( \r
+            IDeckLinkMutableVideoFrame * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetBytes )( \r
+            IDeckLinkMutableVideoFrame * This,\r
+            /* [out] */ void **buffer);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetTimecode )( \r
+            IDeckLinkMutableVideoFrame * This,\r
+            BMDTimecodeFormat format,\r
+            /* [out] */ IDeckLinkTimecode **timecode);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetAncillaryData )( \r
+            IDeckLinkMutableVideoFrame * This,\r
+            /* [out] */ IDeckLinkVideoFrameAncillary **ancillary);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetFlags )( \r
+            IDeckLinkMutableVideoFrame * This,\r
+            BMDFrameFlags newFlags);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetTimecode )( \r
+            IDeckLinkMutableVideoFrame * This,\r
+            BMDTimecodeFormat format,\r
+            /* [in] */ IDeckLinkTimecode *timecode);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetTimecodeFromComponents )( \r
+            IDeckLinkMutableVideoFrame * This,\r
+            BMDTimecodeFormat format,\r
+            unsigned char hours,\r
+            unsigned char minutes,\r
+            unsigned char seconds,\r
+            unsigned char frames,\r
+            BMDTimecodeFlags flags);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetAncillaryData )( \r
+            IDeckLinkMutableVideoFrame * This,\r
+            /* [in] */ IDeckLinkVideoFrameAncillary *ancillary);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkMutableVideoFrameVtbl;\r
+\r
+    interface IDeckLinkMutableVideoFrame\r
+    {\r
+        CONST_VTBL struct IDeckLinkMutableVideoFrameVtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkMutableVideoFrame_QueryInterface(This,riid,ppvObject) \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkMutableVideoFrame_AddRef(This)        \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkMutableVideoFrame_Release(This)       \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkMutableVideoFrame_GetWidth(This)      \\r
+    ( (This)->lpVtbl -> GetWidth(This) ) \r
+\r
+#define IDeckLinkMutableVideoFrame_GetHeight(This)     \\r
+    ( (This)->lpVtbl -> GetHeight(This) ) \r
+\r
+#define IDeckLinkMutableVideoFrame_GetRowBytes(This)   \\r
+    ( (This)->lpVtbl -> GetRowBytes(This) ) \r
+\r
+#define IDeckLinkMutableVideoFrame_GetPixelFormat(This)        \\r
+    ( (This)->lpVtbl -> GetPixelFormat(This) ) \r
+\r
+#define IDeckLinkMutableVideoFrame_GetFlags(This)      \\r
+    ( (This)->lpVtbl -> GetFlags(This) ) \r
+\r
+#define IDeckLinkMutableVideoFrame_GetBytes(This,buffer)       \\r
+    ( (This)->lpVtbl -> GetBytes(This,buffer) ) \r
+\r
+#define IDeckLinkMutableVideoFrame_GetTimecode(This,format,timecode)   \\r
+    ( (This)->lpVtbl -> GetTimecode(This,format,timecode) ) \r
+\r
+#define IDeckLinkMutableVideoFrame_GetAncillaryData(This,ancillary)    \\r
+    ( (This)->lpVtbl -> GetAncillaryData(This,ancillary) ) \r
+\r
+\r
+#define IDeckLinkMutableVideoFrame_SetFlags(This,newFlags)     \\r
+    ( (This)->lpVtbl -> SetFlags(This,newFlags) ) \r
+\r
+#define IDeckLinkMutableVideoFrame_SetTimecode(This,format,timecode)   \\r
+    ( (This)->lpVtbl -> SetTimecode(This,format,timecode) ) \r
+\r
+#define IDeckLinkMutableVideoFrame_SetTimecodeFromComponents(This,format,hours,minutes,seconds,frames,flags)   \\r
+    ( (This)->lpVtbl -> SetTimecodeFromComponents(This,format,hours,minutes,seconds,frames,flags) ) \r
+\r
+#define IDeckLinkMutableVideoFrame_SetAncillaryData(This,ancillary)    \\r
+    ( (This)->lpVtbl -> SetAncillaryData(This,ancillary) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkMutableVideoFrame_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkVideoInputFrame_INTERFACE_DEFINED__\r
+#define __IDeckLinkVideoInputFrame_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkVideoInputFrame */\r
+/* [helpstring][local][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkVideoInputFrame;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("9A74FA41-AE9F-47AC-8CF4-01F42DD59965")\r
+    IDeckLinkVideoInputFrame : public IDeckLinkVideoFrame\r
+    {\r
+    public:\r
+        virtual HRESULT STDMETHODCALLTYPE GetStreamTime( \r
+            /* [out] */ BMDTimeValue *frameTime,\r
+            /* [out] */ BMDTimeValue *frameDuration,\r
+            BMDTimeScale timeScale) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetHardwareReferenceTimestamp( \r
+            BMDTimeScale timeScale,\r
+            /* [out] */ BMDTimeValue *frameTime,\r
+            /* [out] */ BMDTimeValue *frameDuration) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkVideoInputFrameVtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkVideoInputFrame * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkVideoInputFrame * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkVideoInputFrame * This);\r
+        \r
+        long ( STDMETHODCALLTYPE *GetWidth )( \r
+            IDeckLinkVideoInputFrame * This);\r
+        \r
+        long ( STDMETHODCALLTYPE *GetHeight )( \r
+            IDeckLinkVideoInputFrame * This);\r
+        \r
+        long ( STDMETHODCALLTYPE *GetRowBytes )( \r
+            IDeckLinkVideoInputFrame * This);\r
+        \r
+        BMDPixelFormat ( STDMETHODCALLTYPE *GetPixelFormat )( \r
+            IDeckLinkVideoInputFrame * This);\r
+        \r
+        BMDFrameFlags ( STDMETHODCALLTYPE *GetFlags )( \r
+            IDeckLinkVideoInputFrame * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetBytes )( \r
+            IDeckLinkVideoInputFrame * This,\r
+            /* [out] */ void **buffer);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetTimecode )( \r
+            IDeckLinkVideoInputFrame * This,\r
+            BMDTimecodeFormat format,\r
+            /* [out] */ IDeckLinkTimecode **timecode);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetAncillaryData )( \r
+            IDeckLinkVideoInputFrame * This,\r
+            /* [out] */ IDeckLinkVideoFrameAncillary **ancillary);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetStreamTime )( \r
+            IDeckLinkVideoInputFrame * This,\r
+            /* [out] */ BMDTimeValue *frameTime,\r
+            /* [out] */ BMDTimeValue *frameDuration,\r
+            BMDTimeScale timeScale);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetHardwareReferenceTimestamp )( \r
+            IDeckLinkVideoInputFrame * This,\r
+            BMDTimeScale timeScale,\r
+            /* [out] */ BMDTimeValue *frameTime,\r
+            /* [out] */ BMDTimeValue *frameDuration);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkVideoInputFrameVtbl;\r
+\r
+    interface IDeckLinkVideoInputFrame\r
+    {\r
+        CONST_VTBL struct IDeckLinkVideoInputFrameVtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkVideoInputFrame_QueryInterface(This,riid,ppvObject)   \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkVideoInputFrame_AddRef(This)  \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkVideoInputFrame_Release(This) \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkVideoInputFrame_GetWidth(This)        \\r
+    ( (This)->lpVtbl -> GetWidth(This) ) \r
+\r
+#define IDeckLinkVideoInputFrame_GetHeight(This)       \\r
+    ( (This)->lpVtbl -> GetHeight(This) ) \r
+\r
+#define IDeckLinkVideoInputFrame_GetRowBytes(This)     \\r
+    ( (This)->lpVtbl -> GetRowBytes(This) ) \r
+\r
+#define IDeckLinkVideoInputFrame_GetPixelFormat(This)  \\r
+    ( (This)->lpVtbl -> GetPixelFormat(This) ) \r
+\r
+#define IDeckLinkVideoInputFrame_GetFlags(This)        \\r
+    ( (This)->lpVtbl -> GetFlags(This) ) \r
+\r
+#define IDeckLinkVideoInputFrame_GetBytes(This,buffer) \\r
+    ( (This)->lpVtbl -> GetBytes(This,buffer) ) \r
+\r
+#define IDeckLinkVideoInputFrame_GetTimecode(This,format,timecode)     \\r
+    ( (This)->lpVtbl -> GetTimecode(This,format,timecode) ) \r
+\r
+#define IDeckLinkVideoInputFrame_GetAncillaryData(This,ancillary)      \\r
+    ( (This)->lpVtbl -> GetAncillaryData(This,ancillary) ) \r
+\r
+\r
+#define IDeckLinkVideoInputFrame_GetStreamTime(This,frameTime,frameDuration,timeScale) \\r
+    ( (This)->lpVtbl -> GetStreamTime(This,frameTime,frameDuration,timeScale) ) \r
+\r
+#define IDeckLinkVideoInputFrame_GetHardwareReferenceTimestamp(This,timeScale,frameTime,frameDuration) \\r
+    ( (This)->lpVtbl -> GetHardwareReferenceTimestamp(This,timeScale,frameTime,frameDuration) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkVideoInputFrame_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkVideoFrameAncillary_INTERFACE_DEFINED__\r
+#define __IDeckLinkVideoFrameAncillary_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkVideoFrameAncillary */\r
+/* [helpstring][local][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkVideoFrameAncillary;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("732E723C-D1A4-4E29-9E8E-4A88797A0004")\r
+    IDeckLinkVideoFrameAncillary : public IUnknown\r
+    {\r
+    public:\r
+        virtual HRESULT STDMETHODCALLTYPE GetBufferForVerticalBlankingLine( \r
+            unsigned long lineNumber,\r
+            /* [out] */ void **buffer) = 0;\r
+        \r
+        virtual BMDPixelFormat STDMETHODCALLTYPE GetPixelFormat( void) = 0;\r
+        \r
+        virtual BMDDisplayMode STDMETHODCALLTYPE GetDisplayMode( void) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkVideoFrameAncillaryVtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkVideoFrameAncillary * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkVideoFrameAncillary * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkVideoFrameAncillary * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetBufferForVerticalBlankingLine )( \r
+            IDeckLinkVideoFrameAncillary * This,\r
+            unsigned long lineNumber,\r
+            /* [out] */ void **buffer);\r
+        \r
+        BMDPixelFormat ( STDMETHODCALLTYPE *GetPixelFormat )( \r
+            IDeckLinkVideoFrameAncillary * This);\r
+        \r
+        BMDDisplayMode ( STDMETHODCALLTYPE *GetDisplayMode )( \r
+            IDeckLinkVideoFrameAncillary * This);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkVideoFrameAncillaryVtbl;\r
+\r
+    interface IDeckLinkVideoFrameAncillary\r
+    {\r
+        CONST_VTBL struct IDeckLinkVideoFrameAncillaryVtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkVideoFrameAncillary_QueryInterface(This,riid,ppvObject)       \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkVideoFrameAncillary_AddRef(This)      \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkVideoFrameAncillary_Release(This)     \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkVideoFrameAncillary_GetBufferForVerticalBlankingLine(This,lineNumber,buffer)  \\r
+    ( (This)->lpVtbl -> GetBufferForVerticalBlankingLine(This,lineNumber,buffer) ) \r
+\r
+#define IDeckLinkVideoFrameAncillary_GetPixelFormat(This)      \\r
+    ( (This)->lpVtbl -> GetPixelFormat(This) ) \r
+\r
+#define IDeckLinkVideoFrameAncillary_GetDisplayMode(This)      \\r
+    ( (This)->lpVtbl -> GetDisplayMode(This) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkVideoFrameAncillary_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkAudioInputPacket_INTERFACE_DEFINED__\r
+#define __IDeckLinkAudioInputPacket_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkAudioInputPacket */\r
+/* [helpstring][local][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkAudioInputPacket;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("E43D5870-2894-11DE-8C30-0800200C9A66")\r
+    IDeckLinkAudioInputPacket : public IUnknown\r
+    {\r
+    public:\r
+        virtual long STDMETHODCALLTYPE GetSampleFrameCount( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetBytes( \r
+            /* [out] */ void **buffer) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetPacketTime( \r
+            /* [out] */ BMDTimeValue *packetTime,\r
+            BMDTimeScale timeScale) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkAudioInputPacketVtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkAudioInputPacket * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkAudioInputPacket * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkAudioInputPacket * This);\r
+        \r
+        long ( STDMETHODCALLTYPE *GetSampleFrameCount )( \r
+            IDeckLinkAudioInputPacket * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetBytes )( \r
+            IDeckLinkAudioInputPacket * This,\r
+            /* [out] */ void **buffer);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetPacketTime )( \r
+            IDeckLinkAudioInputPacket * This,\r
+            /* [out] */ BMDTimeValue *packetTime,\r
+            BMDTimeScale timeScale);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkAudioInputPacketVtbl;\r
+\r
+    interface IDeckLinkAudioInputPacket\r
+    {\r
+        CONST_VTBL struct IDeckLinkAudioInputPacketVtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkAudioInputPacket_QueryInterface(This,riid,ppvObject)  \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkAudioInputPacket_AddRef(This) \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkAudioInputPacket_Release(This)        \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkAudioInputPacket_GetSampleFrameCount(This)    \\r
+    ( (This)->lpVtbl -> GetSampleFrameCount(This) ) \r
+\r
+#define IDeckLinkAudioInputPacket_GetBytes(This,buffer)        \\r
+    ( (This)->lpVtbl -> GetBytes(This,buffer) ) \r
+\r
+#define IDeckLinkAudioInputPacket_GetPacketTime(This,packetTime,timeScale)     \\r
+    ( (This)->lpVtbl -> GetPacketTime(This,packetTime,timeScale) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkAudioInputPacket_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkScreenPreviewCallback_INTERFACE_DEFINED__\r
+#define __IDeckLinkScreenPreviewCallback_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkScreenPreviewCallback */\r
+/* [helpstring][local][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkScreenPreviewCallback;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("373F499D-4B4D-4518-AD22-6354E5A5825E")\r
+    IDeckLinkScreenPreviewCallback : public IUnknown\r
+    {\r
+    public:\r
+        virtual HRESULT STDMETHODCALLTYPE DrawFrame( \r
+            /* [in] */ IDeckLinkVideoFrame *theFrame) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkScreenPreviewCallbackVtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkScreenPreviewCallback * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkScreenPreviewCallback * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkScreenPreviewCallback * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *DrawFrame )( \r
+            IDeckLinkScreenPreviewCallback * This,\r
+            /* [in] */ IDeckLinkVideoFrame *theFrame);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkScreenPreviewCallbackVtbl;\r
+\r
+    interface IDeckLinkScreenPreviewCallback\r
+    {\r
+        CONST_VTBL struct IDeckLinkScreenPreviewCallbackVtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkScreenPreviewCallback_QueryInterface(This,riid,ppvObject)     \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkScreenPreviewCallback_AddRef(This)    \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkScreenPreviewCallback_Release(This)   \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkScreenPreviewCallback_DrawFrame(This,theFrame)        \\r
+    ( (This)->lpVtbl -> DrawFrame(This,theFrame) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkScreenPreviewCallback_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkGLScreenPreviewHelper_INTERFACE_DEFINED__\r
+#define __IDeckLinkGLScreenPreviewHelper_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkGLScreenPreviewHelper */\r
+/* [helpstring][local][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkGLScreenPreviewHelper;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("BA575CD9-A15E-497B-B2C2-F9AFE7BE4EBA")\r
+    IDeckLinkGLScreenPreviewHelper : public IUnknown\r
+    {\r
+    public:\r
+        virtual HRESULT STDMETHODCALLTYPE InitializeGL( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE PaintGL( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE SetFrame( \r
+            /* [in] */ IDeckLinkVideoFrame *theFrame) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkGLScreenPreviewHelperVtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkGLScreenPreviewHelper * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkGLScreenPreviewHelper * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkGLScreenPreviewHelper * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *InitializeGL )( \r
+            IDeckLinkGLScreenPreviewHelper * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *PaintGL )( \r
+            IDeckLinkGLScreenPreviewHelper * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetFrame )( \r
+            IDeckLinkGLScreenPreviewHelper * This,\r
+            /* [in] */ IDeckLinkVideoFrame *theFrame);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkGLScreenPreviewHelperVtbl;\r
+\r
+    interface IDeckLinkGLScreenPreviewHelper\r
+    {\r
+        CONST_VTBL struct IDeckLinkGLScreenPreviewHelperVtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkGLScreenPreviewHelper_QueryInterface(This,riid,ppvObject)     \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkGLScreenPreviewHelper_AddRef(This)    \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkGLScreenPreviewHelper_Release(This)   \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkGLScreenPreviewHelper_InitializeGL(This)      \\r
+    ( (This)->lpVtbl -> InitializeGL(This) ) \r
+\r
+#define IDeckLinkGLScreenPreviewHelper_PaintGL(This)   \\r
+    ( (This)->lpVtbl -> PaintGL(This) ) \r
+\r
+#define IDeckLinkGLScreenPreviewHelper_SetFrame(This,theFrame) \\r
+    ( (This)->lpVtbl -> SetFrame(This,theFrame) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkGLScreenPreviewHelper_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkConfiguration_INTERFACE_DEFINED__\r
+#define __IDeckLinkConfiguration_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkConfiguration */\r
+/* [helpstring][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkConfiguration;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("B8EAD569-B764-47F0-A73F-AE40DF6CBF10")\r
+    IDeckLinkConfiguration : public IUnknown\r
+    {\r
+    public:\r
+        virtual HRESULT STDMETHODCALLTYPE GetConfigurationValidator( \r
+            /* [out] */ IDeckLinkConfiguration **configObject) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE WriteConfigurationToPreferences( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE SetVideoOutputFormat( \r
+            BMDVideoConnection videoOutputConnection) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE IsVideoOutputActive( \r
+            BMDVideoConnection videoOutputConnection,\r
+            /* [out] */ BOOL *active) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE SetAnalogVideoOutputFlags( \r
+            BMDAnalogVideoFlags analogVideoFlags) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetAnalogVideoOutputFlags( \r
+            /* [out] */ BMDAnalogVideoFlags *analogVideoFlags) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE EnableFieldFlickerRemovalWhenPaused( \r
+            BOOL enable) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE IsEnabledFieldFlickerRemovalWhenPaused( \r
+            /* [out] */ BOOL *enabled) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE Set444And3GBpsVideoOutput( \r
+            BOOL enable444VideoOutput,\r
+            BOOL enable3GbsOutput) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE Get444And3GBpsVideoOutput( \r
+            /* [out] */ BOOL *is444VideoOutputEnabled,\r
+            /* [out] */ BOOL *threeGbsOutputEnabled) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE SetVideoOutputConversionMode( \r
+            BMDVideoOutputConversionMode conversionMode) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetVideoOutputConversionMode( \r
+            /* [out] */ BMDVideoOutputConversionMode *conversionMode) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE Set_HD1080p24_to_HD1080i5994_Conversion( \r
+            BOOL enable) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE Get_HD1080p24_to_HD1080i5994_Conversion( \r
+            /* [out] */ BOOL *enabled) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE SetVideoInputFormat( \r
+            BMDVideoConnection videoInputFormat) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetVideoInputFormat( \r
+            /* [out] */ BMDVideoConnection *videoInputFormat) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE SetAnalogVideoInputFlags( \r
+            BMDAnalogVideoFlags analogVideoFlags) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetAnalogVideoInputFlags( \r
+            /* [out] */ BMDAnalogVideoFlags *analogVideoFlags) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE SetVideoInputConversionMode( \r
+            BMDVideoInputConversionMode conversionMode) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetVideoInputConversionMode( \r
+            /* [out] */ BMDVideoInputConversionMode *conversionMode) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE SetBlackVideoOutputDuringCapture( \r
+            BOOL blackOutInCapture) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetBlackVideoOutputDuringCapture( \r
+            /* [out] */ BOOL *blackOutInCapture) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE Set32PulldownSequenceInitialTimecodeFrame( \r
+            unsigned long aFrameTimecode) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE Get32PulldownSequenceInitialTimecodeFrame( \r
+            /* [out] */ unsigned long *aFrameTimecode) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE SetVancSourceLineMapping( \r
+            unsigned long activeLine1VANCsource,\r
+            unsigned long activeLine2VANCsource,\r
+            unsigned long activeLine3VANCsource) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetVancSourceLineMapping( \r
+            /* [out] */ unsigned long *activeLine1VANCsource,\r
+            /* [out] */ unsigned long *activeLine2VANCsource,\r
+            /* [out] */ unsigned long *activeLine3VANCsource) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE SetAudioInputFormat( \r
+            BMDAudioConnection audioInputFormat) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetAudioInputFormat( \r
+            /* [out] */ BMDAudioConnection *audioInputFormat) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkConfigurationVtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkConfiguration * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkConfiguration * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkConfiguration * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetConfigurationValidator )( \r
+            IDeckLinkConfiguration * This,\r
+            /* [out] */ IDeckLinkConfiguration **configObject);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *WriteConfigurationToPreferences )( \r
+            IDeckLinkConfiguration * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetVideoOutputFormat )( \r
+            IDeckLinkConfiguration * This,\r
+            BMDVideoConnection videoOutputConnection);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *IsVideoOutputActive )( \r
+            IDeckLinkConfiguration * This,\r
+            BMDVideoConnection videoOutputConnection,\r
+            /* [out] */ BOOL *active);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetAnalogVideoOutputFlags )( \r
+            IDeckLinkConfiguration * This,\r
+            BMDAnalogVideoFlags analogVideoFlags);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetAnalogVideoOutputFlags )( \r
+            IDeckLinkConfiguration * This,\r
+            /* [out] */ BMDAnalogVideoFlags *analogVideoFlags);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *EnableFieldFlickerRemovalWhenPaused )( \r
+            IDeckLinkConfiguration * This,\r
+            BOOL enable);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *IsEnabledFieldFlickerRemovalWhenPaused )( \r
+            IDeckLinkConfiguration * This,\r
+            /* [out] */ BOOL *enabled);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *Set444And3GBpsVideoOutput )( \r
+            IDeckLinkConfiguration * This,\r
+            BOOL enable444VideoOutput,\r
+            BOOL enable3GbsOutput);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *Get444And3GBpsVideoOutput )( \r
+            IDeckLinkConfiguration * This,\r
+            /* [out] */ BOOL *is444VideoOutputEnabled,\r
+            /* [out] */ BOOL *threeGbsOutputEnabled);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetVideoOutputConversionMode )( \r
+            IDeckLinkConfiguration * This,\r
+            BMDVideoOutputConversionMode conversionMode);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetVideoOutputConversionMode )( \r
+            IDeckLinkConfiguration * This,\r
+            /* [out] */ BMDVideoOutputConversionMode *conversionMode);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *Set_HD1080p24_to_HD1080i5994_Conversion )( \r
+            IDeckLinkConfiguration * This,\r
+            BOOL enable);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *Get_HD1080p24_to_HD1080i5994_Conversion )( \r
+            IDeckLinkConfiguration * This,\r
+            /* [out] */ BOOL *enabled);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetVideoInputFormat )( \r
+            IDeckLinkConfiguration * This,\r
+            BMDVideoConnection videoInputFormat);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetVideoInputFormat )( \r
+            IDeckLinkConfiguration * This,\r
+            /* [out] */ BMDVideoConnection *videoInputFormat);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetAnalogVideoInputFlags )( \r
+            IDeckLinkConfiguration * This,\r
+            BMDAnalogVideoFlags analogVideoFlags);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetAnalogVideoInputFlags )( \r
+            IDeckLinkConfiguration * This,\r
+            /* [out] */ BMDAnalogVideoFlags *analogVideoFlags);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetVideoInputConversionMode )( \r
+            IDeckLinkConfiguration * This,\r
+            BMDVideoInputConversionMode conversionMode);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetVideoInputConversionMode )( \r
+            IDeckLinkConfiguration * This,\r
+            /* [out] */ BMDVideoInputConversionMode *conversionMode);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetBlackVideoOutputDuringCapture )( \r
+            IDeckLinkConfiguration * This,\r
+            BOOL blackOutInCapture);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetBlackVideoOutputDuringCapture )( \r
+            IDeckLinkConfiguration * This,\r
+            /* [out] */ BOOL *blackOutInCapture);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *Set32PulldownSequenceInitialTimecodeFrame )( \r
+            IDeckLinkConfiguration * This,\r
+            unsigned long aFrameTimecode);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *Get32PulldownSequenceInitialTimecodeFrame )( \r
+            IDeckLinkConfiguration * This,\r
+            /* [out] */ unsigned long *aFrameTimecode);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetVancSourceLineMapping )( \r
+            IDeckLinkConfiguration * This,\r
+            unsigned long activeLine1VANCsource,\r
+            unsigned long activeLine2VANCsource,\r
+            unsigned long activeLine3VANCsource);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetVancSourceLineMapping )( \r
+            IDeckLinkConfiguration * This,\r
+            /* [out] */ unsigned long *activeLine1VANCsource,\r
+            /* [out] */ unsigned long *activeLine2VANCsource,\r
+            /* [out] */ unsigned long *activeLine3VANCsource);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetAudioInputFormat )( \r
+            IDeckLinkConfiguration * This,\r
+            BMDAudioConnection audioInputFormat);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetAudioInputFormat )( \r
+            IDeckLinkConfiguration * This,\r
+            /* [out] */ BMDAudioConnection *audioInputFormat);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkConfigurationVtbl;\r
+\r
+    interface IDeckLinkConfiguration\r
+    {\r
+        CONST_VTBL struct IDeckLinkConfigurationVtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkConfiguration_QueryInterface(This,riid,ppvObject)     \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkConfiguration_AddRef(This)    \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkConfiguration_Release(This)   \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkConfiguration_GetConfigurationValidator(This,configObject)    \\r
+    ( (This)->lpVtbl -> GetConfigurationValidator(This,configObject) ) \r
+\r
+#define IDeckLinkConfiguration_WriteConfigurationToPreferences(This)   \\r
+    ( (This)->lpVtbl -> WriteConfigurationToPreferences(This) ) \r
+\r
+#define IDeckLinkConfiguration_SetVideoOutputFormat(This,videoOutputConnection)        \\r
+    ( (This)->lpVtbl -> SetVideoOutputFormat(This,videoOutputConnection) ) \r
+\r
+#define IDeckLinkConfiguration_IsVideoOutputActive(This,videoOutputConnection,active)  \\r
+    ( (This)->lpVtbl -> IsVideoOutputActive(This,videoOutputConnection,active) ) \r
+\r
+#define IDeckLinkConfiguration_SetAnalogVideoOutputFlags(This,analogVideoFlags)        \\r
+    ( (This)->lpVtbl -> SetAnalogVideoOutputFlags(This,analogVideoFlags) ) \r
+\r
+#define IDeckLinkConfiguration_GetAnalogVideoOutputFlags(This,analogVideoFlags)        \\r
+    ( (This)->lpVtbl -> GetAnalogVideoOutputFlags(This,analogVideoFlags) ) \r
+\r
+#define IDeckLinkConfiguration_EnableFieldFlickerRemovalWhenPaused(This,enable)        \\r
+    ( (This)->lpVtbl -> EnableFieldFlickerRemovalWhenPaused(This,enable) ) \r
+\r
+#define IDeckLinkConfiguration_IsEnabledFieldFlickerRemovalWhenPaused(This,enabled)    \\r
+    ( (This)->lpVtbl -> IsEnabledFieldFlickerRemovalWhenPaused(This,enabled) ) \r
+\r
+#define IDeckLinkConfiguration_Set444And3GBpsVideoOutput(This,enable444VideoOutput,enable3GbsOutput)   \\r
+    ( (This)->lpVtbl -> Set444And3GBpsVideoOutput(This,enable444VideoOutput,enable3GbsOutput) ) \r
+\r
+#define IDeckLinkConfiguration_Get444And3GBpsVideoOutput(This,is444VideoOutputEnabled,threeGbsOutputEnabled)   \\r
+    ( (This)->lpVtbl -> Get444And3GBpsVideoOutput(This,is444VideoOutputEnabled,threeGbsOutputEnabled) ) \r
+\r
+#define IDeckLinkConfiguration_SetVideoOutputConversionMode(This,conversionMode)       \\r
+    ( (This)->lpVtbl -> SetVideoOutputConversionMode(This,conversionMode) ) \r
+\r
+#define IDeckLinkConfiguration_GetVideoOutputConversionMode(This,conversionMode)       \\r
+    ( (This)->lpVtbl -> GetVideoOutputConversionMode(This,conversionMode) ) \r
+\r
+#define IDeckLinkConfiguration_Set_HD1080p24_to_HD1080i5994_Conversion(This,enable)    \\r
+    ( (This)->lpVtbl -> Set_HD1080p24_to_HD1080i5994_Conversion(This,enable) ) \r
+\r
+#define IDeckLinkConfiguration_Get_HD1080p24_to_HD1080i5994_Conversion(This,enabled)   \\r
+    ( (This)->lpVtbl -> Get_HD1080p24_to_HD1080i5994_Conversion(This,enabled) ) \r
+\r
+#define IDeckLinkConfiguration_SetVideoInputFormat(This,videoInputFormat)      \\r
+    ( (This)->lpVtbl -> SetVideoInputFormat(This,videoInputFormat) ) \r
+\r
+#define IDeckLinkConfiguration_GetVideoInputFormat(This,videoInputFormat)      \\r
+    ( (This)->lpVtbl -> GetVideoInputFormat(This,videoInputFormat) ) \r
+\r
+#define IDeckLinkConfiguration_SetAnalogVideoInputFlags(This,analogVideoFlags) \\r
+    ( (This)->lpVtbl -> SetAnalogVideoInputFlags(This,analogVideoFlags) ) \r
+\r
+#define IDeckLinkConfiguration_GetAnalogVideoInputFlags(This,analogVideoFlags) \\r
+    ( (This)->lpVtbl -> GetAnalogVideoInputFlags(This,analogVideoFlags) ) \r
+\r
+#define IDeckLinkConfiguration_SetVideoInputConversionMode(This,conversionMode)        \\r
+    ( (This)->lpVtbl -> SetVideoInputConversionMode(This,conversionMode) ) \r
+\r
+#define IDeckLinkConfiguration_GetVideoInputConversionMode(This,conversionMode)        \\r
+    ( (This)->lpVtbl -> GetVideoInputConversionMode(This,conversionMode) ) \r
+\r
+#define IDeckLinkConfiguration_SetBlackVideoOutputDuringCapture(This,blackOutInCapture)        \\r
+    ( (This)->lpVtbl -> SetBlackVideoOutputDuringCapture(This,blackOutInCapture) ) \r
+\r
+#define IDeckLinkConfiguration_GetBlackVideoOutputDuringCapture(This,blackOutInCapture)        \\r
+    ( (This)->lpVtbl -> GetBlackVideoOutputDuringCapture(This,blackOutInCapture) ) \r
+\r
+#define IDeckLinkConfiguration_Set32PulldownSequenceInitialTimecodeFrame(This,aFrameTimecode)  \\r
+    ( (This)->lpVtbl -> Set32PulldownSequenceInitialTimecodeFrame(This,aFrameTimecode) ) \r
+\r
+#define IDeckLinkConfiguration_Get32PulldownSequenceInitialTimecodeFrame(This,aFrameTimecode)  \\r
+    ( (This)->lpVtbl -> Get32PulldownSequenceInitialTimecodeFrame(This,aFrameTimecode) ) \r
+\r
+#define IDeckLinkConfiguration_SetVancSourceLineMapping(This,activeLine1VANCsource,activeLine2VANCsource,activeLine3VANCsource)        \\r
+    ( (This)->lpVtbl -> SetVancSourceLineMapping(This,activeLine1VANCsource,activeLine2VANCsource,activeLine3VANCsource) ) \r
+\r
+#define IDeckLinkConfiguration_GetVancSourceLineMapping(This,activeLine1VANCsource,activeLine2VANCsource,activeLine3VANCsource)        \\r
+    ( (This)->lpVtbl -> GetVancSourceLineMapping(This,activeLine1VANCsource,activeLine2VANCsource,activeLine3VANCsource) ) \r
+\r
+#define IDeckLinkConfiguration_SetAudioInputFormat(This,audioInputFormat)      \\r
+    ( (This)->lpVtbl -> SetAudioInputFormat(This,audioInputFormat) ) \r
+\r
+#define IDeckLinkConfiguration_GetAudioInputFormat(This,audioInputFormat)      \\r
+    ( (This)->lpVtbl -> GetAudioInputFormat(This,audioInputFormat) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkConfiguration_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkAttributes_INTERFACE_DEFINED__\r
+#define __IDeckLinkAttributes_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkAttributes */\r
+/* [helpstring][local][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkAttributes;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("ABC11843-D966-44CB-96E2-A1CB5D3135C4")\r
+    IDeckLinkAttributes : public IUnknown\r
+    {\r
+    public:\r
+        virtual HRESULT STDMETHODCALLTYPE GetFlag( \r
+            /* [in] */ BMDDeckLinkAttributeID cfgID,\r
+            /* [out] */ BOOL *value) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetInt( \r
+            /* [in] */ BMDDeckLinkAttributeID cfgID,\r
+            /* [out] */ LONGLONG *value) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetFloat( \r
+            /* [in] */ BMDDeckLinkAttributeID cfgID,\r
+            /* [out] */ double *value) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetString( \r
+            /* [in] */ BMDDeckLinkAttributeID cfgID,\r
+            /* [out] */ BSTR *value) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkAttributesVtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkAttributes * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkAttributes * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkAttributes * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetFlag )( \r
+            IDeckLinkAttributes * This,\r
+            /* [in] */ BMDDeckLinkAttributeID cfgID,\r
+            /* [out] */ BOOL *value);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetInt )( \r
+            IDeckLinkAttributes * This,\r
+            /* [in] */ BMDDeckLinkAttributeID cfgID,\r
+            /* [out] */ LONGLONG *value);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetFloat )( \r
+            IDeckLinkAttributes * This,\r
+            /* [in] */ BMDDeckLinkAttributeID cfgID,\r
+            /* [out] */ double *value);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetString )( \r
+            IDeckLinkAttributes * This,\r
+            /* [in] */ BMDDeckLinkAttributeID cfgID,\r
+            /* [out] */ BSTR *value);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkAttributesVtbl;\r
+\r
+    interface IDeckLinkAttributes\r
+    {\r
+        CONST_VTBL struct IDeckLinkAttributesVtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkAttributes_QueryInterface(This,riid,ppvObject)        \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkAttributes_AddRef(This)       \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkAttributes_Release(This)      \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkAttributes_GetFlag(This,cfgID,value)  \\r
+    ( (This)->lpVtbl -> GetFlag(This,cfgID,value) ) \r
+\r
+#define IDeckLinkAttributes_GetInt(This,cfgID,value)   \\r
+    ( (This)->lpVtbl -> GetInt(This,cfgID,value) ) \r
+\r
+#define IDeckLinkAttributes_GetFloat(This,cfgID,value) \\r
+    ( (This)->lpVtbl -> GetFloat(This,cfgID,value) ) \r
+\r
+#define IDeckLinkAttributes_GetString(This,cfgID,value)        \\r
+    ( (This)->lpVtbl -> GetString(This,cfgID,value) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkAttributes_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkKeyer_INTERFACE_DEFINED__\r
+#define __IDeckLinkKeyer_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkKeyer */\r
+/* [helpstring][local][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkKeyer;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("89AFCAF5-65F8-421E-98F7-96FE5F5BFBA3")\r
+    IDeckLinkKeyer : public IUnknown\r
+    {\r
+    public:\r
+        virtual HRESULT STDMETHODCALLTYPE Enable( \r
+            /* [in] */ BOOL isExternal) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE SetLevel( \r
+            /* [in] */ unsigned char level) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE RampUp( \r
+            /* [in] */ unsigned long numberOfFrames) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE RampDown( \r
+            /* [in] */ unsigned long numberOfFrames) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE Disable( void) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkKeyerVtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkKeyer * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkKeyer * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkKeyer * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *Enable )( \r
+            IDeckLinkKeyer * This,\r
+            /* [in] */ BOOL isExternal);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetLevel )( \r
+            IDeckLinkKeyer * This,\r
+            /* [in] */ unsigned char level);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *RampUp )( \r
+            IDeckLinkKeyer * This,\r
+            /* [in] */ unsigned long numberOfFrames);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *RampDown )( \r
+            IDeckLinkKeyer * This,\r
+            /* [in] */ unsigned long numberOfFrames);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *Disable )( \r
+            IDeckLinkKeyer * This);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkKeyerVtbl;\r
+\r
+    interface IDeckLinkKeyer\r
+    {\r
+        CONST_VTBL struct IDeckLinkKeyerVtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkKeyer_QueryInterface(This,riid,ppvObject)     \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkKeyer_AddRef(This)    \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkKeyer_Release(This)   \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkKeyer_Enable(This,isExternal) \\r
+    ( (This)->lpVtbl -> Enable(This,isExternal) ) \r
+\r
+#define IDeckLinkKeyer_SetLevel(This,level)    \\r
+    ( (This)->lpVtbl -> SetLevel(This,level) ) \r
+\r
+#define IDeckLinkKeyer_RampUp(This,numberOfFrames)     \\r
+    ( (This)->lpVtbl -> RampUp(This,numberOfFrames) ) \r
+\r
+#define IDeckLinkKeyer_RampDown(This,numberOfFrames)   \\r
+    ( (This)->lpVtbl -> RampDown(This,numberOfFrames) ) \r
+\r
+#define IDeckLinkKeyer_Disable(This)   \\r
+    ( (This)->lpVtbl -> Disable(This) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkKeyer_INTERFACE_DEFINED__ */\r
+\r
+\r
+EXTERN_C const CLSID CLSID_CDeckLinkIterator;\r
+\r
+#ifdef __cplusplus\r
+\r
+class DECLSPEC_UUID("D9EDA3B3-2887-41FA-B724-017CF1EB1D37")\r
+CDeckLinkIterator;\r
+#endif\r
+\r
+EXTERN_C const CLSID CLSID_CDeckLinkGLScreenPreviewHelper;\r
+\r
+#ifdef __cplusplus\r
+\r
+class DECLSPEC_UUID("D398CEE7-4434-4CA3-9BA6-5AE34556B905")\r
+CDeckLinkGLScreenPreviewHelper;\r
+#endif\r
+\r
+#ifndef __IDeckLinkDisplayModeIterator_v7_1_INTERFACE_DEFINED__\r
+#define __IDeckLinkDisplayModeIterator_v7_1_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkDisplayModeIterator_v7_1 */\r
+/* [helpstring][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkDisplayModeIterator_v7_1;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("B28131B6-59AC-4857-B5AC-CD75D5883E2F")\r
+    IDeckLinkDisplayModeIterator_v7_1 : public IUnknown\r
+    {\r
+    public:\r
+        virtual HRESULT STDMETHODCALLTYPE Next( \r
+            /* [out] */ IDeckLinkDisplayMode_v7_1 **deckLinkDisplayMode) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkDisplayModeIterator_v7_1Vtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkDisplayModeIterator_v7_1 * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkDisplayModeIterator_v7_1 * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkDisplayModeIterator_v7_1 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *Next )( \r
+            IDeckLinkDisplayModeIterator_v7_1 * This,\r
+            /* [out] */ IDeckLinkDisplayMode_v7_1 **deckLinkDisplayMode);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkDisplayModeIterator_v7_1Vtbl;\r
+\r
+    interface IDeckLinkDisplayModeIterator_v7_1\r
+    {\r
+        CONST_VTBL struct IDeckLinkDisplayModeIterator_v7_1Vtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkDisplayModeIterator_v7_1_QueryInterface(This,riid,ppvObject)  \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkDisplayModeIterator_v7_1_AddRef(This) \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkDisplayModeIterator_v7_1_Release(This)        \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkDisplayModeIterator_v7_1_Next(This,deckLinkDisplayMode)       \\r
+    ( (This)->lpVtbl -> Next(This,deckLinkDisplayMode) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkDisplayModeIterator_v7_1_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkDisplayMode_v7_1_INTERFACE_DEFINED__\r
+#define __IDeckLinkDisplayMode_v7_1_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkDisplayMode_v7_1 */\r
+/* [helpstring][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkDisplayMode_v7_1;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("AF0CD6D5-8376-435E-8433-54F9DD530AC3")\r
+    IDeckLinkDisplayMode_v7_1 : public IUnknown\r
+    {\r
+    public:\r
+        virtual HRESULT STDMETHODCALLTYPE GetName( \r
+            /* [out] */ BSTR *name) = 0;\r
+        \r
+        virtual BMDDisplayMode STDMETHODCALLTYPE GetDisplayMode( void) = 0;\r
+        \r
+        virtual long STDMETHODCALLTYPE GetWidth( void) = 0;\r
+        \r
+        virtual long STDMETHODCALLTYPE GetHeight( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetFrameRate( \r
+            /* [out] */ BMDTimeValue *frameDuration,\r
+            /* [out] */ BMDTimeScale *timeScale) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkDisplayMode_v7_1Vtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkDisplayMode_v7_1 * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkDisplayMode_v7_1 * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkDisplayMode_v7_1 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetName )( \r
+            IDeckLinkDisplayMode_v7_1 * This,\r
+            /* [out] */ BSTR *name);\r
+        \r
+        BMDDisplayMode ( STDMETHODCALLTYPE *GetDisplayMode )( \r
+            IDeckLinkDisplayMode_v7_1 * This);\r
+        \r
+        long ( STDMETHODCALLTYPE *GetWidth )( \r
+            IDeckLinkDisplayMode_v7_1 * This);\r
+        \r
+        long ( STDMETHODCALLTYPE *GetHeight )( \r
+            IDeckLinkDisplayMode_v7_1 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetFrameRate )( \r
+            IDeckLinkDisplayMode_v7_1 * This,\r
+            /* [out] */ BMDTimeValue *frameDuration,\r
+            /* [out] */ BMDTimeScale *timeScale);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkDisplayMode_v7_1Vtbl;\r
+\r
+    interface IDeckLinkDisplayMode_v7_1\r
+    {\r
+        CONST_VTBL struct IDeckLinkDisplayMode_v7_1Vtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkDisplayMode_v7_1_QueryInterface(This,riid,ppvObject)  \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkDisplayMode_v7_1_AddRef(This) \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkDisplayMode_v7_1_Release(This)        \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkDisplayMode_v7_1_GetName(This,name)   \\r
+    ( (This)->lpVtbl -> GetName(This,name) ) \r
+\r
+#define IDeckLinkDisplayMode_v7_1_GetDisplayMode(This) \\r
+    ( (This)->lpVtbl -> GetDisplayMode(This) ) \r
+\r
+#define IDeckLinkDisplayMode_v7_1_GetWidth(This)       \\r
+    ( (This)->lpVtbl -> GetWidth(This) ) \r
+\r
+#define IDeckLinkDisplayMode_v7_1_GetHeight(This)      \\r
+    ( (This)->lpVtbl -> GetHeight(This) ) \r
+\r
+#define IDeckLinkDisplayMode_v7_1_GetFrameRate(This,frameDuration,timeScale)   \\r
+    ( (This)->lpVtbl -> GetFrameRate(This,frameDuration,timeScale) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkDisplayMode_v7_1_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkVideoFrame_v7_1_INTERFACE_DEFINED__\r
+#define __IDeckLinkVideoFrame_v7_1_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkVideoFrame_v7_1 */\r
+/* [helpstring][local][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkVideoFrame_v7_1;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("333F3A10-8C2D-43CF-B79D-46560FEEA1CE")\r
+    IDeckLinkVideoFrame_v7_1 : public IUnknown\r
+    {\r
+    public:\r
+        virtual long STDMETHODCALLTYPE GetWidth( void) = 0;\r
+        \r
+        virtual long STDMETHODCALLTYPE GetHeight( void) = 0;\r
+        \r
+        virtual long STDMETHODCALLTYPE GetRowBytes( void) = 0;\r
+        \r
+        virtual BMDPixelFormat STDMETHODCALLTYPE GetPixelFormat( void) = 0;\r
+        \r
+        virtual BMDFrameFlags STDMETHODCALLTYPE GetFlags( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetBytes( \r
+            void **buffer) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkVideoFrame_v7_1Vtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkVideoFrame_v7_1 * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkVideoFrame_v7_1 * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkVideoFrame_v7_1 * This);\r
+        \r
+        long ( STDMETHODCALLTYPE *GetWidth )( \r
+            IDeckLinkVideoFrame_v7_1 * This);\r
+        \r
+        long ( STDMETHODCALLTYPE *GetHeight )( \r
+            IDeckLinkVideoFrame_v7_1 * This);\r
+        \r
+        long ( STDMETHODCALLTYPE *GetRowBytes )( \r
+            IDeckLinkVideoFrame_v7_1 * This);\r
+        \r
+        BMDPixelFormat ( STDMETHODCALLTYPE *GetPixelFormat )( \r
+            IDeckLinkVideoFrame_v7_1 * This);\r
+        \r
+        BMDFrameFlags ( STDMETHODCALLTYPE *GetFlags )( \r
+            IDeckLinkVideoFrame_v7_1 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetBytes )( \r
+            IDeckLinkVideoFrame_v7_1 * This,\r
+            void **buffer);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkVideoFrame_v7_1Vtbl;\r
+\r
+    interface IDeckLinkVideoFrame_v7_1\r
+    {\r
+        CONST_VTBL struct IDeckLinkVideoFrame_v7_1Vtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkVideoFrame_v7_1_QueryInterface(This,riid,ppvObject)   \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkVideoFrame_v7_1_AddRef(This)  \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkVideoFrame_v7_1_Release(This) \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkVideoFrame_v7_1_GetWidth(This)        \\r
+    ( (This)->lpVtbl -> GetWidth(This) ) \r
+\r
+#define IDeckLinkVideoFrame_v7_1_GetHeight(This)       \\r
+    ( (This)->lpVtbl -> GetHeight(This) ) \r
+\r
+#define IDeckLinkVideoFrame_v7_1_GetRowBytes(This)     \\r
+    ( (This)->lpVtbl -> GetRowBytes(This) ) \r
+\r
+#define IDeckLinkVideoFrame_v7_1_GetPixelFormat(This)  \\r
+    ( (This)->lpVtbl -> GetPixelFormat(This) ) \r
+\r
+#define IDeckLinkVideoFrame_v7_1_GetFlags(This)        \\r
+    ( (This)->lpVtbl -> GetFlags(This) ) \r
+\r
+#define IDeckLinkVideoFrame_v7_1_GetBytes(This,buffer) \\r
+    ( (This)->lpVtbl -> GetBytes(This,buffer) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkVideoFrame_v7_1_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkVideoInputFrame_v7_1_INTERFACE_DEFINED__\r
+#define __IDeckLinkVideoInputFrame_v7_1_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkVideoInputFrame_v7_1 */\r
+/* [helpstring][local][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkVideoInputFrame_v7_1;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("C8B41D95-8848-40EE-9B37-6E3417FB114B")\r
+    IDeckLinkVideoInputFrame_v7_1 : public IDeckLinkVideoFrame_v7_1\r
+    {\r
+    public:\r
+        virtual HRESULT STDMETHODCALLTYPE GetFrameTime( \r
+            BMDTimeValue *frameTime,\r
+            BMDTimeValue *frameDuration,\r
+            BMDTimeScale timeScale) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkVideoInputFrame_v7_1Vtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkVideoInputFrame_v7_1 * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkVideoInputFrame_v7_1 * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkVideoInputFrame_v7_1 * This);\r
+        \r
+        long ( STDMETHODCALLTYPE *GetWidth )( \r
+            IDeckLinkVideoInputFrame_v7_1 * This);\r
+        \r
+        long ( STDMETHODCALLTYPE *GetHeight )( \r
+            IDeckLinkVideoInputFrame_v7_1 * This);\r
+        \r
+        long ( STDMETHODCALLTYPE *GetRowBytes )( \r
+            IDeckLinkVideoInputFrame_v7_1 * This);\r
+        \r
+        BMDPixelFormat ( STDMETHODCALLTYPE *GetPixelFormat )( \r
+            IDeckLinkVideoInputFrame_v7_1 * This);\r
+        \r
+        BMDFrameFlags ( STDMETHODCALLTYPE *GetFlags )( \r
+            IDeckLinkVideoInputFrame_v7_1 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetBytes )( \r
+            IDeckLinkVideoInputFrame_v7_1 * This,\r
+            void **buffer);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetFrameTime )( \r
+            IDeckLinkVideoInputFrame_v7_1 * This,\r
+            BMDTimeValue *frameTime,\r
+            BMDTimeValue *frameDuration,\r
+            BMDTimeScale timeScale);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkVideoInputFrame_v7_1Vtbl;\r
+\r
+    interface IDeckLinkVideoInputFrame_v7_1\r
+    {\r
+        CONST_VTBL struct IDeckLinkVideoInputFrame_v7_1Vtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkVideoInputFrame_v7_1_QueryInterface(This,riid,ppvObject)      \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkVideoInputFrame_v7_1_AddRef(This)     \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkVideoInputFrame_v7_1_Release(This)    \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkVideoInputFrame_v7_1_GetWidth(This)   \\r
+    ( (This)->lpVtbl -> GetWidth(This) ) \r
+\r
+#define IDeckLinkVideoInputFrame_v7_1_GetHeight(This)  \\r
+    ( (This)->lpVtbl -> GetHeight(This) ) \r
+\r
+#define IDeckLinkVideoInputFrame_v7_1_GetRowBytes(This)        \\r
+    ( (This)->lpVtbl -> GetRowBytes(This) ) \r
+\r
+#define IDeckLinkVideoInputFrame_v7_1_GetPixelFormat(This)     \\r
+    ( (This)->lpVtbl -> GetPixelFormat(This) ) \r
+\r
+#define IDeckLinkVideoInputFrame_v7_1_GetFlags(This)   \\r
+    ( (This)->lpVtbl -> GetFlags(This) ) \r
+\r
+#define IDeckLinkVideoInputFrame_v7_1_GetBytes(This,buffer)    \\r
+    ( (This)->lpVtbl -> GetBytes(This,buffer) ) \r
+\r
+\r
+#define IDeckLinkVideoInputFrame_v7_1_GetFrameTime(This,frameTime,frameDuration,timeScale)     \\r
+    ( (This)->lpVtbl -> GetFrameTime(This,frameTime,frameDuration,timeScale) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkVideoInputFrame_v7_1_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkAudioInputPacket_v7_1_INTERFACE_DEFINED__\r
+#define __IDeckLinkAudioInputPacket_v7_1_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkAudioInputPacket_v7_1 */\r
+/* [helpstring][local][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkAudioInputPacket_v7_1;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("C86DE4F6-A29F-42E3-AB3A-1363E29F0788")\r
+    IDeckLinkAudioInputPacket_v7_1 : public IUnknown\r
+    {\r
+    public:\r
+        virtual long STDMETHODCALLTYPE GetSampleCount( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetBytes( \r
+            void **buffer) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetAudioPacketTime( \r
+            BMDTimeValue *packetTime,\r
+            BMDTimeScale timeScale) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkAudioInputPacket_v7_1Vtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkAudioInputPacket_v7_1 * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkAudioInputPacket_v7_1 * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkAudioInputPacket_v7_1 * This);\r
+        \r
+        long ( STDMETHODCALLTYPE *GetSampleCount )( \r
+            IDeckLinkAudioInputPacket_v7_1 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetBytes )( \r
+            IDeckLinkAudioInputPacket_v7_1 * This,\r
+            void **buffer);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetAudioPacketTime )( \r
+            IDeckLinkAudioInputPacket_v7_1 * This,\r
+            BMDTimeValue *packetTime,\r
+            BMDTimeScale timeScale);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkAudioInputPacket_v7_1Vtbl;\r
+\r
+    interface IDeckLinkAudioInputPacket_v7_1\r
+    {\r
+        CONST_VTBL struct IDeckLinkAudioInputPacket_v7_1Vtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkAudioInputPacket_v7_1_QueryInterface(This,riid,ppvObject)     \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkAudioInputPacket_v7_1_AddRef(This)    \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkAudioInputPacket_v7_1_Release(This)   \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkAudioInputPacket_v7_1_GetSampleCount(This)    \\r
+    ( (This)->lpVtbl -> GetSampleCount(This) ) \r
+\r
+#define IDeckLinkAudioInputPacket_v7_1_GetBytes(This,buffer)   \\r
+    ( (This)->lpVtbl -> GetBytes(This,buffer) ) \r
+\r
+#define IDeckLinkAudioInputPacket_v7_1_GetAudioPacketTime(This,packetTime,timeScale)   \\r
+    ( (This)->lpVtbl -> GetAudioPacketTime(This,packetTime,timeScale) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkAudioInputPacket_v7_1_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkVideoOutputCallback_v7_1_INTERFACE_DEFINED__\r
+#define __IDeckLinkVideoOutputCallback_v7_1_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkVideoOutputCallback_v7_1 */\r
+/* [helpstring][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkVideoOutputCallback_v7_1;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("EBD01AFA-E4B0-49C6-A01D-EDB9D1B55FD9")\r
+    IDeckLinkVideoOutputCallback_v7_1 : public IUnknown\r
+    {\r
+    public:\r
+        virtual HRESULT STDMETHODCALLTYPE ScheduledFrameCompleted( \r
+            /* [in] */ IDeckLinkVideoFrame_v7_1 *completedFrame,\r
+            /* [in] */ BMDOutputFrameCompletionResult result) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkVideoOutputCallback_v7_1Vtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkVideoOutputCallback_v7_1 * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkVideoOutputCallback_v7_1 * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkVideoOutputCallback_v7_1 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *ScheduledFrameCompleted )( \r
+            IDeckLinkVideoOutputCallback_v7_1 * This,\r
+            /* [in] */ IDeckLinkVideoFrame_v7_1 *completedFrame,\r
+            /* [in] */ BMDOutputFrameCompletionResult result);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkVideoOutputCallback_v7_1Vtbl;\r
+\r
+    interface IDeckLinkVideoOutputCallback_v7_1\r
+    {\r
+        CONST_VTBL struct IDeckLinkVideoOutputCallback_v7_1Vtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkVideoOutputCallback_v7_1_QueryInterface(This,riid,ppvObject)  \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkVideoOutputCallback_v7_1_AddRef(This) \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkVideoOutputCallback_v7_1_Release(This)        \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkVideoOutputCallback_v7_1_ScheduledFrameCompleted(This,completedFrame,result)  \\r
+    ( (This)->lpVtbl -> ScheduledFrameCompleted(This,completedFrame,result) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkVideoOutputCallback_v7_1_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkInputCallback_v7_1_INTERFACE_DEFINED__\r
+#define __IDeckLinkInputCallback_v7_1_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkInputCallback_v7_1 */\r
+/* [helpstring][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkInputCallback_v7_1;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("7F94F328-5ED4-4E9F-9729-76A86BDC99CC")\r
+    IDeckLinkInputCallback_v7_1 : public IUnknown\r
+    {\r
+    public:\r
+        virtual HRESULT STDMETHODCALLTYPE VideoInputFrameArrived( \r
+            /* [in] */ IDeckLinkVideoInputFrame_v7_1 *videoFrame,\r
+            /* [in] */ IDeckLinkAudioInputPacket_v7_1 *audioPacket) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkInputCallback_v7_1Vtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkInputCallback_v7_1 * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkInputCallback_v7_1 * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkInputCallback_v7_1 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *VideoInputFrameArrived )( \r
+            IDeckLinkInputCallback_v7_1 * This,\r
+            /* [in] */ IDeckLinkVideoInputFrame_v7_1 *videoFrame,\r
+            /* [in] */ IDeckLinkAudioInputPacket_v7_1 *audioPacket);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkInputCallback_v7_1Vtbl;\r
+\r
+    interface IDeckLinkInputCallback_v7_1\r
+    {\r
+        CONST_VTBL struct IDeckLinkInputCallback_v7_1Vtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkInputCallback_v7_1_QueryInterface(This,riid,ppvObject)        \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkInputCallback_v7_1_AddRef(This)       \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkInputCallback_v7_1_Release(This)      \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkInputCallback_v7_1_VideoInputFrameArrived(This,videoFrame,audioPacket)        \\r
+    ( (This)->lpVtbl -> VideoInputFrameArrived(This,videoFrame,audioPacket) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkInputCallback_v7_1_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkOutput_v7_1_INTERFACE_DEFINED__\r
+#define __IDeckLinkOutput_v7_1_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkOutput_v7_1 */\r
+/* [helpstring][local][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkOutput_v7_1;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("AE5B3E9B-4E1E-4535-B6E8-480FF52F6CE5")\r
+    IDeckLinkOutput_v7_1 : public IUnknown\r
+    {\r
+    public:\r
+        virtual HRESULT STDMETHODCALLTYPE DoesSupportVideoMode( \r
+            BMDDisplayMode displayMode,\r
+            BMDPixelFormat pixelFormat,\r
+            /* [out] */ BMDDisplayModeSupport *result) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetDisplayModeIterator( \r
+            /* [out] */ IDeckLinkDisplayModeIterator_v7_1 **iterator) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE EnableVideoOutput( \r
+            BMDDisplayMode displayMode) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE DisableVideoOutput( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE SetVideoOutputFrameMemoryAllocator( \r
+            /* [in] */ IDeckLinkMemoryAllocator *theAllocator) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE CreateVideoFrame( \r
+            long width,\r
+            long height,\r
+            long rowBytes,\r
+            BMDPixelFormat pixelFormat,\r
+            BMDFrameFlags flags,\r
+            IDeckLinkVideoFrame_v7_1 **outFrame) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE CreateVideoFrameFromBuffer( \r
+            void *buffer,\r
+            long width,\r
+            long height,\r
+            long rowBytes,\r
+            BMDPixelFormat pixelFormat,\r
+            BMDFrameFlags flags,\r
+            IDeckLinkVideoFrame_v7_1 **outFrame) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE DisplayVideoFrameSync( \r
+            IDeckLinkVideoFrame_v7_1 *theFrame) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE ScheduleVideoFrame( \r
+            IDeckLinkVideoFrame_v7_1 *theFrame,\r
+            BMDTimeValue displayTime,\r
+            BMDTimeValue displayDuration,\r
+            BMDTimeScale timeScale) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE SetScheduledFrameCompletionCallback( \r
+            /* [in] */ IDeckLinkVideoOutputCallback_v7_1 *theCallback) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE EnableAudioOutput( \r
+            BMDAudioSampleRate sampleRate,\r
+            BMDAudioSampleType sampleType,\r
+            unsigned long channelCount) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE DisableAudioOutput( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE WriteAudioSamplesSync( \r
+            void *buffer,\r
+            unsigned long sampleFrameCount,\r
+            /* [out] */ unsigned long *sampleFramesWritten) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE BeginAudioPreroll( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE EndAudioPreroll( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE ScheduleAudioSamples( \r
+            void *buffer,\r
+            unsigned long sampleFrameCount,\r
+            BMDTimeValue streamTime,\r
+            BMDTimeScale timeScale,\r
+            /* [out] */ unsigned long *sampleFramesWritten) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetBufferedAudioSampleFrameCount( \r
+            /* [out] */ unsigned long *bufferedSampleCount) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE FlushBufferedAudioSamples( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE SetAudioCallback( \r
+            /* [in] */ IDeckLinkAudioOutputCallback *theCallback) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE StartScheduledPlayback( \r
+            BMDTimeValue playbackStartTime,\r
+            BMDTimeScale timeScale,\r
+            double playbackSpeed) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE StopScheduledPlayback( \r
+            BMDTimeValue stopPlaybackAtTime,\r
+            BMDTimeValue *actualStopTime,\r
+            BMDTimeScale timeScale) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetHardwareReferenceClock( \r
+            BMDTimeScale desiredTimeScale,\r
+            BMDTimeValue *elapsedTimeSinceSchedulerBegan) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkOutput_v7_1Vtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkOutput_v7_1 * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkOutput_v7_1 * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkOutput_v7_1 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *DoesSupportVideoMode )( \r
+            IDeckLinkOutput_v7_1 * This,\r
+            BMDDisplayMode displayMode,\r
+            BMDPixelFormat pixelFormat,\r
+            /* [out] */ BMDDisplayModeSupport *result);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetDisplayModeIterator )( \r
+            IDeckLinkOutput_v7_1 * This,\r
+            /* [out] */ IDeckLinkDisplayModeIterator_v7_1 **iterator);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *EnableVideoOutput )( \r
+            IDeckLinkOutput_v7_1 * This,\r
+            BMDDisplayMode displayMode);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *DisableVideoOutput )( \r
+            IDeckLinkOutput_v7_1 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetVideoOutputFrameMemoryAllocator )( \r
+            IDeckLinkOutput_v7_1 * This,\r
+            /* [in] */ IDeckLinkMemoryAllocator *theAllocator);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *CreateVideoFrame )( \r
+            IDeckLinkOutput_v7_1 * This,\r
+            long width,\r
+            long height,\r
+            long rowBytes,\r
+            BMDPixelFormat pixelFormat,\r
+            BMDFrameFlags flags,\r
+            IDeckLinkVideoFrame_v7_1 **outFrame);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *CreateVideoFrameFromBuffer )( \r
+            IDeckLinkOutput_v7_1 * This,\r
+            void *buffer,\r
+            long width,\r
+            long height,\r
+            long rowBytes,\r
+            BMDPixelFormat pixelFormat,\r
+            BMDFrameFlags flags,\r
+            IDeckLinkVideoFrame_v7_1 **outFrame);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *DisplayVideoFrameSync )( \r
+            IDeckLinkOutput_v7_1 * This,\r
+            IDeckLinkVideoFrame_v7_1 *theFrame);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *ScheduleVideoFrame )( \r
+            IDeckLinkOutput_v7_1 * This,\r
+            IDeckLinkVideoFrame_v7_1 *theFrame,\r
+            BMDTimeValue displayTime,\r
+            BMDTimeValue displayDuration,\r
+            BMDTimeScale timeScale);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetScheduledFrameCompletionCallback )( \r
+            IDeckLinkOutput_v7_1 * This,\r
+            /* [in] */ IDeckLinkVideoOutputCallback_v7_1 *theCallback);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *EnableAudioOutput )( \r
+            IDeckLinkOutput_v7_1 * This,\r
+            BMDAudioSampleRate sampleRate,\r
+            BMDAudioSampleType sampleType,\r
+            unsigned long channelCount);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *DisableAudioOutput )( \r
+            IDeckLinkOutput_v7_1 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *WriteAudioSamplesSync )( \r
+            IDeckLinkOutput_v7_1 * This,\r
+            void *buffer,\r
+            unsigned long sampleFrameCount,\r
+            /* [out] */ unsigned long *sampleFramesWritten);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *BeginAudioPreroll )( \r
+            IDeckLinkOutput_v7_1 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *EndAudioPreroll )( \r
+            IDeckLinkOutput_v7_1 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *ScheduleAudioSamples )( \r
+            IDeckLinkOutput_v7_1 * This,\r
+            void *buffer,\r
+            unsigned long sampleFrameCount,\r
+            BMDTimeValue streamTime,\r
+            BMDTimeScale timeScale,\r
+            /* [out] */ unsigned long *sampleFramesWritten);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetBufferedAudioSampleFrameCount )( \r
+            IDeckLinkOutput_v7_1 * This,\r
+            /* [out] */ unsigned long *bufferedSampleCount);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *FlushBufferedAudioSamples )( \r
+            IDeckLinkOutput_v7_1 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetAudioCallback )( \r
+            IDeckLinkOutput_v7_1 * This,\r
+            /* [in] */ IDeckLinkAudioOutputCallback *theCallback);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *StartScheduledPlayback )( \r
+            IDeckLinkOutput_v7_1 * This,\r
+            BMDTimeValue playbackStartTime,\r
+            BMDTimeScale timeScale,\r
+            double playbackSpeed);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *StopScheduledPlayback )( \r
+            IDeckLinkOutput_v7_1 * This,\r
+            BMDTimeValue stopPlaybackAtTime,\r
+            BMDTimeValue *actualStopTime,\r
+            BMDTimeScale timeScale);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetHardwareReferenceClock )( \r
+            IDeckLinkOutput_v7_1 * This,\r
+            BMDTimeScale desiredTimeScale,\r
+            BMDTimeValue *elapsedTimeSinceSchedulerBegan);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkOutput_v7_1Vtbl;\r
+\r
+    interface IDeckLinkOutput_v7_1\r
+    {\r
+        CONST_VTBL struct IDeckLinkOutput_v7_1Vtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkOutput_v7_1_QueryInterface(This,riid,ppvObject)       \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkOutput_v7_1_AddRef(This)      \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkOutput_v7_1_Release(This)     \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkOutput_v7_1_DoesSupportVideoMode(This,displayMode,pixelFormat,result) \\r
+    ( (This)->lpVtbl -> DoesSupportVideoMode(This,displayMode,pixelFormat,result) ) \r
+\r
+#define IDeckLinkOutput_v7_1_GetDisplayModeIterator(This,iterator)     \\r
+    ( (This)->lpVtbl -> GetDisplayModeIterator(This,iterator) ) \r
+\r
+#define IDeckLinkOutput_v7_1_EnableVideoOutput(This,displayMode)       \\r
+    ( (This)->lpVtbl -> EnableVideoOutput(This,displayMode) ) \r
+\r
+#define IDeckLinkOutput_v7_1_DisableVideoOutput(This)  \\r
+    ( (This)->lpVtbl -> DisableVideoOutput(This) ) \r
+\r
+#define IDeckLinkOutput_v7_1_SetVideoOutputFrameMemoryAllocator(This,theAllocator)     \\r
+    ( (This)->lpVtbl -> SetVideoOutputFrameMemoryAllocator(This,theAllocator) ) \r
+\r
+#define IDeckLinkOutput_v7_1_CreateVideoFrame(This,width,height,rowBytes,pixelFormat,flags,outFrame)   \\r
+    ( (This)->lpVtbl -> CreateVideoFrame(This,width,height,rowBytes,pixelFormat,flags,outFrame) ) \r
+\r
+#define IDeckLinkOutput_v7_1_CreateVideoFrameFromBuffer(This,buffer,width,height,rowBytes,pixelFormat,flags,outFrame)  \\r
+    ( (This)->lpVtbl -> CreateVideoFrameFromBuffer(This,buffer,width,height,rowBytes,pixelFormat,flags,outFrame) ) \r
+\r
+#define IDeckLinkOutput_v7_1_DisplayVideoFrameSync(This,theFrame)      \\r
+    ( (This)->lpVtbl -> DisplayVideoFrameSync(This,theFrame) ) \r
+\r
+#define IDeckLinkOutput_v7_1_ScheduleVideoFrame(This,theFrame,displayTime,displayDuration,timeScale)   \\r
+    ( (This)->lpVtbl -> ScheduleVideoFrame(This,theFrame,displayTime,displayDuration,timeScale) ) \r
+\r
+#define IDeckLinkOutput_v7_1_SetScheduledFrameCompletionCallback(This,theCallback)     \\r
+    ( (This)->lpVtbl -> SetScheduledFrameCompletionCallback(This,theCallback) ) \r
+\r
+#define IDeckLinkOutput_v7_1_EnableAudioOutput(This,sampleRate,sampleType,channelCount)        \\r
+    ( (This)->lpVtbl -> EnableAudioOutput(This,sampleRate,sampleType,channelCount) ) \r
+\r
+#define IDeckLinkOutput_v7_1_DisableAudioOutput(This)  \\r
+    ( (This)->lpVtbl -> DisableAudioOutput(This) ) \r
+\r
+#define IDeckLinkOutput_v7_1_WriteAudioSamplesSync(This,buffer,sampleFrameCount,sampleFramesWritten)   \\r
+    ( (This)->lpVtbl -> WriteAudioSamplesSync(This,buffer,sampleFrameCount,sampleFramesWritten) ) \r
+\r
+#define IDeckLinkOutput_v7_1_BeginAudioPreroll(This)   \\r
+    ( (This)->lpVtbl -> BeginAudioPreroll(This) ) \r
+\r
+#define IDeckLinkOutput_v7_1_EndAudioPreroll(This)     \\r
+    ( (This)->lpVtbl -> EndAudioPreroll(This) ) \r
+\r
+#define IDeckLinkOutput_v7_1_ScheduleAudioSamples(This,buffer,sampleFrameCount,streamTime,timeScale,sampleFramesWritten)       \\r
+    ( (This)->lpVtbl -> ScheduleAudioSamples(This,buffer,sampleFrameCount,streamTime,timeScale,sampleFramesWritten) ) \r
+\r
+#define IDeckLinkOutput_v7_1_GetBufferedAudioSampleFrameCount(This,bufferedSampleCount)        \\r
+    ( (This)->lpVtbl -> GetBufferedAudioSampleFrameCount(This,bufferedSampleCount) ) \r
+\r
+#define IDeckLinkOutput_v7_1_FlushBufferedAudioSamples(This)   \\r
+    ( (This)->lpVtbl -> FlushBufferedAudioSamples(This) ) \r
+\r
+#define IDeckLinkOutput_v7_1_SetAudioCallback(This,theCallback)        \\r
+    ( (This)->lpVtbl -> SetAudioCallback(This,theCallback) ) \r
+\r
+#define IDeckLinkOutput_v7_1_StartScheduledPlayback(This,playbackStartTime,timeScale,playbackSpeed)    \\r
+    ( (This)->lpVtbl -> StartScheduledPlayback(This,playbackStartTime,timeScale,playbackSpeed) ) \r
+\r
+#define IDeckLinkOutput_v7_1_StopScheduledPlayback(This,stopPlaybackAtTime,actualStopTime,timeScale)   \\r
+    ( (This)->lpVtbl -> StopScheduledPlayback(This,stopPlaybackAtTime,actualStopTime,timeScale) ) \r
+\r
+#define IDeckLinkOutput_v7_1_GetHardwareReferenceClock(This,desiredTimeScale,elapsedTimeSinceSchedulerBegan)   \\r
+    ( (This)->lpVtbl -> GetHardwareReferenceClock(This,desiredTimeScale,elapsedTimeSinceSchedulerBegan) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkOutput_v7_1_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkInput_v7_1_INTERFACE_DEFINED__\r
+#define __IDeckLinkInput_v7_1_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkInput_v7_1 */\r
+/* [helpstring][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkInput_v7_1;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("2B54EDEF-5B32-429F-BA11-BB990596EACD")\r
+    IDeckLinkInput_v7_1 : public IUnknown\r
+    {\r
+    public:\r
+        virtual HRESULT STDMETHODCALLTYPE DoesSupportVideoMode( \r
+            BMDDisplayMode displayMode,\r
+            BMDPixelFormat pixelFormat,\r
+            /* [out] */ BMDDisplayModeSupport *result) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetDisplayModeIterator( \r
+            /* [out] */ IDeckLinkDisplayModeIterator_v7_1 **iterator) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE EnableVideoInput( \r
+            BMDDisplayMode displayMode,\r
+            BMDPixelFormat pixelFormat,\r
+            BMDVideoInputFlags flags) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE DisableVideoInput( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE EnableAudioInput( \r
+            BMDAudioSampleRate sampleRate,\r
+            BMDAudioSampleType sampleType,\r
+            unsigned long channelCount) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE DisableAudioInput( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE ReadAudioSamples( \r
+            void *buffer,\r
+            unsigned long sampleFrameCount,\r
+            /* [out] */ unsigned long *sampleFramesRead,\r
+            /* [out] */ BMDTimeValue *audioPacketTime,\r
+            BMDTimeScale timeScale) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetBufferedAudioSampleFrameCount( \r
+            /* [out] */ unsigned long *bufferedSampleCount) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE StartStreams( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE StopStreams( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE PauseStreams( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE SetCallback( \r
+            /* [in] */ IDeckLinkInputCallback_v7_1 *theCallback) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkInput_v7_1Vtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkInput_v7_1 * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkInput_v7_1 * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkInput_v7_1 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *DoesSupportVideoMode )( \r
+            IDeckLinkInput_v7_1 * This,\r
+            BMDDisplayMode displayMode,\r
+            BMDPixelFormat pixelFormat,\r
+            /* [out] */ BMDDisplayModeSupport *result);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetDisplayModeIterator )( \r
+            IDeckLinkInput_v7_1 * This,\r
+            /* [out] */ IDeckLinkDisplayModeIterator_v7_1 **iterator);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *EnableVideoInput )( \r
+            IDeckLinkInput_v7_1 * This,\r
+            BMDDisplayMode displayMode,\r
+            BMDPixelFormat pixelFormat,\r
+            BMDVideoInputFlags flags);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *DisableVideoInput )( \r
+            IDeckLinkInput_v7_1 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *EnableAudioInput )( \r
+            IDeckLinkInput_v7_1 * This,\r
+            BMDAudioSampleRate sampleRate,\r
+            BMDAudioSampleType sampleType,\r
+            unsigned long channelCount);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *DisableAudioInput )( \r
+            IDeckLinkInput_v7_1 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *ReadAudioSamples )( \r
+            IDeckLinkInput_v7_1 * This,\r
+            void *buffer,\r
+            unsigned long sampleFrameCount,\r
+            /* [out] */ unsigned long *sampleFramesRead,\r
+            /* [out] */ BMDTimeValue *audioPacketTime,\r
+            BMDTimeScale timeScale);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetBufferedAudioSampleFrameCount )( \r
+            IDeckLinkInput_v7_1 * This,\r
+            /* [out] */ unsigned long *bufferedSampleCount);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *StartStreams )( \r
+            IDeckLinkInput_v7_1 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *StopStreams )( \r
+            IDeckLinkInput_v7_1 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *PauseStreams )( \r
+            IDeckLinkInput_v7_1 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetCallback )( \r
+            IDeckLinkInput_v7_1 * This,\r
+            /* [in] */ IDeckLinkInputCallback_v7_1 *theCallback);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkInput_v7_1Vtbl;\r
+\r
+    interface IDeckLinkInput_v7_1\r
+    {\r
+        CONST_VTBL struct IDeckLinkInput_v7_1Vtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkInput_v7_1_QueryInterface(This,riid,ppvObject)        \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkInput_v7_1_AddRef(This)       \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkInput_v7_1_Release(This)      \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkInput_v7_1_DoesSupportVideoMode(This,displayMode,pixelFormat,result)  \\r
+    ( (This)->lpVtbl -> DoesSupportVideoMode(This,displayMode,pixelFormat,result) ) \r
+\r
+#define IDeckLinkInput_v7_1_GetDisplayModeIterator(This,iterator)      \\r
+    ( (This)->lpVtbl -> GetDisplayModeIterator(This,iterator) ) \r
+\r
+#define IDeckLinkInput_v7_1_EnableVideoInput(This,displayMode,pixelFormat,flags)       \\r
+    ( (This)->lpVtbl -> EnableVideoInput(This,displayMode,pixelFormat,flags) ) \r
+\r
+#define IDeckLinkInput_v7_1_DisableVideoInput(This)    \\r
+    ( (This)->lpVtbl -> DisableVideoInput(This) ) \r
+\r
+#define IDeckLinkInput_v7_1_EnableAudioInput(This,sampleRate,sampleType,channelCount)  \\r
+    ( (This)->lpVtbl -> EnableAudioInput(This,sampleRate,sampleType,channelCount) ) \r
+\r
+#define IDeckLinkInput_v7_1_DisableAudioInput(This)    \\r
+    ( (This)->lpVtbl -> DisableAudioInput(This) ) \r
+\r
+#define IDeckLinkInput_v7_1_ReadAudioSamples(This,buffer,sampleFrameCount,sampleFramesRead,audioPacketTime,timeScale)  \\r
+    ( (This)->lpVtbl -> ReadAudioSamples(This,buffer,sampleFrameCount,sampleFramesRead,audioPacketTime,timeScale) ) \r
+\r
+#define IDeckLinkInput_v7_1_GetBufferedAudioSampleFrameCount(This,bufferedSampleCount) \\r
+    ( (This)->lpVtbl -> GetBufferedAudioSampleFrameCount(This,bufferedSampleCount) ) \r
+\r
+#define IDeckLinkInput_v7_1_StartStreams(This) \\r
+    ( (This)->lpVtbl -> StartStreams(This) ) \r
+\r
+#define IDeckLinkInput_v7_1_StopStreams(This)  \\r
+    ( (This)->lpVtbl -> StopStreams(This) ) \r
+\r
+#define IDeckLinkInput_v7_1_PauseStreams(This) \\r
+    ( (This)->lpVtbl -> PauseStreams(This) ) \r
+\r
+#define IDeckLinkInput_v7_1_SetCallback(This,theCallback)      \\r
+    ( (This)->lpVtbl -> SetCallback(This,theCallback) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkInput_v7_1_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkInputCallback_v7_3_INTERFACE_DEFINED__\r
+#define __IDeckLinkInputCallback_v7_3_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkInputCallback_v7_3 */\r
+/* [helpstring][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkInputCallback_v7_3;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("FD6F311D-4D00-444B-9ED4-1F25B5730AD0")\r
+    IDeckLinkInputCallback_v7_3 : public IUnknown\r
+    {\r
+    public:\r
+        virtual HRESULT STDMETHODCALLTYPE VideoInputFormatChanged( \r
+            /* [in] */ BMDVideoInputFormatChangedEvents notificationEvents,\r
+            /* [in] */ IDeckLinkDisplayMode *newDisplayMode,\r
+            /* [in] */ BMDDetectedVideoInputFormatFlags detectedSignalFlags) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE VideoInputFrameArrived( \r
+            /* [in] */ IDeckLinkVideoInputFrame_v7_3 *videoFrame,\r
+            /* [in] */ IDeckLinkAudioInputPacket *audioPacket) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkInputCallback_v7_3Vtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkInputCallback_v7_3 * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkInputCallback_v7_3 * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkInputCallback_v7_3 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *VideoInputFormatChanged )( \r
+            IDeckLinkInputCallback_v7_3 * This,\r
+            /* [in] */ BMDVideoInputFormatChangedEvents notificationEvents,\r
+            /* [in] */ IDeckLinkDisplayMode *newDisplayMode,\r
+            /* [in] */ BMDDetectedVideoInputFormatFlags detectedSignalFlags);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *VideoInputFrameArrived )( \r
+            IDeckLinkInputCallback_v7_3 * This,\r
+            /* [in] */ IDeckLinkVideoInputFrame_v7_3 *videoFrame,\r
+            /* [in] */ IDeckLinkAudioInputPacket *audioPacket);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkInputCallback_v7_3Vtbl;\r
+\r
+    interface IDeckLinkInputCallback_v7_3\r
+    {\r
+        CONST_VTBL struct IDeckLinkInputCallback_v7_3Vtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkInputCallback_v7_3_QueryInterface(This,riid,ppvObject)        \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkInputCallback_v7_3_AddRef(This)       \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkInputCallback_v7_3_Release(This)      \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkInputCallback_v7_3_VideoInputFormatChanged(This,notificationEvents,newDisplayMode,detectedSignalFlags)        \\r
+    ( (This)->lpVtbl -> VideoInputFormatChanged(This,notificationEvents,newDisplayMode,detectedSignalFlags) ) \r
+\r
+#define IDeckLinkInputCallback_v7_3_VideoInputFrameArrived(This,videoFrame,audioPacket)        \\r
+    ( (This)->lpVtbl -> VideoInputFrameArrived(This,videoFrame,audioPacket) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkInputCallback_v7_3_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkOutput_v7_3_INTERFACE_DEFINED__\r
+#define __IDeckLinkOutput_v7_3_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkOutput_v7_3 */\r
+/* [helpstring][local][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkOutput_v7_3;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("271C65E3-C323-4344-A30F-D908BCB20AA3")\r
+    IDeckLinkOutput_v7_3 : public IUnknown\r
+    {\r
+    public:\r
+        virtual HRESULT STDMETHODCALLTYPE DoesSupportVideoMode( \r
+            BMDDisplayMode displayMode,\r
+            BMDPixelFormat pixelFormat,\r
+            /* [out] */ BMDDisplayModeSupport *result) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetDisplayModeIterator( \r
+            /* [out] */ IDeckLinkDisplayModeIterator **iterator) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE SetScreenPreviewCallback( \r
+            /* [in] */ IDeckLinkScreenPreviewCallback *previewCallback) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE EnableVideoOutput( \r
+            BMDDisplayMode displayMode,\r
+            BMDVideoOutputFlags flags) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE DisableVideoOutput( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE SetVideoOutputFrameMemoryAllocator( \r
+            /* [in] */ IDeckLinkMemoryAllocator *theAllocator) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE CreateVideoFrame( \r
+            long width,\r
+            long height,\r
+            long rowBytes,\r
+            BMDPixelFormat pixelFormat,\r
+            BMDFrameFlags flags,\r
+            /* [out] */ IDeckLinkMutableVideoFrame **outFrame) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE CreateAncillaryData( \r
+            BMDDisplayMode displayMode,\r
+            BMDPixelFormat pixelFormat,\r
+            /* [out] */ IDeckLinkVideoFrameAncillary **outBuffer) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE DisplayVideoFrameSync( \r
+            /* [in] */ IDeckLinkVideoFrame *theFrame) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE ScheduleVideoFrame( \r
+            /* [in] */ IDeckLinkVideoFrame *theFrame,\r
+            BMDTimeValue displayTime,\r
+            BMDTimeValue displayDuration,\r
+            BMDTimeScale timeScale) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE SetScheduledFrameCompletionCallback( \r
+            /* [in] */ IDeckLinkVideoOutputCallback *theCallback) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetBufferedVideoFrameCount( \r
+            /* [out] */ unsigned long *bufferedFrameCount) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE EnableAudioOutput( \r
+            BMDAudioSampleRate sampleRate,\r
+            BMDAudioSampleType sampleType,\r
+            unsigned long channelCount,\r
+            BMDAudioOutputStreamType streamType) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE DisableAudioOutput( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE WriteAudioSamplesSync( \r
+            /* [in] */ void *buffer,\r
+            unsigned long sampleFrameCount,\r
+            /* [out] */ unsigned long *sampleFramesWritten) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE BeginAudioPreroll( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE EndAudioPreroll( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE ScheduleAudioSamples( \r
+            /* [in] */ void *buffer,\r
+            unsigned long sampleFrameCount,\r
+            BMDTimeValue streamTime,\r
+            BMDTimeScale timeScale,\r
+            /* [out] */ unsigned long *sampleFramesWritten) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetBufferedAudioSampleFrameCount( \r
+            /* [out] */ unsigned long *bufferedSampleFrameCount) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE FlushBufferedAudioSamples( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE SetAudioCallback( \r
+            /* [in] */ IDeckLinkAudioOutputCallback *theCallback) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE StartScheduledPlayback( \r
+            BMDTimeValue playbackStartTime,\r
+            BMDTimeScale timeScale,\r
+            double playbackSpeed) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE StopScheduledPlayback( \r
+            BMDTimeValue stopPlaybackAtTime,\r
+            /* [out] */ BMDTimeValue *actualStopTime,\r
+            BMDTimeScale timeScale) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE IsScheduledPlaybackRunning( \r
+            /* [out] */ BOOL *active) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetHardwareReferenceClock( \r
+            BMDTimeScale desiredTimeScale,\r
+            /* [out] */ BMDTimeValue *elapsedTimeSinceSchedulerBegan) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkOutput_v7_3Vtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkOutput_v7_3 * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkOutput_v7_3 * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkOutput_v7_3 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *DoesSupportVideoMode )( \r
+            IDeckLinkOutput_v7_3 * This,\r
+            BMDDisplayMode displayMode,\r
+            BMDPixelFormat pixelFormat,\r
+            /* [out] */ BMDDisplayModeSupport *result);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetDisplayModeIterator )( \r
+            IDeckLinkOutput_v7_3 * This,\r
+            /* [out] */ IDeckLinkDisplayModeIterator **iterator);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetScreenPreviewCallback )( \r
+            IDeckLinkOutput_v7_3 * This,\r
+            /* [in] */ IDeckLinkScreenPreviewCallback *previewCallback);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *EnableVideoOutput )( \r
+            IDeckLinkOutput_v7_3 * This,\r
+            BMDDisplayMode displayMode,\r
+            BMDVideoOutputFlags flags);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *DisableVideoOutput )( \r
+            IDeckLinkOutput_v7_3 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetVideoOutputFrameMemoryAllocator )( \r
+            IDeckLinkOutput_v7_3 * This,\r
+            /* [in] */ IDeckLinkMemoryAllocator *theAllocator);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *CreateVideoFrame )( \r
+            IDeckLinkOutput_v7_3 * This,\r
+            long width,\r
+            long height,\r
+            long rowBytes,\r
+            BMDPixelFormat pixelFormat,\r
+            BMDFrameFlags flags,\r
+            /* [out] */ IDeckLinkMutableVideoFrame **outFrame);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *CreateAncillaryData )( \r
+            IDeckLinkOutput_v7_3 * This,\r
+            BMDDisplayMode displayMode,\r
+            BMDPixelFormat pixelFormat,\r
+            /* [out] */ IDeckLinkVideoFrameAncillary **outBuffer);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *DisplayVideoFrameSync )( \r
+            IDeckLinkOutput_v7_3 * This,\r
+            /* [in] */ IDeckLinkVideoFrame *theFrame);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *ScheduleVideoFrame )( \r
+            IDeckLinkOutput_v7_3 * This,\r
+            /* [in] */ IDeckLinkVideoFrame *theFrame,\r
+            BMDTimeValue displayTime,\r
+            BMDTimeValue displayDuration,\r
+            BMDTimeScale timeScale);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetScheduledFrameCompletionCallback )( \r
+            IDeckLinkOutput_v7_3 * This,\r
+            /* [in] */ IDeckLinkVideoOutputCallback *theCallback);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetBufferedVideoFrameCount )( \r
+            IDeckLinkOutput_v7_3 * This,\r
+            /* [out] */ unsigned long *bufferedFrameCount);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *EnableAudioOutput )( \r
+            IDeckLinkOutput_v7_3 * This,\r
+            BMDAudioSampleRate sampleRate,\r
+            BMDAudioSampleType sampleType,\r
+            unsigned long channelCount,\r
+            BMDAudioOutputStreamType streamType);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *DisableAudioOutput )( \r
+            IDeckLinkOutput_v7_3 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *WriteAudioSamplesSync )( \r
+            IDeckLinkOutput_v7_3 * This,\r
+            /* [in] */ void *buffer,\r
+            unsigned long sampleFrameCount,\r
+            /* [out] */ unsigned long *sampleFramesWritten);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *BeginAudioPreroll )( \r
+            IDeckLinkOutput_v7_3 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *EndAudioPreroll )( \r
+            IDeckLinkOutput_v7_3 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *ScheduleAudioSamples )( \r
+            IDeckLinkOutput_v7_3 * This,\r
+            /* [in] */ void *buffer,\r
+            unsigned long sampleFrameCount,\r
+            BMDTimeValue streamTime,\r
+            BMDTimeScale timeScale,\r
+            /* [out] */ unsigned long *sampleFramesWritten);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetBufferedAudioSampleFrameCount )( \r
+            IDeckLinkOutput_v7_3 * This,\r
+            /* [out] */ unsigned long *bufferedSampleFrameCount);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *FlushBufferedAudioSamples )( \r
+            IDeckLinkOutput_v7_3 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetAudioCallback )( \r
+            IDeckLinkOutput_v7_3 * This,\r
+            /* [in] */ IDeckLinkAudioOutputCallback *theCallback);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *StartScheduledPlayback )( \r
+            IDeckLinkOutput_v7_3 * This,\r
+            BMDTimeValue playbackStartTime,\r
+            BMDTimeScale timeScale,\r
+            double playbackSpeed);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *StopScheduledPlayback )( \r
+            IDeckLinkOutput_v7_3 * This,\r
+            BMDTimeValue stopPlaybackAtTime,\r
+            /* [out] */ BMDTimeValue *actualStopTime,\r
+            BMDTimeScale timeScale);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *IsScheduledPlaybackRunning )( \r
+            IDeckLinkOutput_v7_3 * This,\r
+            /* [out] */ BOOL *active);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetHardwareReferenceClock )( \r
+            IDeckLinkOutput_v7_3 * This,\r
+            BMDTimeScale desiredTimeScale,\r
+            /* [out] */ BMDTimeValue *elapsedTimeSinceSchedulerBegan);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkOutput_v7_3Vtbl;\r
+\r
+    interface IDeckLinkOutput_v7_3\r
+    {\r
+        CONST_VTBL struct IDeckLinkOutput_v7_3Vtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkOutput_v7_3_QueryInterface(This,riid,ppvObject)       \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkOutput_v7_3_AddRef(This)      \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkOutput_v7_3_Release(This)     \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkOutput_v7_3_DoesSupportVideoMode(This,displayMode,pixelFormat,result) \\r
+    ( (This)->lpVtbl -> DoesSupportVideoMode(This,displayMode,pixelFormat,result) ) \r
+\r
+#define IDeckLinkOutput_v7_3_GetDisplayModeIterator(This,iterator)     \\r
+    ( (This)->lpVtbl -> GetDisplayModeIterator(This,iterator) ) \r
+\r
+#define IDeckLinkOutput_v7_3_SetScreenPreviewCallback(This,previewCallback)    \\r
+    ( (This)->lpVtbl -> SetScreenPreviewCallback(This,previewCallback) ) \r
+\r
+#define IDeckLinkOutput_v7_3_EnableVideoOutput(This,displayMode,flags) \\r
+    ( (This)->lpVtbl -> EnableVideoOutput(This,displayMode,flags) ) \r
+\r
+#define IDeckLinkOutput_v7_3_DisableVideoOutput(This)  \\r
+    ( (This)->lpVtbl -> DisableVideoOutput(This) ) \r
+\r
+#define IDeckLinkOutput_v7_3_SetVideoOutputFrameMemoryAllocator(This,theAllocator)     \\r
+    ( (This)->lpVtbl -> SetVideoOutputFrameMemoryAllocator(This,theAllocator) ) \r
+\r
+#define IDeckLinkOutput_v7_3_CreateVideoFrame(This,width,height,rowBytes,pixelFormat,flags,outFrame)   \\r
+    ( (This)->lpVtbl -> CreateVideoFrame(This,width,height,rowBytes,pixelFormat,flags,outFrame) ) \r
+\r
+#define IDeckLinkOutput_v7_3_CreateAncillaryData(This,displayMode,pixelFormat,outBuffer)       \\r
+    ( (This)->lpVtbl -> CreateAncillaryData(This,displayMode,pixelFormat,outBuffer) ) \r
+\r
+#define IDeckLinkOutput_v7_3_DisplayVideoFrameSync(This,theFrame)      \\r
+    ( (This)->lpVtbl -> DisplayVideoFrameSync(This,theFrame) ) \r
+\r
+#define IDeckLinkOutput_v7_3_ScheduleVideoFrame(This,theFrame,displayTime,displayDuration,timeScale)   \\r
+    ( (This)->lpVtbl -> ScheduleVideoFrame(This,theFrame,displayTime,displayDuration,timeScale) ) \r
+\r
+#define IDeckLinkOutput_v7_3_SetScheduledFrameCompletionCallback(This,theCallback)     \\r
+    ( (This)->lpVtbl -> SetScheduledFrameCompletionCallback(This,theCallback) ) \r
+\r
+#define IDeckLinkOutput_v7_3_GetBufferedVideoFrameCount(This,bufferedFrameCount)       \\r
+    ( (This)->lpVtbl -> GetBufferedVideoFrameCount(This,bufferedFrameCount) ) \r
+\r
+#define IDeckLinkOutput_v7_3_EnableAudioOutput(This,sampleRate,sampleType,channelCount,streamType)     \\r
+    ( (This)->lpVtbl -> EnableAudioOutput(This,sampleRate,sampleType,channelCount,streamType) ) \r
+\r
+#define IDeckLinkOutput_v7_3_DisableAudioOutput(This)  \\r
+    ( (This)->lpVtbl -> DisableAudioOutput(This) ) \r
+\r
+#define IDeckLinkOutput_v7_3_WriteAudioSamplesSync(This,buffer,sampleFrameCount,sampleFramesWritten)   \\r
+    ( (This)->lpVtbl -> WriteAudioSamplesSync(This,buffer,sampleFrameCount,sampleFramesWritten) ) \r
+\r
+#define IDeckLinkOutput_v7_3_BeginAudioPreroll(This)   \\r
+    ( (This)->lpVtbl -> BeginAudioPreroll(This) ) \r
+\r
+#define IDeckLinkOutput_v7_3_EndAudioPreroll(This)     \\r
+    ( (This)->lpVtbl -> EndAudioPreroll(This) ) \r
+\r
+#define IDeckLinkOutput_v7_3_ScheduleAudioSamples(This,buffer,sampleFrameCount,streamTime,timeScale,sampleFramesWritten)       \\r
+    ( (This)->lpVtbl -> ScheduleAudioSamples(This,buffer,sampleFrameCount,streamTime,timeScale,sampleFramesWritten) ) \r
+\r
+#define IDeckLinkOutput_v7_3_GetBufferedAudioSampleFrameCount(This,bufferedSampleFrameCount)   \\r
+    ( (This)->lpVtbl -> GetBufferedAudioSampleFrameCount(This,bufferedSampleFrameCount) ) \r
+\r
+#define IDeckLinkOutput_v7_3_FlushBufferedAudioSamples(This)   \\r
+    ( (This)->lpVtbl -> FlushBufferedAudioSamples(This) ) \r
+\r
+#define IDeckLinkOutput_v7_3_SetAudioCallback(This,theCallback)        \\r
+    ( (This)->lpVtbl -> SetAudioCallback(This,theCallback) ) \r
+\r
+#define IDeckLinkOutput_v7_3_StartScheduledPlayback(This,playbackStartTime,timeScale,playbackSpeed)    \\r
+    ( (This)->lpVtbl -> StartScheduledPlayback(This,playbackStartTime,timeScale,playbackSpeed) ) \r
+\r
+#define IDeckLinkOutput_v7_3_StopScheduledPlayback(This,stopPlaybackAtTime,actualStopTime,timeScale)   \\r
+    ( (This)->lpVtbl -> StopScheduledPlayback(This,stopPlaybackAtTime,actualStopTime,timeScale) ) \r
+\r
+#define IDeckLinkOutput_v7_3_IsScheduledPlaybackRunning(This,active)   \\r
+    ( (This)->lpVtbl -> IsScheduledPlaybackRunning(This,active) ) \r
+\r
+#define IDeckLinkOutput_v7_3_GetHardwareReferenceClock(This,desiredTimeScale,elapsedTimeSinceSchedulerBegan)   \\r
+    ( (This)->lpVtbl -> GetHardwareReferenceClock(This,desiredTimeScale,elapsedTimeSinceSchedulerBegan) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkOutput_v7_3_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkInput_v7_3_INTERFACE_DEFINED__\r
+#define __IDeckLinkInput_v7_3_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkInput_v7_3 */\r
+/* [helpstring][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkInput_v7_3;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("4973F012-9925-458C-871C-18774CDBBECB")\r
+    IDeckLinkInput_v7_3 : public IUnknown\r
+    {\r
+    public:\r
+        virtual HRESULT STDMETHODCALLTYPE DoesSupportVideoMode( \r
+            BMDDisplayMode displayMode,\r
+            BMDPixelFormat pixelFormat,\r
+            /* [out] */ BMDDisplayModeSupport *result) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetDisplayModeIterator( \r
+            /* [out] */ IDeckLinkDisplayModeIterator **iterator) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE SetScreenPreviewCallback( \r
+            /* [in] */ IDeckLinkScreenPreviewCallback *previewCallback) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE EnableVideoInput( \r
+            BMDDisplayMode displayMode,\r
+            BMDPixelFormat pixelFormat,\r
+            BMDVideoInputFlags flags) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE DisableVideoInput( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetAvailableVideoFrameCount( \r
+            /* [out] */ unsigned long *availableFrameCount) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE EnableAudioInput( \r
+            BMDAudioSampleRate sampleRate,\r
+            BMDAudioSampleType sampleType,\r
+            unsigned long channelCount) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE DisableAudioInput( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE GetAvailableAudioSampleFrameCount( \r
+            /* [out] */ unsigned long *availableSampleFrameCount) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE StartStreams( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE StopStreams( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE PauseStreams( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE FlushStreams( void) = 0;\r
+        \r
+        virtual HRESULT STDMETHODCALLTYPE SetCallback( \r
+            /* [in] */ IDeckLinkInputCallback_v7_3 *theCallback) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkInput_v7_3Vtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkInput_v7_3 * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkInput_v7_3 * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkInput_v7_3 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *DoesSupportVideoMode )( \r
+            IDeckLinkInput_v7_3 * This,\r
+            BMDDisplayMode displayMode,\r
+            BMDPixelFormat pixelFormat,\r
+            /* [out] */ BMDDisplayModeSupport *result);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetDisplayModeIterator )( \r
+            IDeckLinkInput_v7_3 * This,\r
+            /* [out] */ IDeckLinkDisplayModeIterator **iterator);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetScreenPreviewCallback )( \r
+            IDeckLinkInput_v7_3 * This,\r
+            /* [in] */ IDeckLinkScreenPreviewCallback *previewCallback);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *EnableVideoInput )( \r
+            IDeckLinkInput_v7_3 * This,\r
+            BMDDisplayMode displayMode,\r
+            BMDPixelFormat pixelFormat,\r
+            BMDVideoInputFlags flags);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *DisableVideoInput )( \r
+            IDeckLinkInput_v7_3 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetAvailableVideoFrameCount )( \r
+            IDeckLinkInput_v7_3 * This,\r
+            /* [out] */ unsigned long *availableFrameCount);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *EnableAudioInput )( \r
+            IDeckLinkInput_v7_3 * This,\r
+            BMDAudioSampleRate sampleRate,\r
+            BMDAudioSampleType sampleType,\r
+            unsigned long channelCount);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *DisableAudioInput )( \r
+            IDeckLinkInput_v7_3 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetAvailableAudioSampleFrameCount )( \r
+            IDeckLinkInput_v7_3 * This,\r
+            /* [out] */ unsigned long *availableSampleFrameCount);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *StartStreams )( \r
+            IDeckLinkInput_v7_3 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *StopStreams )( \r
+            IDeckLinkInput_v7_3 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *PauseStreams )( \r
+            IDeckLinkInput_v7_3 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *FlushStreams )( \r
+            IDeckLinkInput_v7_3 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *SetCallback )( \r
+            IDeckLinkInput_v7_3 * This,\r
+            /* [in] */ IDeckLinkInputCallback_v7_3 *theCallback);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkInput_v7_3Vtbl;\r
+\r
+    interface IDeckLinkInput_v7_3\r
+    {\r
+        CONST_VTBL struct IDeckLinkInput_v7_3Vtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkInput_v7_3_QueryInterface(This,riid,ppvObject)        \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkInput_v7_3_AddRef(This)       \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkInput_v7_3_Release(This)      \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkInput_v7_3_DoesSupportVideoMode(This,displayMode,pixelFormat,result)  \\r
+    ( (This)->lpVtbl -> DoesSupportVideoMode(This,displayMode,pixelFormat,result) ) \r
+\r
+#define IDeckLinkInput_v7_3_GetDisplayModeIterator(This,iterator)      \\r
+    ( (This)->lpVtbl -> GetDisplayModeIterator(This,iterator) ) \r
+\r
+#define IDeckLinkInput_v7_3_SetScreenPreviewCallback(This,previewCallback)     \\r
+    ( (This)->lpVtbl -> SetScreenPreviewCallback(This,previewCallback) ) \r
+\r
+#define IDeckLinkInput_v7_3_EnableVideoInput(This,displayMode,pixelFormat,flags)       \\r
+    ( (This)->lpVtbl -> EnableVideoInput(This,displayMode,pixelFormat,flags) ) \r
+\r
+#define IDeckLinkInput_v7_3_DisableVideoInput(This)    \\r
+    ( (This)->lpVtbl -> DisableVideoInput(This) ) \r
+\r
+#define IDeckLinkInput_v7_3_GetAvailableVideoFrameCount(This,availableFrameCount)      \\r
+    ( (This)->lpVtbl -> GetAvailableVideoFrameCount(This,availableFrameCount) ) \r
+\r
+#define IDeckLinkInput_v7_3_EnableAudioInput(This,sampleRate,sampleType,channelCount)  \\r
+    ( (This)->lpVtbl -> EnableAudioInput(This,sampleRate,sampleType,channelCount) ) \r
+\r
+#define IDeckLinkInput_v7_3_DisableAudioInput(This)    \\r
+    ( (This)->lpVtbl -> DisableAudioInput(This) ) \r
+\r
+#define IDeckLinkInput_v7_3_GetAvailableAudioSampleFrameCount(This,availableSampleFrameCount)  \\r
+    ( (This)->lpVtbl -> GetAvailableAudioSampleFrameCount(This,availableSampleFrameCount) ) \r
+\r
+#define IDeckLinkInput_v7_3_StartStreams(This) \\r
+    ( (This)->lpVtbl -> StartStreams(This) ) \r
+\r
+#define IDeckLinkInput_v7_3_StopStreams(This)  \\r
+    ( (This)->lpVtbl -> StopStreams(This) ) \r
+\r
+#define IDeckLinkInput_v7_3_PauseStreams(This) \\r
+    ( (This)->lpVtbl -> PauseStreams(This) ) \r
+\r
+#define IDeckLinkInput_v7_3_FlushStreams(This) \\r
+    ( (This)->lpVtbl -> FlushStreams(This) ) \r
+\r
+#define IDeckLinkInput_v7_3_SetCallback(This,theCallback)      \\r
+    ( (This)->lpVtbl -> SetCallback(This,theCallback) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkInput_v7_3_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDeckLinkVideoInputFrame_v7_3_INTERFACE_DEFINED__\r
+#define __IDeckLinkVideoInputFrame_v7_3_INTERFACE_DEFINED__\r
+\r
+/* interface IDeckLinkVideoInputFrame_v7_3 */\r
+/* [helpstring][local][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDeckLinkVideoInputFrame_v7_3;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("CF317790-2894-11DE-8C30-0800200C9A66")\r
+    IDeckLinkVideoInputFrame_v7_3 : public IDeckLinkVideoFrame\r
+    {\r
+    public:\r
+        virtual HRESULT STDMETHODCALLTYPE GetStreamTime( \r
+            /* [out] */ BMDTimeValue *frameTime,\r
+            /* [out] */ BMDTimeValue *frameDuration,\r
+            BMDTimeScale timeScale) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDeckLinkVideoInputFrame_v7_3Vtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDeckLinkVideoInputFrame_v7_3 * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ \r
+            __RPC__deref_out  void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDeckLinkVideoInputFrame_v7_3 * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDeckLinkVideoInputFrame_v7_3 * This);\r
+        \r
+        long ( STDMETHODCALLTYPE *GetWidth )( \r
+            IDeckLinkVideoInputFrame_v7_3 * This);\r
+        \r
+        long ( STDMETHODCALLTYPE *GetHeight )( \r
+            IDeckLinkVideoInputFrame_v7_3 * This);\r
+        \r
+        long ( STDMETHODCALLTYPE *GetRowBytes )( \r
+            IDeckLinkVideoInputFrame_v7_3 * This);\r
+        \r
+        BMDPixelFormat ( STDMETHODCALLTYPE *GetPixelFormat )( \r
+            IDeckLinkVideoInputFrame_v7_3 * This);\r
+        \r
+        BMDFrameFlags ( STDMETHODCALLTYPE *GetFlags )( \r
+            IDeckLinkVideoInputFrame_v7_3 * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetBytes )( \r
+            IDeckLinkVideoInputFrame_v7_3 * This,\r
+            /* [out] */ void **buffer);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetTimecode )( \r
+            IDeckLinkVideoInputFrame_v7_3 * This,\r
+            BMDTimecodeFormat format,\r
+            /* [out] */ IDeckLinkTimecode **timecode);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetAncillaryData )( \r
+            IDeckLinkVideoInputFrame_v7_3 * This,\r
+            /* [out] */ IDeckLinkVideoFrameAncillary **ancillary);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetStreamTime )( \r
+            IDeckLinkVideoInputFrame_v7_3 * This,\r
+            /* [out] */ BMDTimeValue *frameTime,\r
+            /* [out] */ BMDTimeValue *frameDuration,\r
+            BMDTimeScale timeScale);\r
+        \r
+        END_INTERFACE\r
+    } IDeckLinkVideoInputFrame_v7_3Vtbl;\r
+\r
+    interface IDeckLinkVideoInputFrame_v7_3\r
+    {\r
+        CONST_VTBL struct IDeckLinkVideoInputFrame_v7_3Vtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDeckLinkVideoInputFrame_v7_3_QueryInterface(This,riid,ppvObject)      \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IDeckLinkVideoInputFrame_v7_3_AddRef(This)     \\r
+    ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IDeckLinkVideoInputFrame_v7_3_Release(This)    \\r
+    ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IDeckLinkVideoInputFrame_v7_3_GetWidth(This)   \\r
+    ( (This)->lpVtbl -> GetWidth(This) ) \r
+\r
+#define IDeckLinkVideoInputFrame_v7_3_GetHeight(This)  \\r
+    ( (This)->lpVtbl -> GetHeight(This) ) \r
+\r
+#define IDeckLinkVideoInputFrame_v7_3_GetRowBytes(This)        \\r
+    ( (This)->lpVtbl -> GetRowBytes(This) ) \r
+\r
+#define IDeckLinkVideoInputFrame_v7_3_GetPixelFormat(This)     \\r
+    ( (This)->lpVtbl -> GetPixelFormat(This) ) \r
+\r
+#define IDeckLinkVideoInputFrame_v7_3_GetFlags(This)   \\r
+    ( (This)->lpVtbl -> GetFlags(This) ) \r
+\r
+#define IDeckLinkVideoInputFrame_v7_3_GetBytes(This,buffer)    \\r
+    ( (This)->lpVtbl -> GetBytes(This,buffer) ) \r
+\r
+#define IDeckLinkVideoInputFrame_v7_3_GetTimecode(This,format,timecode)        \\r
+    ( (This)->lpVtbl -> GetTimecode(This,format,timecode) ) \r
+\r
+#define IDeckLinkVideoInputFrame_v7_3_GetAncillaryData(This,ancillary) \\r
+    ( (This)->lpVtbl -> GetAncillaryData(This,ancillary) ) \r
+\r
+\r
+#define IDeckLinkVideoInputFrame_v7_3_GetStreamTime(This,frameTime,frameDuration,timeScale)    \\r
+    ( (This)->lpVtbl -> GetStreamTime(This,frameTime,frameDuration,timeScale) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IDeckLinkVideoInputFrame_v7_3_INTERFACE_DEFINED__ */\r
+\r
+#endif /* __DeckLinkAPI_LIBRARY_DEFINED__ */\r
+\r
+/* Additional Prototypes for ALL interfaces */\r
+\r
+/* end of Additional Prototypes */\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
+\r
+\r
diff --git a/server/consumers/decklink/DeckLinkAPI_i.c b/server/consumers/decklink/DeckLinkAPI_i.c
new file mode 100644 (file)
index 0000000..b2e87a9
--- /dev/null
@@ -0,0 +1,190 @@
+\r
+\r
+/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */\r
+\r
+/* link this file in with the server and any clients */\r
+\r
+\r
+ /* File created by MIDL compiler version 7.00.0500 */\r
+/* at Wed Jan 13 09:58:01 2010\r
+ */\r
+/* Compiler settings for .\consumers\declink\DeckLinkAPI.idl:\r
+    Oicf, W1, Zp8, env=Win32 (32b run)\r
+    protocol : dce , ms_ext, c_ext, robust\r
+    error checks: allocation ref bounds_check enum stub_data \r
+    VC __declspec() decoration level: \r
+         __declspec(uuid()), __declspec(selectany), __declspec(novtable)\r
+         DECLSPEC_UUID(), MIDL_INTERFACE()\r
+*/\r
+//@@MIDL_FILE_HEADING(  )\r
+\r
+#pragma warning( disable: 4049 )  /* more than 64k source lines */\r
+\r
+\r
+#ifdef __cplusplus\r
+extern "C"{\r
+#endif \r
+\r
+\r
+#include <rpc.h>\r
+#include <rpcndr.h>\r
+\r
+#ifdef _MIDL_USE_GUIDDEF_\r
+\r
+#ifndef INITGUID\r
+#define INITGUID\r
+#include <guiddef.h>\r
+#undef INITGUID\r
+#else\r
+#include <guiddef.h>\r
+#endif\r
+\r
+#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \\r
+        DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8)\r
+\r
+#else // !_MIDL_USE_GUIDDEF_\r
+\r
+#ifndef __IID_DEFINED__\r
+#define __IID_DEFINED__\r
+\r
+typedef struct _IID\r
+{\r
+    unsigned long x;\r
+    unsigned short s1;\r
+    unsigned short s2;\r
+    unsigned char  c[8];\r
+} IID;\r
+\r
+#endif // __IID_DEFINED__\r
+\r
+#ifndef CLSID_DEFINED\r
+#define CLSID_DEFINED\r
+typedef IID CLSID;\r
+#endif // CLSID_DEFINED\r
+\r
+#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \\r
+        const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}\r
+\r
+#endif !_MIDL_USE_GUIDDEF_\r
+\r
+MIDL_DEFINE_GUID(IID, LIBID_DeckLinkAPI,0xD864517A,0xEDD5,0x466D,0x86,0x7D,0xC8,0x19,0xF1,0xC0,0x52,0xBB);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkVideoOutputCallback,0xE763A626,0x4A3C,0x49D1,0xBF,0x13,0xE7,0xAD,0x36,0x92,0xAE,0x52);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkInputCallback,0x31D28EE7,0x88B6,0x4CB1,0x89,0x7A,0xCD,0xBF,0x79,0xA2,0x64,0x14);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkMemoryAllocator,0xB36EB6E7,0x9D29,0x4AA8,0x92,0xEF,0x84,0x3B,0x87,0xA2,0x89,0xE8);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkAudioOutputCallback,0x403C681B,0x7F46,0x4A12,0xB9,0x93,0x2B,0xB1,0x27,0x08,0x4E,0xE6);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkIterator,0x74E936FC,0xCC28,0x4A67,0x81,0xA0,0x1E,0x94,0xE5,0x2D,0x4E,0x69);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkAPIInformation,0x7BEA3C68,0x730D,0x4322,0xAF,0x34,0x8A,0x71,0x52,0xB5,0x32,0xA4);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkDisplayModeIterator,0x455D741F,0x1779,0x4800,0x86,0xF5,0x0B,0x5D,0x13,0xD7,0x97,0x51);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkDisplayMode,0x87451E84,0x2B7E,0x439E,0xA6,0x29,0x43,0x93,0xEA,0x4A,0x85,0x50);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLink,0x62BFF75D,0x6569,0x4E55,0x8D,0x4D,0x66,0xAA,0x03,0x82,0x9A,0xBC);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkOutput,0x29228142,0xEB8C,0x4141,0xA6,0x21,0xF7,0x40,0x26,0x45,0x09,0x55);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkInput,0x300C135A,0x9F43,0x48E2,0x99,0x06,0x6D,0x79,0x11,0xD9,0x3C,0xF1);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkTimecode,0xEFB9BCA6,0xA521,0x44F7,0xBD,0x69,0x23,0x32,0xF2,0x4D,0x9E,0xE6);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkVideoFrame,0xA8D8238E,0x6B18,0x4196,0x99,0xE1,0x5A,0xF7,0x17,0xB8,0x3D,0x32);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkMutableVideoFrame,0x46FCEE00,0xB4E6,0x43D0,0x91,0xC0,0x02,0x3A,0x7F,0xCE,0xB3,0x4F);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkVideoInputFrame,0x9A74FA41,0xAE9F,0x47AC,0x8C,0xF4,0x01,0xF4,0x2D,0xD5,0x99,0x65);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkVideoFrameAncillary,0x732E723C,0xD1A4,0x4E29,0x9E,0x8E,0x4A,0x88,0x79,0x7A,0x00,0x04);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkAudioInputPacket,0xE43D5870,0x2894,0x11DE,0x8C,0x30,0x08,0x00,0x20,0x0C,0x9A,0x66);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkScreenPreviewCallback,0x373F499D,0x4B4D,0x4518,0xAD,0x22,0x63,0x54,0xE5,0xA5,0x82,0x5E);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkGLScreenPreviewHelper,0xBA575CD9,0xA15E,0x497B,0xB2,0xC2,0xF9,0xAF,0xE7,0xBE,0x4E,0xBA);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkConfiguration,0xB8EAD569,0xB764,0x47F0,0xA7,0x3F,0xAE,0x40,0xDF,0x6C,0xBF,0x10);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkAttributes,0xABC11843,0xD966,0x44CB,0x96,0xE2,0xA1,0xCB,0x5D,0x31,0x35,0xC4);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkKeyer,0x89AFCAF5,0x65F8,0x421E,0x98,0xF7,0x96,0xFE,0x5F,0x5B,0xFB,0xA3);\r
+\r
+\r
+MIDL_DEFINE_GUID(CLSID, CLSID_CDeckLinkIterator,0xD9EDA3B3,0x2887,0x41FA,0xB7,0x24,0x01,0x7C,0xF1,0xEB,0x1D,0x37);\r
+\r
+\r
+MIDL_DEFINE_GUID(CLSID, CLSID_CDeckLinkGLScreenPreviewHelper,0xD398CEE7,0x4434,0x4CA3,0x9B,0xA6,0x5A,0xE3,0x45,0x56,0xB9,0x05);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkDisplayModeIterator_v7_1,0xB28131B6,0x59AC,0x4857,0xB5,0xAC,0xCD,0x75,0xD5,0x88,0x3E,0x2F);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkDisplayMode_v7_1,0xAF0CD6D5,0x8376,0x435E,0x84,0x33,0x54,0xF9,0xDD,0x53,0x0A,0xC3);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkVideoFrame_v7_1,0x333F3A10,0x8C2D,0x43CF,0xB7,0x9D,0x46,0x56,0x0F,0xEE,0xA1,0xCE);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkVideoInputFrame_v7_1,0xC8B41D95,0x8848,0x40EE,0x9B,0x37,0x6E,0x34,0x17,0xFB,0x11,0x4B);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkAudioInputPacket_v7_1,0xC86DE4F6,0xA29F,0x42E3,0xAB,0x3A,0x13,0x63,0xE2,0x9F,0x07,0x88);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkVideoOutputCallback_v7_1,0xEBD01AFA,0xE4B0,0x49C6,0xA0,0x1D,0xED,0xB9,0xD1,0xB5,0x5F,0xD9);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkInputCallback_v7_1,0x7F94F328,0x5ED4,0x4E9F,0x97,0x29,0x76,0xA8,0x6B,0xDC,0x99,0xCC);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkOutput_v7_1,0xAE5B3E9B,0x4E1E,0x4535,0xB6,0xE8,0x48,0x0F,0xF5,0x2F,0x6C,0xE5);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkInput_v7_1,0x2B54EDEF,0x5B32,0x429F,0xBA,0x11,0xBB,0x99,0x05,0x96,0xEA,0xCD);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkInputCallback_v7_3,0xFD6F311D,0x4D00,0x444B,0x9E,0xD4,0x1F,0x25,0xB5,0x73,0x0A,0xD0);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkOutput_v7_3,0x271C65E3,0xC323,0x4344,0xA3,0x0F,0xD9,0x08,0xBC,0xB2,0x0A,0xA3);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkInput_v7_3,0x4973F012,0x9925,0x458C,0x87,0x1C,0x18,0x77,0x4C,0xDB,0xBE,0xCB);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDeckLinkVideoInputFrame_v7_3,0xCF317790,0x2894,0x11DE,0x8C,0x30,0x08,0x00,0x20,0x0C,0x9A,0x66);\r
+\r
+#undef MIDL_DEFINE_GUID\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+\r
+\r
diff --git a/server/consumers/decklink/DeckLinkAPI_v7_1.idl b/server/consumers/decklink/DeckLinkAPI_v7_1.idl
new file mode 100644 (file)
index 0000000..20d4e5f
--- /dev/null
@@ -0,0 +1,160 @@
+/* -LICENSE-START-\r
+** Copyright (c) 2009 Blackmagic Design\r
+**\r
+** Permission is hereby granted, free of charge, to any person or organization\r
+** obtaining a copy of the software and accompanying documentation covered by\r
+** this license (the "Software") to use, reproduce, display, distribute,\r
+** execute, and transmit the Software, and to prepare derivative works of the\r
+** Software, and to permit third-parties to whom the Software is furnished to\r
+** do so, all subject to the following:\r
+** \r
+** The copyright notices in the Software and this entire statement, including\r
+** the above license grant, this restriction and the following disclaimer,\r
+** must be included in all copies of the Software, in whole or in part, and\r
+** all derivative works of the Software, unless such copies or derivative\r
+** works are solely in the form of machine-executable object code generated by\r
+** a source language processor.\r
+** \r
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT\r
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE\r
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,\r
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\r
+** DEALINGS IN THE SOFTWARE.\r
+** -LICENSE-END-\r
+*/\r
+/* DeckLinkAPI_v7_1.idl */\r
+\r
+       interface IDeckLinkDisplayModeIterator_v7_1;\r
+       interface IDeckLinkDisplayMode_v7_1;\r
+       interface IDeckLinkVideoFrame_v7_1;\r
+       interface IDeckLinkVideoInputFrame_v7_1;\r
+       interface IDeckLinkAudioInputPacket_v7_1;\r
+       \r
+       [object, uuid(B28131B6-59AC-4857-B5AC-CD75D5883E2F),\r
+        helpstring("IDeckLinkDisplayModeIterator_v7_1 enumerates over supported input/output display modes.")]\r
+       interface IDeckLinkDisplayModeIterator_v7_1 : IUnknown\r
+       {\r
+               HRESULT         Next ([out] IDeckLinkDisplayMode_v7_1** deckLinkDisplayMode);\r
+       };\r
+\r
+\r
+       [object, uuid(AF0CD6D5-8376-435E-8433-54F9DD530AC3),\r
+        helpstring("IDeckLinkDisplayMode_v7_1 represents a display mode")]\r
+       interface IDeckLinkDisplayMode_v7_1 : IUnknown\r
+       {\r
+               HRESULT                         GetName ([out] BSTR* name);\r
+               BMDDisplayMode          GetDisplayMode ();\r
+               long                            GetWidth ();\r
+               long                            GetHeight ();\r
+               HRESULT                         GetFrameRate ([out] BMDTimeValue *frameDuration, [out] BMDTimeScale *timeScale);\r
+       };\r
+       \r
+       [object, uuid(EBD01AFA-E4B0-49C6-A01D-EDB9D1B55FD9),\r
+     helpstring("IDeckLinkVideoOutputCallback. Frame completion callback.")]\r
+    interface IDeckLinkVideoOutputCallback_v7_1 : IUnknown\r
+    {\r
+        HRESULT                ScheduledFrameCompleted ([in] IDeckLinkVideoFrame_v7_1* completedFrame, [in] BMDOutputFrameCompletionResult result);\r
+    };\r
+       \r
+    [object, uuid(7F94F328-5ED4-4E9F-9729-76A86BDC99CC),\r
+     helpstring("IDeckLinkInputCallback_v7_1. Frame arrival callback.")]\r
+    interface IDeckLinkInputCallback_v7_1 : IUnknown\r
+    {\r
+        HRESULT                VideoInputFrameArrived ([in] IDeckLinkVideoInputFrame_v7_1* videoFrame, [in] IDeckLinkAudioInputPacket_v7_1* audioPacket);\r
+    };\r
+       \r
+\r
+    [object, uuid(AE5B3E9B-4E1E-4535-B6E8-480FF52F6CE5), local,\r
+     helpstring("IDeckLinkOutput_v7_1.  Created by QueryInterface from IDeckLink.")]\r
+    interface IDeckLinkOutput_v7_1 : IUnknown\r
+    {\r
+               HRESULT         DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, [out] BMDDisplayModeSupport *result);\r
+               HRESULT         GetDisplayModeIterator ([out] IDeckLinkDisplayModeIterator_v7_1 **iterator);\r
+               \r
+               // Video output\r
+        HRESULT                EnableVideoOutput (BMDDisplayMode displayMode);\r
+        HRESULT                DisableVideoOutput ();\r
+               \r
+               HRESULT         SetVideoOutputFrameMemoryAllocator ([in] IDeckLinkMemoryAllocator* theAllocator);\r
+        HRESULT                CreateVideoFrame (long width, long height, long rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, IDeckLinkVideoFrame_v7_1** outFrame);\r
+        HRESULT                CreateVideoFrameFromBuffer (void* buffer, long width, long height, long rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, IDeckLinkVideoFrame_v7_1** outFrame);\r
+\r
+        HRESULT                DisplayVideoFrameSync (IDeckLinkVideoFrame_v7_1* theFrame);\r
+        HRESULT                ScheduleVideoFrame (IDeckLinkVideoFrame_v7_1* theFrame, BMDTimeValue displayTime, BMDTimeValue displayDuration, BMDTimeScale timeScale);\r
+        HRESULT                SetScheduledFrameCompletionCallback ([in] IDeckLinkVideoOutputCallback_v7_1* theCallback);\r
+               \r
+               // Audio output\r
+               HRESULT         EnableAudioOutput (BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, unsigned long channelCount);\r
+               HRESULT         DisableAudioOutput ();\r
+               \r
+               HRESULT         WriteAudioSamplesSync (void* buffer, unsigned long sampleFrameCount, [out] unsigned long *sampleFramesWritten);\r
+               \r
+               HRESULT         BeginAudioPreroll ();\r
+               HRESULT         EndAudioPreroll ();\r
+               HRESULT         ScheduleAudioSamples (void* buffer, unsigned long sampleFrameCount, BMDTimeValue streamTime, BMDTimeScale timeScale, [out] unsigned long *sampleFramesWritten);\r
+               \r
+               HRESULT         GetBufferedAudioSampleFrameCount ( [out] unsigned long *bufferedSampleCount);\r
+               HRESULT         FlushBufferedAudioSamples ();\r
+               \r
+               HRESULT         SetAudioCallback ( [in] IDeckLinkAudioOutputCallback* theCallback);\r
+               \r
+               // Output control\r
+        HRESULT                StartScheduledPlayback (BMDTimeValue playbackStartTime, BMDTimeScale timeScale, double playbackSpeed);\r
+        HRESULT                StopScheduledPlayback (BMDTimeValue stopPlaybackAtTime, BMDTimeValue *actualStopTime, BMDTimeScale timeScale);\r
+        HRESULT                GetHardwareReferenceClock (BMDTimeScale desiredTimeScale, BMDTimeValue *elapsedTimeSinceSchedulerBegan);\r
+    };\r
+\r
+    [object, uuid(2B54EDEF-5B32-429F-BA11-BB990596EACD),\r
+     helpstring("IDeckLinkInput_v7_1.  Created by QueryInterface from IDeckLink.")]\r
+    interface IDeckLinkInput_v7_1 : IUnknown\r
+    {\r
+               HRESULT         DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, [out] BMDDisplayModeSupport *result);\r
+               HRESULT         GetDisplayModeIterator ([out] IDeckLinkDisplayModeIterator_v7_1 **iterator);\r
+               \r
+               // Video input\r
+               HRESULT         EnableVideoInput (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDVideoInputFlags flags);\r
+               HRESULT         DisableVideoInput ();\r
+               \r
+               // Audio input\r
+               HRESULT         EnableAudioInput (BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, unsigned long channelCount);\r
+               HRESULT         DisableAudioInput ();\r
+               HRESULT         ReadAudioSamples (void* buffer, unsigned long sampleFrameCount, [out] unsigned long *sampleFramesRead, [out] BMDTimeValue *audioPacketTime, BMDTimeScale timeScale);\r
+               HRESULT         GetBufferedAudioSampleFrameCount ( [out] unsigned long *bufferedSampleCount);\r
+               \r
+               // Input control\r
+               HRESULT         StartStreams ();\r
+               HRESULT         StopStreams ();\r
+               HRESULT         PauseStreams ();\r
+               HRESULT         SetCallback ([in] IDeckLinkInputCallback_v7_1* theCallback);\r
+    };\r
+       \r
+       [object, uuid(333F3A10-8C2D-43CF-B79D-46560FEEA1CE), local,\r
+     helpstring("IDeckLinkVideoFrame_v7_1.  Created by IDeckLinkVideoOutput::CreateVideoFrame.")]\r
+    interface IDeckLinkVideoFrame_v7_1 : IUnknown\r
+    {\r
+        long                           GetWidth ();\r
+        long                           GetHeight ();\r
+        long                           GetRowBytes ();\r
+        BMDPixelFormat         GetPixelFormat ();\r
+        BMDFrameFlags          GetFlags ();\r
+        HRESULT                                GetBytes (void* *buffer);\r
+    };\r
+       \r
+       [object, uuid(C8B41D95-8848-40EE-9B37-6E3417FB114B), local,\r
+     helpstring("IDeckLinkVideoInputFrame_v7_1.  Provided by the IDeckLinkVideoInput frame arrival callback.")]\r
+    interface IDeckLinkVideoInputFrame_v7_1 : IDeckLinkVideoFrame_v7_1\r
+    {\r
+        HRESULT                                GetFrameTime (BMDTimeValue *frameTime, BMDTimeValue *frameDuration, BMDTimeScale timeScale);\r
+    };\r
+       \r
+       [object, uuid(C86DE4F6-A29F-42E3-AB3A-1363E29F0788), local,\r
+     helpstring("IDeckLinkAudioInputPacket_v7_1.  Provided by the IDeckLinkInput callback.")]\r
+    interface IDeckLinkAudioInputPacket_v7_1 : IUnknown\r
+    {\r
+               long                            GetSampleCount ();\r
+               HRESULT                         GetBytes (void* *buffer);\r
+               HRESULT                         GetAudioPacketTime (BMDTimeValue *packetTime, BMDTimeScale timeScale);\r
+    };\r
+       \r
diff --git a/server/consumers/decklink/DeckLinkAPI_v7_3.idl b/server/consumers/decklink/DeckLinkAPI_v7_3.idl
new file mode 100644 (file)
index 0000000..682b200
--- /dev/null
@@ -0,0 +1,157 @@
+/* -LICENSE-START-
+** Copyright (c) 2009 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+** 
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+** 
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+/* Forward Declarations */
+
+interface IDeckLinkInputCallback_v7_3;
+interface IDeckLinkOutput_v7_3;
+interface IDeckLinkInput_v7_3;
+interface IDeckLinkVideoInputFrame_v7_3;
+
+/* End Forward Declarations */
+
+
+/* Interface IDeckLinkInputCallback - Frame arrival callback. */
+
+[
+    object,
+    uuid(FD6F311D-4D00-444B-9ED4-1F25B5730AD0),
+    helpstring("Frame arrival callback.")
+] interface IDeckLinkInputCallback_v7_3 : IUnknown
+{
+    HRESULT VideoInputFormatChanged([in] BMDVideoInputFormatChangedEvents notificationEvents, [in] IDeckLinkDisplayMode *newDisplayMode, [in] BMDDetectedVideoInputFormatFlags detectedSignalFlags);
+    HRESULT VideoInputFrameArrived([in] IDeckLinkVideoInputFrame_v7_3 *videoFrame, [in] IDeckLinkAudioInputPacket *audioPacket);
+};
+
+/* End Interface IDeckLinkInputCallback */
+
+
+/* Interface IDeckLinkOutput - Created by QueryInterface from IDeckLink. */
+
+[
+    object,
+    uuid(271C65E3-C323-4344-A30F-D908BCB20AA3),
+    local, 
+    helpstring("Created by QueryInterface from IDeckLink.")
+] interface IDeckLinkOutput_v7_3 : IUnknown
+{
+    HRESULT DoesSupportVideoMode(BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, [out] BMDDisplayModeSupport *result);
+    HRESULT GetDisplayModeIterator([out] IDeckLinkDisplayModeIterator **iterator);
+
+    HRESULT SetScreenPreviewCallback([in] IDeckLinkScreenPreviewCallback *previewCallback);
+
+    /* Video Output */
+
+    HRESULT EnableVideoOutput(BMDDisplayMode displayMode, BMDVideoOutputFlags flags);
+    HRESULT DisableVideoOutput(void);
+
+    HRESULT SetVideoOutputFrameMemoryAllocator([in] IDeckLinkMemoryAllocator *theAllocator);
+    HRESULT CreateVideoFrame(long width, long height, long rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, [out] IDeckLinkMutableVideoFrame **outFrame);
+    HRESULT CreateAncillaryData(BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, [out] IDeckLinkVideoFrameAncillary **outBuffer);
+
+    HRESULT DisplayVideoFrameSync([in] IDeckLinkVideoFrame *theFrame);
+    HRESULT ScheduleVideoFrame([in] IDeckLinkVideoFrame *theFrame, BMDTimeValue displayTime, BMDTimeValue displayDuration, BMDTimeScale timeScale);
+    HRESULT SetScheduledFrameCompletionCallback([in] IDeckLinkVideoOutputCallback *theCallback);
+    HRESULT GetBufferedVideoFrameCount([out] unsigned long *bufferedFrameCount);
+
+    /* Audio Output */
+
+    HRESULT EnableAudioOutput(BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, unsigned long channelCount, BMDAudioOutputStreamType streamType);
+    HRESULT DisableAudioOutput(void);
+
+    HRESULT WriteAudioSamplesSync([in] void *buffer, unsigned long sampleFrameCount, [out] unsigned long *sampleFramesWritten);
+
+    HRESULT BeginAudioPreroll(void);
+    HRESULT EndAudioPreroll(void);
+    HRESULT ScheduleAudioSamples([in] void *buffer, unsigned long sampleFrameCount, BMDTimeValue streamTime, BMDTimeScale timeScale, [out] unsigned long *sampleFramesWritten);
+
+    HRESULT GetBufferedAudioSampleFrameCount([out] unsigned long *bufferedSampleFrameCount);
+    HRESULT FlushBufferedAudioSamples(void);
+
+    HRESULT SetAudioCallback([in] IDeckLinkAudioOutputCallback *theCallback);
+
+    /* Output Control */
+
+    HRESULT StartScheduledPlayback(BMDTimeValue playbackStartTime, BMDTimeScale timeScale, double playbackSpeed);
+    HRESULT StopScheduledPlayback(BMDTimeValue stopPlaybackAtTime, [out] BMDTimeValue *actualStopTime, BMDTimeScale timeScale);
+    HRESULT IsScheduledPlaybackRunning([out] BOOL *active);
+    HRESULT GetHardwareReferenceClock(BMDTimeScale desiredTimeScale, [out] BMDTimeValue *elapsedTimeSinceSchedulerBegan);
+};
+
+/* End Interface IDeckLinkOutput */
+
+/* Interface IDeckLinkInput - Created by QueryInterface from IDeckLink. */
+
+[
+    object,
+    uuid(4973F012-9925-458C-871C-18774CDBBECB),
+    helpstring("Created by QueryInterface from IDeckLink.")
+] interface IDeckLinkInput_v7_3 : IUnknown
+{
+    HRESULT DoesSupportVideoMode(BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, [out] BMDDisplayModeSupport *result);
+    HRESULT GetDisplayModeIterator([out] IDeckLinkDisplayModeIterator **iterator);
+
+    HRESULT SetScreenPreviewCallback([in] IDeckLinkScreenPreviewCallback *previewCallback);
+
+    /* Video Input */
+
+    HRESULT EnableVideoInput(BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDVideoInputFlags flags);
+    HRESULT DisableVideoInput(void);
+    HRESULT GetAvailableVideoFrameCount([out] unsigned long *availableFrameCount);
+
+    /* Audio Input */
+
+    HRESULT EnableAudioInput(BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, unsigned long channelCount);
+    HRESULT DisableAudioInput(void);
+    HRESULT GetAvailableAudioSampleFrameCount([out] unsigned long *availableSampleFrameCount);
+
+    /* Input Control */
+
+    HRESULT StartStreams(void);
+    HRESULT StopStreams(void);
+    HRESULT PauseStreams(void);
+    HRESULT FlushStreams(void);
+    HRESULT SetCallback([in] IDeckLinkInputCallback_v7_3 *theCallback);
+};
+
+/* End Interface IDeckLinkInput */
+
+
+/* Interface IDeckLinkVideoInputFrame - Provided by the IDeckLinkVideoInput frame arrival callback. */
+
+[
+    object,
+    uuid(CF317790-2894-11DE-8C30-0800200C9A66),
+    local, 
+    helpstring("Provided by the IDeckLinkVideoInput frame arrival callback.")
+] interface IDeckLinkVideoInputFrame_v7_3 : IDeckLinkVideoFrame
+{
+    HRESULT GetStreamTime([out] BMDTimeValue *frameTime, [out] BMDTimeValue *frameDuration, BMDTimeScale timeScale);
+};
+
+/* End Interface IDeckLinkVideoInputFrame */
+
diff --git a/server/consumers/decklink/DecklinkVideoConsumer.cpp b/server/consumers/decklink/DecklinkVideoConsumer.cpp
new file mode 100644 (file)
index 0000000..e21b8b0
--- /dev/null
@@ -0,0 +1,465 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\..\stdafx.h"\r
+\r
+#include "..\..\Application.h"\r
+#include "DecklinkVideoConsumer.h"\r
+#include "..\..\frame\FramePlaybackControl.h"\r
+#include "..\..\frame\Frame.h"\r
+#include "..\..\frame\FramePlaybackStrategy.h"\r
+#include "DeckLinkAPI_h.h"\r
+#include "..\..\utils\image\Image.hpp"\r
+#include "..\..\utils\event.h"\r
+\r
+#include <queue>\r
+\r
+namespace caspar {\r
+namespace decklink {\r
+\r
+\r
+struct DecklinkVideoConsumer::Implementation : public IDeckLinkVideoOutputCallback\r
+{\r
+       //struct DecklinkFrameQueue : private caspar::utils::LockableObject\r
+       //{\r
+       //      std::queue<FramePtr> availibleFrames;\r
+       //      std::queue<FramePtr> scheduledFrames;\r
+\r
+       //      void add_free(FramePtr pFrame) {\r
+       //              availibleFrames.push(pFrame);\r
+       //      }\r
+       //};\r
+\r
+       struct DecklinkFrameManager;\r
+       struct DecklinkVideoFrame : public Frame {\r
+               explicit DecklinkVideoFrame(DecklinkFrameManager* pFactory) : factoryID_(pFactory->ID()) {\r
+                       IDeckLinkMutableVideoFrame* pFrame = NULL;\r
+                       const FrameFormatDescription& fmtDesc = pFactory->pConsumerImpl_->GetFrameFormatDescription();\r
+                       if(pFactory->pConsumerImpl_->pDecklinkOutput_->CreateVideoFrame(fmtDesc.width, fmtDesc.height, fmtDesc.size/fmtDesc.height, bmdFormat8BitBGRA, bmdFrameFlagDefault, &pFrame) != S_OK) {\r
+                               throw std::exception("DECKLINK: Failed to create frame");\r
+                       }\r
+                       pDecklinkFrame_ = pFrame;\r
+                       pFrame->Release();\r
+\r
+                       if(pDecklinkFrame_->GetBytes((void**)&pBytes_) != S_OK)\r
+                               throw std::exception("DECKLINK: Failed to get bytes to frame");\r
+               }\r
+               virtual unsigned char* GetDataPtr() const {\r
+                       HasVideo(true);\r
+                       return pBytes_;\r
+               }\r
+               virtual bool HasValidDataPtr() const {\r
+                       return true;\r
+               }\r
+\r
+               virtual unsigned int GetDataSize() const {\r
+                       return pDecklinkFrame_->GetRowBytes() * pDecklinkFrame_->GetHeight();\r
+               }\r
+               virtual FrameMetadata GetMetadata() const {\r
+                       IDeckLinkMutableVideoFrame* pFramePtr = pDecklinkFrame_;\r
+                       return reinterpret_cast<FrameMetadata>(pFramePtr);\r
+               }\r
+               const utils::ID& FactoryID() const {\r
+                       return factoryID_;\r
+               }\r
+\r
+               utils::ID factoryID_;\r
+               CComPtr<IDeckLinkMutableVideoFrame> pDecklinkFrame_;\r
+               unsigned char* pBytes_;\r
+       };\r
+\r
+       struct DecklinkPlaybackStrategy : public IFramePlaybackStrategy\r
+       {\r
+               explicit DecklinkPlaybackStrategy(Implementation* pConsumerImpl) : pConsumerImpl_(pConsumerImpl), currentReservedFrameIndex_(0), totalFramesScheduled_(0)\r
+               {\r
+                       for(int i = 0; i<4; ++i) {\r
+                               reservedFrames_.push_back(pConsumerImpl_->pFrameManager_->CreateReservedFrame());\r
+                       }\r
+               }\r
+\r
+               FrameManagerPtr GetFrameManager()\r
+               {\r
+                       return pConsumerImpl_->pFrameManager_;\r
+               }\r
+\r
+               FramePtr GetReservedFrame()\r
+               {\r
+                       FramePtr pResult;\r
+                       if(reservedFrames_.size() > currentReservedFrameIndex_) {\r
+                               pResult = reservedFrames_[currentReservedFrameIndex_];\r
+                               currentReservedFrameIndex_ = (currentReservedFrameIndex_+1) & 3;\r
+                       }\r
+                       return pResult;\r
+               }\r
+\r
+               void DisplayFrame(Frame* pFrame)\r
+               {\r
+                       if(pFrame != NULL && pFrame->HasValidDataPtr()) {\r
+                               if(GetFrameManager()->Owns(*pFrame)) {\r
+                                       DoRender(pFrame);\r
+                               }\r
+                               else {\r
+                                       FramePtr pTempFrame = GetReservedFrame();\r
+                                       if(pTempFrame && pFrame->GetDataSize() == pTempFrame->GetDataSize()) {\r
+                                               utils::image::Copy(pTempFrame->GetDataPtr(), pFrame->GetDataPtr(), pTempFrame->GetDataSize());\r
+                                               DoRender(pTempFrame.get());\r
+                                       }\r
+                                       else\r
+                                               LOG << TEXT("DECKLINK: Failed to get reserved frame");\r
+                               }\r
+                       }\r
+                       else {\r
+                               LOG << TEXT("DECKLINK: Tried to render frame with no data");\r
+                       }\r
+               }\r
+               void DoRender(Frame* pFrame) {\r
+                       static DWORD lastTime = 0;\r
+                       static bool bDoLog = true;\r
+                       DWORD timediff = timeGetTime() - lastTime;\r
+                       if(timediff < 30) {\r
+                               Sleep(40 - timediff);\r
+                               lastTime += 40;\r
+                       }\r
+                       else\r
+                               lastTime = timeGetTime();\r
+\r
+                       if(pConsumerImpl_->pDecklinkOutput_->DisplayVideoFrameSync(reinterpret_cast<IDeckLinkMutableVideoFrame*>(pFrame->GetMetadata())) != S_OK) {\r
+                               if(bDoLog) {\r
+                                       LOG << TEXT("DECKLINK: Failed to render frame");\r
+                                       bDoLog = false;\r
+                               }\r
+                       }\r
+                       else {\r
+                               bDoLog = true;\r
+                       }\r
+//                     lastFrameID_ = pFrame->ID();\r
+               }\r
+\r
+               int totalFramesScheduled_;\r
+               std::vector<FramePtr> reservedFrames_;\r
+               unsigned int currentReservedFrameIndex_;\r
+               Implementation* pConsumerImpl_;\r
+       };\r
+       friend struct DecklinkPlaybackStrategy;\r
+\r
+       struct DecklinkFrameManager : public caspar::FrameManager\r
+       {\r
+               explicit DecklinkFrameManager(Implementation* pConsumerImpl) : pConsumerImpl_(pConsumerImpl)\r
+               {\r
+                       pFrameManager_.reset(new SystemFrameManager(pConsumerImpl_->GetFrameFormatDescription()));\r
+               }\r
+\r
+               FramePtr CreateFrame() {\r
+                       return pFrameManager_->CreateFrame();\r
+               }\r
+\r
+               FramePtr CreateReservedFrame() {\r
+                       return FramePtr(new DecklinkVideoFrame(this));\r
+               }\r
+\r
+               const FrameFormatDescription& GetFrameFormatDescription() const {\r
+                       return pConsumerImpl_->GetFrameFormatDescription();\r
+               }\r
+\r
+               Implementation* pConsumerImpl_;\r
+               SystemFrameManagerPtr pFrameManager_;\r
+       };\r
+\r
+       typedef std::tr1::shared_ptr<DecklinkFrameManager> DecklinkFrameManagerPtr;\r
+\r
+       CComPtr<IDeckLink> pDecklink_;\r
+       CComQIPtr<IDeckLinkOutput> pDecklinkOutput_;\r
+       CComQIPtr<IDeckLinkKeyer> pDecklinkKeyer_;\r
+\r
+       FramePlaybackControlPtr pPlaybackControl_;\r
+       DecklinkFrameManagerPtr pFrameManager_;\r
+       FrameFormat currentFormat_;\r
+\r
+//     IDeckLinkMutableVideoFrame* pNextFrame_;\r
+\r
+       explicit Implementation(CComPtr<IDeckLink> pDecklink) : pDecklink_(pDecklink), currentFormat_(FFormatPAL)//, pNextFrame_(NULL)\r
+       {}\r
+\r
+       ~Implementation()\r
+       {\r
+               ReleaseDevice();\r
+       }\r
+\r
+       bool SetupDevice()\r
+       {\r
+               if(!pDecklink_)\r
+                       return false;\r
+\r
+               BSTR pModelName;\r
+               pDecklink_->GetModelName(&pModelName);\r
+               if(pModelName != NULL)\r
+                       LOG << TEXT("DECKLINK: Modelname: ") << pModelName;\r
+\r
+               pDecklinkOutput_ = pDecklink_;\r
+               if(pDecklinkOutput_ == NULL) {\r
+                       LOG << TEXT("DECKLINK: Failed to get IDecklinkOutput interface");\r
+                       return false;\r
+               }\r
+\r
+               tstring strDesiredFrameFormat = TEXT("PAL");//caspar::GetApplication()->GetSetting(TEXT("videomode"));\r
+               if(strDesiredFrameFormat.size() == 0)\r
+                       strDesiredFrameFormat = TEXT("PAL");\r
+               FrameFormat casparVideoFormat = caspar::GetVideoFormat(strDesiredFrameFormat);\r
+               unsigned long decklinkVideoFormat = GetDecklinkVideoFormat(casparVideoFormat);\r
+               if(decklinkVideoFormat == ULONG_MAX) {\r
+                       LOG << "DECKLINK: Card does not support requested videoformat: " << strDesiredFrameFormat;\r
+                       return false;\r
+               }\r
+               \r
+               currentFormat_ = casparVideoFormat;\r
+\r
+               BMDDisplayModeSupport displayModeSupport;\r
+               if(FAILED(pDecklinkOutput_->DoesSupportVideoMode((BMDDisplayMode)decklinkVideoFormat, bmdFormat8BitBGRA, &displayModeSupport))) {\r
+                       LOG << TEXT("DECKLINK: Card does not support requested videoformat");\r
+                       return false;\r
+               }\r
+\r
+               pDecklinkOutput_->DisableAudioOutput();\r
+               if(FAILED(pDecklinkOutput_->EnableVideoOutput((BMDDisplayMode)decklinkVideoFormat, bmdVideoOutputFlagDefault))) {\r
+                       LOG << TEXT("DECKLINK: Could not enable video output");\r
+                       return false;\r
+               }\r
+\r
+               pFrameManager_.reset(new DecklinkFrameManager(this));\r
+\r
+               if(GetApplication()->GetSetting(TEXT("internalkey")) == TEXT("true")) {\r
+                       pDecklinkKeyer_ = pDecklink_;\r
+                       if(pDecklinkKeyer_) {\r
+                               bool bSuccess = true;\r
+                               if(FAILED(pDecklinkKeyer_->Enable(FALSE))) {\r
+                                       LOG << TEXT("DECKLINK: Failed to enable internal keyer");\r
+                                       bSuccess = false;\r
+                               }\r
+                               if(FAILED(pDecklinkKeyer_->SetLevel(255))) {\r
+                                       LOG << TEXT("DECKLINK: Keyer - Failed to set blend-level to max");\r
+                                       bSuccess = false;\r
+                               }\r
+\r
+                               if(bSuccess)\r
+                                       LOG << TEXT("DECKLINK: Successfully configured internal keyer");\r
+                       }\r
+                       else {\r
+                               LOG << TEXT("DECKLINK: Failed to get keyer-interface");\r
+                       }\r
+               }\r
+\r
+               pPlaybackControl_.reset(new FramePlaybackControl(FramePlaybackStrategyPtr(new DecklinkPlaybackStrategy(this))));\r
+               pPlaybackControl_->Start();\r
+\r
+               LOG << TEXT("DECKLINK: Successfully initialized decklink for ") << strDesiredFrameFormat;\r
+               return true;\r
+       }\r
+\r
+       bool ReleaseDevice()\r
+       {\r
+               if(pPlaybackControl_)\r
+                       pPlaybackControl_->Stop();\r
+\r
+               if(pDecklinkKeyer_) {\r
+                       pDecklinkKeyer_.Release();\r
+               }\r
+\r
+               if(pDecklinkOutput_) {\r
+                       BOOL bIsRunning = FALSE;\r
+                       pDecklinkOutput_->IsScheduledPlaybackRunning(&bIsRunning);\r
+                       if(bIsRunning)\r
+                               pDecklinkOutput_->StopScheduledPlayback(0, NULL, 0);\r
+\r
+                       pDecklinkOutput_->DisableVideoOutput();\r
+               }\r
+\r
+               return true;\r
+       }\r
+\r
+       //void DoScheduleNextFrame() {\r
+       //      static int frame = 0;\r
+       //      static bool bLog = true;\r
+       //      if(pDecklinkOutput_->ScheduleVideoFrame(pNextFrame_, frame++, 1, 25) != S_OK) {\r
+       //              if(bLog) {\r
+       //                      LOG << TEXT("DECKLINK: Failed to display frame");\r
+       //                      bLog = false;\r
+       //              }\r
+       //      }\r
+       //      else {\r
+       //              if(((frame-1) % 25) == 0)\r
+       //                      LOG << TEXT("DECKLINK: Scheduled frame ") << (frame-1);\r
+       //              bLog = true;\r
+       //      }\r
+       //}\r
+\r
+       // IUnknown needs o a dummy implementation\r
+       virtual HRESULT STDMETHODCALLTYPE       QueryInterface(REFIID iid, LPVOID *ppv) \r
+       {\r
+               if(ppv != NULL) {\r
+                       if(iid == IID_IUnknown) {\r
+                               (*ppv) = this;\r
+                               return S_OK;\r
+                       }\r
+                       if(iid == IID_IDeckLinkVideoOutputCallback_v7_1) {\r
+                               (*ppv) = (IDeckLinkVideoOutputCallback_v7_1*)this;\r
+                               return S_OK;\r
+                       }\r
+                       if(iid == IID_IDeckLinkVideoOutputCallback) {\r
+                               (*ppv) = (IDeckLinkVideoOutputCallback*)this;\r
+                               return S_OK;\r
+                       }\r
+               }\r
+               return E_NOINTERFACE;\r
+       }\r
+       virtual ULONG STDMETHODCALLTYPE         AddRef() {return 1;}\r
+       virtual ULONG STDMETHODCALLTYPE         Release() {return 1;}\r
+\r
+       virtual HRESULT STDMETHODCALLTYPE ScheduledFrameCompleted(IDeckLinkVideoFrame* completedFrame, BMDOutputFrameCompletionResult result) {\r
+               //DoScheduleNextFrame();\r
+               return S_OK;\r
+       }\r
+\r
+       virtual HRESULT STDMETHODCALLTYPE ScheduledPlaybackHasStopped() {\r
+               return S_OK;\r
+       }\r
+\r
+       const FrameFormatDescription& GetFrameFormatDescription() const {\r
+               return FrameFormatDescription::FormatDescriptions[currentFormat_];\r
+       }\r
+\r
+       unsigned long GetDecklinkVideoFormat(FrameFormat fmt) {\r
+               switch(fmt)\r
+               {\r
+               case FFormatPAL:\r
+                       return bmdModePAL;\r
+\r
+               case FFormatNTSC:\r
+                       return bmdModeNTSC;\r
+\r
+               case FFormat576p2500:\r
+                       return ULONG_MAX;       //not supported\r
+\r
+               case FFormat720p5000:\r
+                       return bmdModeHD720p50;\r
+\r
+               case FFormat720p5994:\r
+                       return bmdModeHD720p5994;\r
+\r
+               case FFormat720p6000:\r
+                       return bmdModeHD720p60;\r
+\r
+               case FFormat1080p2397:\r
+                       return bmdModeHD1080p2398;\r
+\r
+               case FFormat1080p2400:\r
+                       return bmdModeHD1080p24;\r
+\r
+               case FFormat1080i5000:\r
+                       return bmdModeHD1080i50;\r
+\r
+               case FFormat1080i5994:\r
+                       return bmdModeHD1080i5994;\r
+\r
+               case FFormat1080i6000:\r
+                       return bmdModeHD1080i6000;\r
+\r
+               case FFormat1080p2500:\r
+                       return bmdModeHD1080p25;\r
+\r
+               case FFormat1080p2997:\r
+                       return bmdModeHD1080p2997;\r
+\r
+               case FFormat1080p3000:\r
+                       return bmdModeHD1080p30;\r
+               }\r
+\r
+               return ULONG_MAX;\r
+       }\r
+};\r
+\r
+DecklinkVideoConsumer::DecklinkVideoConsumer(ImplementationPtr pImpl) : pImpl_(pImpl)\r
+{}\r
+\r
+DecklinkVideoConsumer::~DecklinkVideoConsumer()\r
+{}\r
+\r
+VideoConsumerPtr DecklinkVideoConsumer::Create() {\r
+       VideoConsumerPtr pResult;\r
+\r
+       CComPtr<IDeckLinkIterator> pDecklinkIterator;\r
+       HRESULT result = pDecklinkIterator.CoCreateInstance(CLSID_CDeckLinkIterator);\r
+       if(FAILED(result)) {\r
+               LOG << TEXT("No Decklink drivers installed");\r
+               return pResult;\r
+       }\r
+\r
+       CComPtr<IDeckLink> pDecklink;\r
+       IDeckLink* pTempDecklink = NULL;\r
+       while(pDecklinkIterator->Next(&pTempDecklink) == S_OK) {\r
+               if(pDecklink == NULL)\r
+                       pDecklink = pTempDecklink;\r
+\r
+               if(pTempDecklink)\r
+                       pTempDecklink->Release();\r
+               pTempDecklink = NULL;\r
+       }\r
+\r
+       if(pDecklink == NULL) {\r
+               LOG << TEXT("No Decklink card found");\r
+               return pResult;\r
+       }\r
+\r
+       ImplementationPtr pImpl(new Implementation(pDecklink));\r
+       pResult.reset(new DecklinkVideoConsumer(pImpl));\r
+\r
+       if(pResult != 0 && pResult->SetupDevice(0) == false)\r
+               pResult.reset();\r
+\r
+       return pResult;\r
+}\r
+\r
+IPlaybackControl* DecklinkVideoConsumer::GetPlaybackControl() const\r
+{\r
+       return pImpl_->pPlaybackControl_.get();\r
+}\r
+\r
+bool DecklinkVideoConsumer::SetupDevice(unsigned int deviceIndex)\r
+{\r
+       return (pImpl_) ? pImpl_->SetupDevice() : false;\r
+}\r
+\r
+bool DecklinkVideoConsumer::ReleaseDevice()\r
+{\r
+       return (pImpl_) ? pImpl_->ReleaseDevice() : false;\r
+}\r
+\r
+void DecklinkVideoConsumer::EnableVideoOutput(){}\r
+void DecklinkVideoConsumer::DisableVideoOutput(){}\r
+\r
+const FrameFormatDescription& DecklinkVideoConsumer::GetFrameFormatDescription() const {\r
+       return pImpl_->GetFrameFormatDescription();\r
+}\r
+const TCHAR* DecklinkVideoConsumer::GetFormatDescription() const {\r
+       return pImpl_->GetFrameFormatDescription().name;\r
+}\r
+\r
+\r
+}      //namespace decklink\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/consumers/decklink/DecklinkVideoConsumer.h b/server/consumers/decklink/DecklinkVideoConsumer.h
new file mode 100644 (file)
index 0000000..b4f94ae
--- /dev/null
@@ -0,0 +1,58 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+#include "..\..\VideoConsumer.h"\r
+#include "..\..\MediaProducer.h"\r
+\r
+#include "..\..\utils\thread.h"\r
+#include "..\..\utils\lockable.h"\r
+#include "..\..\utils\Noncopyable.hpp"\r
+\r
+#include "..\..\frame\Frame.h"\r
+\r
+namespace caspar {\r
+namespace decklink {\r
+\r
+class DecklinkVideoConsumer : public IVideoConsumer, private utils::LockableObject, utils::Noncopyable\r
+{\r
+       struct Implementation;\r
+       typedef std::tr1::shared_ptr<Implementation> ImplementationPtr;\r
+       ImplementationPtr pImpl_;\r
+\r
+       explicit DecklinkVideoConsumer(ImplementationPtr pImpl);\r
+\r
+public:\r
+       virtual ~DecklinkVideoConsumer();\r
+\r
+       static VideoConsumerPtr Create();\r
+\r
+       virtual IPlaybackControl* GetPlaybackControl() const;\r
+\r
+       virtual void EnableVideoOutput();\r
+       virtual void DisableVideoOutput();\r
+       virtual bool SetupDevice(unsigned int deviceIndex);\r
+       virtual bool ReleaseDevice();\r
+       virtual const FrameFormatDescription& GetFrameFormatDescription() const;\r
+       virtual const TCHAR* GetFormatDescription() const;\r
+};\r
+\r
+}      //namespace gdi\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/frame/BitmapFrame.cpp b/server/frame/BitmapFrame.cpp
new file mode 100644 (file)
index 0000000..e8b6dd7
--- /dev/null
@@ -0,0 +1,81 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\StdAfx.h"\r
+#include "BitmapFrame.h"\r
+#include "BitmapFrameManager.h"\r
+\r
+namespace caspar{\r
+\r
+BitmapFrame::BitmapFrame(BitmapHolderPtr pBitmap, const utils::ID& factoryID)\r
+       : pBitmap_(pBitmap), factoryID_(factoryID)\r
+{\r
+}\r
+\r
+BitmapFrame::BitmapFrame(const utils::ID& factoryID, HWND hWnd, size_t height, size_t width, void* memory)\r
+       : pBitmap_(new BitmapHolder(hWnd, height, width, memory)), factoryID_(factoryID)\r
+{\r
+}\r
+\r
+BitmapFrame::~BitmapFrame()\r
+{\r
+}\r
+\r
+unsigned int BitmapFrame::GetDataSize() const \r
+{\r
+       return pBitmap_->Size();\r
+}\r
+\r
+unsigned char* BitmapFrame::GetDataPtr() const \r
+{\r
+       if(pBitmap_ != 0) \r
+       {\r
+               HasVideo(true);\r
+               return pBitmap_->GetPtr();\r
+       }\r
+       return 0;\r
+}\r
+\r
+BitmapHolderPtr BitmapFrame::GetBitmap() const\r
+{\r
+       return pBitmap_;\r
+}\r
+\r
+bool BitmapFrame::HasValidDataPtr() const \r
+{\r
+       return (pBitmap_ != 0 && pBitmap_->GetPtr() != 0);\r
+}\r
+\r
+FrameMetadata BitmapFrame::GetMetadata() const \r
+{\r
+       return (pBitmap_ != 0) ? reinterpret_cast<FrameMetadata>(pBitmap_->GetDC()) : 0;\r
+}\r
+\r
+const utils::ID& BitmapFrame::FactoryID() const\r
+{\r
+       return factoryID_;\r
+}\r
+\r
+HDC BitmapFrame::GetDC() const\r
+{\r
+       return pBitmap_->GetDC();\r
+}\r
+\r
+}
\ No newline at end of file
diff --git a/server/frame/BitmapFrame.h b/server/frame/BitmapFrame.h
new file mode 100644 (file)
index 0000000..0bee32e
--- /dev/null
@@ -0,0 +1,56 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _BITMAP_FRAME_\r
+#define _BITMAP_FRAME_\r
+\r
+#include "..\utils\BitmapHolder.h"\r
+#include "Frame.h"\r
+\r
+namespace caspar{\r
+\r
+class BitmapFrame : public Frame\r
+{\r
+public:\r
+       explicit BitmapFrame(BitmapHolderPtr bitmap, const utils::ID& factoryID);\r
+       BitmapFrame(const utils::ID& factoryID, HWND hWnd, size_t height, size_t width, void* memory = NULL);\r
+       virtual ~BitmapFrame();\r
+\r
+       virtual unsigned char* GetDataPtr() const;\r
+       virtual bool HasValidDataPtr() const;\r
+       virtual unsigned int GetDataSize() const;\r
+       virtual FrameMetadata GetMetadata() const;\r
+\r
+       HDC GetDC() const;\r
+       BitmapHolderPtr GetBitmap() const;\r
+\r
+       const utils::ID& FactoryID() const;     \r
+\r
+private:\r
+       size_t size_;\r
+       BitmapHolderPtr pBitmap_;\r
+       utils::ID factoryID_;\r
+};\r
+typedef std::tr1::shared_ptr<BitmapFrame> BitmapFramePtr;\r
+\r
+}\r
+\r
+#endif\r
+\r
diff --git a/server/frame/BitmapFrameAdapter.cpp b/server/frame/BitmapFrameAdapter.cpp
new file mode 100644 (file)
index 0000000..1ceb770
--- /dev/null
@@ -0,0 +1,44 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\StdAfx.h"\r
+#include "BitmapFrameAdapter.h"\r
+#include "BitmapFrameManager.h"\r
+\r
+namespace caspar{\r
+\r
+struct BitmapHolderAdapter : public caspar::BitmapHolder\r
+{\r
+       BitmapHolderAdapter(HWND hWnd, unsigned int width, unsigned int height, FramePtr pFrame) : BitmapHolder(hWnd, width, height, pFrame->GetDataPtr()), pFrame_(pFrame)\r
+       {\r
+               assert(pFrame->GetDataSize() == width*height*4);\r
+       }\r
+       FramePtr pFrame_;\r
+};\r
+\r
+BitmapFrameAdapter::BitmapFrameAdapter(HWND hWnd, unsigned int width, unsigned int height, FramePtr pFrame, const utils::ID& factoryID) : BitmapFrame(BitmapHolderPtr(new BitmapHolderAdapter(hWnd, width, height, pFrame)), factoryID)\r
+{\r
+}\r
+\r
+BitmapFrameAdapter::~BitmapFrameAdapter()\r
+{\r
+}\r
+\r
+}
\ No newline at end of file
diff --git a/server/frame/BitmapFrameAdapter.h b/server/frame/BitmapFrameAdapter.h
new file mode 100644 (file)
index 0000000..5714fcf
--- /dev/null
@@ -0,0 +1,40 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _BITMAPADAPTER_FRAME_\r
+#define _BITMAPADAPTER_FRAME_\r
+\r
+#include "..\utils\BitmapHolder.h"\r
+#include "BitmapFrame.h"\r
+\r
+namespace caspar{\r
+\r
+class BitmapFrameAdapter : public BitmapFrame\r
+{\r
+public:\r
+       BitmapFrameAdapter(HWND hWnd, unsigned int width, unsigned int height, FramePtr pFrame, const utils::ID& factoryID);\r
+       virtual ~BitmapFrameAdapter();\r
+};\r
+typedef std::tr1::shared_ptr<BitmapFrameAdapter> BitmapFrameAdapterPtr;\r
+\r
+}\r
+\r
+#endif\r
+\r
diff --git a/server/frame/BitmapFrameManager.cpp b/server/frame/BitmapFrameManager.cpp
new file mode 100644 (file)
index 0000000..186a19b
--- /dev/null
@@ -0,0 +1,127 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\stdafx.h"\r
+#include "BitmapFrameManager.h"\r
+#include "BitmapFrame.h"\r
+\r
+#include "..\utils\Lockable.h"\r
+#include "..\utils\BitmapHolder.h"\r
+\r
+#include <algorithm>\r
+\r
+namespace caspar {\r
+\r
+struct BitmapFrameManager::Implementation\r
+{\r
+\r
+       Implementation(BitmapFrameManager* self, const FrameFormatDescription& fmtDesc, HWND hWnd) : self_(self), fmtDesc_(fmtDesc), hWnd_(hWnd), pBitmaps_(new LockableBitmapVector())\r
+       {\r
+               features_.push_back("BITMAP_FRAME");\r
+       }\r
+\r
+       FramePtr CreateFrame()\r
+       {       \r
+               BitmapFramePtr pBitmapFrame;\r
+               {\r
+                       LockableObject::Lock lock(*pBitmaps_);\r
+                       if(!pBitmaps_->empty())\r
+                       {\r
+                               pBitmapFrame = pBitmaps_->back();\r
+                               pBitmaps_->pop_back();\r
+                       }\r
+               }\r
+               \r
+               if(!pBitmapFrame)               \r
+                       pBitmapFrame = self_->CreateBitmapFrame();\r
+               \r
+               class FrameDeallocator\r
+               {\r
+               public:\r
+                       FrameDeallocator(BitmapFramePtr pBitmapFrame, const LockableBitmapVectorPtr pBitmaps) : pBitmapFrame_(pBitmapFrame), pBitmaps_(pBitmaps){}\r
+                       void operator()(BitmapFrame*)\r
+                       {\r
+                               LockableObject::Lock lock(*pBitmaps_);\r
+                               pBitmaps_->push_back(BitmapFramePtr(new BitmapFrame(pBitmapFrame_->GetBitmap(), pBitmapFrame_->FactoryID())));\r
+                       }\r
+               private:\r
+                       LockableBitmapVectorPtr pBitmaps_;\r
+                       BitmapFramePtr pBitmapFrame_;\r
+               };\r
+               \r
+               return BitmapFramePtr(pBitmapFrame.get(), FrameDeallocator(pBitmapFrame, pBitmaps_));\r
+       }\r
+\r
+       const FrameFormatDescription& GetFrameFormatDescription() const \r
+       {\r
+               return fmtDesc_;\r
+       }\r
+\r
+       bool HasFeature(const std::string& feature) const\r
+       {\r
+               return std::find(features_.begin(), features_.end(), feature) != features_.end();\r
+       }\r
+       \r
+       BitmapFramePtr CreateBitmapFrame()\r
+       {\r
+               return BitmapFramePtr(new BitmapFrame(self_->ID(), hWnd_, fmtDesc_.width, fmtDesc_.height));\r
+       }\r
+\r
+       // TODO: need proper threading tools (R.N)\r
+       struct LockableBitmapVector : public std::vector<BitmapFramePtr>, public LockableObject{};\r
+       typedef std::tr1::shared_ptr<LockableBitmapVector> LockableBitmapVectorPtr;\r
+\r
+       LockableBitmapVectorPtr pBitmaps_;\r
+\r
+       std::vector<const std::string> features_;\r
+\r
+       const FrameFormatDescription fmtDesc_;  \r
+       const HWND hWnd_;\r
+\r
+       BitmapFrameManager* self_;\r
+};\r
+\r
+BitmapFrameManager::BitmapFrameManager(const FrameFormatDescription& fmtDesc, HWND hWnd) : pImpl_(new Implementation(this, fmtDesc, hWnd))\r
+{}\r
+\r
+BitmapFrameManager::~BitmapFrameManager()\r
+{}\r
+\r
+FramePtr BitmapFrameManager::CreateFrame()\r
+{      \r
+       return pImpl_->CreateFrame();\r
+}\r
+\r
+const FrameFormatDescription& BitmapFrameManager::GetFrameFormatDescription() const \r
+{\r
+       return pImpl_->GetFrameFormatDescription();\r
+}\r
+\r
+bool BitmapFrameManager::HasFeature(const std::string& feature) const\r
+{\r
+       return pImpl_->HasFeature(feature);\r
+}\r
+\r
+BitmapFramePtr BitmapFrameManager::CreateBitmapFrame()\r
+{\r
+       return pImpl_->CreateBitmapFrame();\r
+}\r
+\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/frame/BitmapFrameManager.h b/server/frame/BitmapFrameManager.h
new file mode 100644 (file)
index 0000000..a30b3e1
--- /dev/null
@@ -0,0 +1,52 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _CASPAR_BITMAPFRAMEMANAGER_H__\r
+#define _CASPAR_BITMAPFRAMEMANAGER_H__\r
+\r
+#include "..\utils\Noncopyable.hpp"\r
+\r
+#include "FrameManager.h"\r
+#include "BitmapFrame.h"\r
+\r
+namespace caspar {\r
+\r
+class BitmapFrameManager : public FrameManager, public utils::LockableObject, private utils::Noncopyable\r
+{      \r
+public:\r
+       BitmapFrameManager(const FrameFormatDescription& fmtDesc, HWND hWnd);\r
+       virtual ~BitmapFrameManager();\r
+\r
+       virtual FramePtr CreateFrame();\r
+       virtual const FrameFormatDescription& GetFrameFormatDescription() const;\r
+\r
+       virtual bool HasFeature(const std::string& feature) const;\r
+\r
+private:\r
+\r
+       virtual BitmapFramePtr CreateBitmapFrame();\r
+\r
+       struct Implementation;\r
+       std::tr1::shared_ptr<Implementation> pImpl_;\r
+};\r
+typedef std::tr1::shared_ptr<BitmapFrameManager> BitmapFrameManagerPtr;\r
+\r
+}      //namespace caspar\r
+#endif 
\ No newline at end of file
diff --git a/server/frame/BitmapFrameManagerAdapter.cpp b/server/frame/BitmapFrameManagerAdapter.cpp
new file mode 100644 (file)
index 0000000..509c648
--- /dev/null
@@ -0,0 +1,59 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\stdafx.h"\r
+#include "BitmapFrameManagerAdapter.h"\r
+#include "BitmapFrameAdapter.h"\r
+\r
+#include "..\utils\Lockable.h"\r
+#include "..\utils\BitmapHolder.h"\r
+\r
+#include <algorithm>\r
+\r
+namespace caspar {\r
+\r
+struct BitmapFrameManagerAdapter::Implementation\r
+{\r
+       Implementation(BitmapFrameManagerAdapter* self, FrameManagerPtr pFrameManager, HWND hWnd) : self_(self), pFrameManager_(pFrameManager), hWnd_(hWnd)\r
+       {\r
+       }\r
+\r
+       BitmapFramePtr CreateBitmapFrame()\r
+       {\r
+               return BitmapFramePtr(new BitmapFrameAdapter(hWnd_, pFrameManager_->GetFrameFormatDescription().width, pFrameManager_->GetFrameFormatDescription().height, pFrameManager_->CreateFrame(), self_->ID()));\r
+       }\r
+\r
+       BitmapFrameManagerAdapter* self_;\r
+       const HWND hWnd_;\r
+       const FrameManagerPtr pFrameManager_;\r
+};\r
+\r
+BitmapFrameManagerAdapter::BitmapFrameManagerAdapter(FrameManagerPtr pFrameManager, HWND hWnd) : BitmapFrameManager(pFrameManager->GetFrameFormatDescription(), hWnd), pImpl_(new Implementation(this, pFrameManager, hWnd))\r
+{}\r
+\r
+BitmapFrameManagerAdapter::~BitmapFrameManagerAdapter()\r
+{}\r
+\r
+BitmapFramePtr BitmapFrameManagerAdapter::CreateBitmapFrame()\r
+{\r
+       return pImpl_->CreateBitmapFrame();\r
+}\r
+\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/frame/BitmapFrameManagerAdapter.h b/server/frame/BitmapFrameManagerAdapter.h
new file mode 100644 (file)
index 0000000..2d64ced
--- /dev/null
@@ -0,0 +1,47 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _CASPAR_BITMAPFRAMEMANAGERADAPTER_H__\r
+#define _CASPAR_BITMAPFRAMEMANAGERADAPTER_H__\r
+\r
+#include "..\utils\Noncopyable.hpp"\r
+\r
+#include "BitmapFrameManager.h"\r
+\r
+namespace caspar {\r
+\r
+class BitmapFrameManagerAdapter : public BitmapFrameManager\r
+{      \r
+public:\r
+       BitmapFrameManagerAdapter(FrameManagerPtr pFrameManager, HWND hWnd);\r
+\r
+       virtual ~BitmapFrameManagerAdapter();\r
+       \r
+private:\r
+       \r
+       virtual BitmapFramePtr CreateBitmapFrame();\r
+\r
+       struct Implementation;\r
+       std::tr1::shared_ptr<Implementation> pImpl_;\r
+};\r
+typedef std::tr1::shared_ptr<BitmapFrameManagerAdapter> BitmapFrameManagerAdapterPtr;\r
+\r
+}      //namespace caspar\r
+#endif 
\ No newline at end of file
diff --git a/server/frame/ClipInfo.h b/server/frame/ClipInfo.h
new file mode 100644 (file)
index 0000000..cc58811
--- /dev/null
@@ -0,0 +1,81 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\MediaProducer.h"\r
+#include "frame.h"\r
+#include "buffers/FrameBuffer.h"\r
+\r
+#pragma once\r
+\r
+namespace caspar {\r
+\r
+class FrameMediaController;\r
+class ITransitionController;\r
+\r
+class ClipInfo\r
+{\r
+public:\r
+       ClipInfo() : pFrameController_(0), pTransitionController_(0), lastFetchResult_(FetchWait), bStopped_(false)\r
+       {}\r
+       ClipInfo(MediaProducerPtr pFP, FrameMediaController* pController) : pFP_(pFP), pFrameController_(pController), pTransitionController_(0), lastFetchResult_(FetchWait), bStopped_(false)\r
+       {}\r
+       ClipInfo(MediaProducerPtr pFP, FrameMediaController* pController, ITransitionController* pTransitionController) : pFP_(pFP), pFrameController_(pController), pTransitionController_(pTransitionController), lastFetchResult_(FetchWait), bStopped_(false)\r
+       {}\r
+\r
+       ClipInfo(const ClipInfo& clipInfo) : pFP_(clipInfo.pFP_), pFrameController_(clipInfo.pFrameController_), pTransitionController_(clipInfo.pTransitionController_), pLastFrame_(clipInfo.pLastFrame_), lastFetchResult_(clipInfo.lastFetchResult_), bStopped_(clipInfo.bStopped_)\r
+       {}\r
+\r
+       ClipInfo& operator=(const ClipInfo& clipInfo) {\r
+               pFP_ = clipInfo.pFP_;\r
+               pFrameController_ = clipInfo.pFrameController_;\r
+               pTransitionController_ = clipInfo.pTransitionController_;\r
+               pLastFrame_ = clipInfo.pLastFrame_;\r
+               lastFetchResult_ = clipInfo.lastFetchResult_;\r
+               bStopped_ = clipInfo.bStopped_;\r
+\r
+               return *this;\r
+       }\r
+\r
+       bool IsEmpty() {\r
+               return (pFrameController_ == 0);\r
+       }\r
+\r
+       ~ClipInfo() {\r
+               Clear();\r
+       }\r
+\r
+       void Clear() {\r
+               pFP_.reset();\r
+               pFrameController_ = 0;\r
+               pTransitionController_ = 0;\r
+               pLastFrame_.reset();\r
+               lastFetchResult_ = FetchWait;\r
+               bStopped_ = false;\r
+       }\r
+\r
+       MediaProducerPtr                pFP_;\r
+       FrameMediaController*   pFrameController_;\r
+       ITransitionController*  pTransitionController_;\r
+       FramePtr                                pLastFrame_;\r
+       FrameBufferFetchResult  lastFetchResult_;\r
+       bool                                    bStopped_;\r
+};\r
+\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/frame/Frame.cpp b/server/frame/Frame.cpp
new file mode 100644 (file)
index 0000000..8cf282c
--- /dev/null
@@ -0,0 +1,81 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\StdAfx.h"\r
+#include "Frame.h"\r
+#include "..\utils\allocator.h"\r
+#include "..\utils\ID.h"\r
+#include "..\utils\image\Image.hpp"\r
+#include "FrameManager.h"\r
+#include <algorithm>\r
+\r
+#include <intrin.h>\r
+#pragma intrinsic(__movsd, __stosd)\r
+\r
+#define DEFINE_VIDEOFORMATDESC(w, h, m, f, s) { (w), (h), (m), (f), (w)*(h)*4, s }\r
+\r
+namespace caspar {\r
+\r
+const FrameFormatDescription FrameFormatDescription::FormatDescriptions[FrameFormatCount] =  { \r
+       DEFINE_VIDEOFORMATDESC(720, 576, Interlaced, 50, TEXT("PAL")), \r
+       DEFINE_VIDEOFORMATDESC(720, 486, Interlaced, 60/1.001, TEXT("NTSC")), \r
+       DEFINE_VIDEOFORMATDESC(720, 576, Progressive, 25, TEXT("576p2500")),\r
+       DEFINE_VIDEOFORMATDESC(1280, 720, Progressive, 50, TEXT("720p5000")), \r
+       DEFINE_VIDEOFORMATDESC(1280, 720, Progressive, 60/1.001, TEXT("720p5994")),\r
+       DEFINE_VIDEOFORMATDESC(1280, 720, Progressive, 60, TEXT("720p6000")),\r
+       DEFINE_VIDEOFORMATDESC(1920, 1080, Progressive, 24/1.001, TEXT("1080p2397")),\r
+       DEFINE_VIDEOFORMATDESC(1920, 1080, Progressive, 24, TEXT("1080p2400")),\r
+       DEFINE_VIDEOFORMATDESC(1920, 1080, Interlaced, 50, TEXT("1080i5000")),\r
+       DEFINE_VIDEOFORMATDESC(1920, 1080, Interlaced, 60/1.001, TEXT("1080i5994")),\r
+       DEFINE_VIDEOFORMATDESC(1920, 1080, Interlaced, 60, TEXT("1080i6000")),\r
+       DEFINE_VIDEOFORMATDESC(1920, 1080, Progressive, 25, TEXT("1080p2500")),\r
+       DEFINE_VIDEOFORMATDESC(1920, 1080, Progressive, 30/1.001, TEXT("1080p2997")),\r
+       DEFINE_VIDEOFORMATDESC(1920, 1080, Progressive, 30, TEXT("1080p3000"))\r
+};\r
+\r
+\r
+FrameFormat GetVideoFormat(const tstring& strVideoMode)\r
+{\r
+       for(int index = 0; index < FrameFormatCount; ++index)\r
+       {\r
+               const FrameFormatDescription& fmtDesc = FrameFormatDescription::FormatDescriptions[index];\r
+\r
+               tstring strVideoModeUpper = strVideoMode;\r
+               tstring strFmtDescUpper = fmtDesc.name;\r
+\r
+               std::transform(strVideoModeUpper.begin(), strVideoModeUpper.end(), strVideoModeUpper.begin(), toupper);\r
+               std::transform(strFmtDescUpper.begin(), strFmtDescUpper.end(), strFmtDescUpper.begin(), toupper);\r
+\r
+               if(strVideoModeUpper == strFmtDescUpper) {\r
+                       return (FrameFormat)index;                      \r
+               }\r
+       }\r
+       return FFormatInvalid;\r
+}\r
+\r
+///////////////\r
+// Frame\r
+Frame::Frame() : bHasVideo_(false)\r
+{}\r
+\r
+Frame::~Frame() {\r
+}\r
+\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/frame/Frame.h b/server/frame/Frame.h
new file mode 100644 (file)
index 0000000..b0928e7
--- /dev/null
@@ -0,0 +1,124 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+\r
+#include "..\utils\event.h"\r
+#include "..\utils\semaphore.h"\r
+#include "..\utils\lockable.h"\r
+#include "..\utils\ID.h"\r
+#include "..\utils\Noncopyable.hpp"\r
+\r
+#include <list>\r
+#include <vector>\r
+\r
+namespace caspar {\r
+\r
+       namespace audio {\r
+               class AudioDataChunk;\r
+               typedef std::tr1::shared_ptr<AudioDataChunk> AudioDataChunkPtr;\r
+       }\r
+\r
+enum VideoUpdateMode {\r
+       Interlaced = 0,\r
+       Progressive\r
+};\r
+\r
+enum FrameFormat {\r
+       FFormatPAL = 0,\r
+       FFormatNTSC,\r
+       FFormat576p2500,\r
+       FFormat720p5000,\r
+       FFormat720p5994,\r
+       FFormat720p6000,\r
+       FFormat1080p2397,\r
+       FFormat1080p2400,\r
+       FFormat1080i5000,\r
+       FFormat1080i5994,\r
+       FFormat1080i6000,\r
+       FFormat1080p2500,\r
+       FFormat1080p2997,\r
+       FFormat1080p3000,\r
+       FrameFormatCount,\r
+       FFormatInvalid\r
+};\r
+\r
+struct FrameFormatDescription\r
+{\r
+       int width;\r
+       int height;\r
+       VideoUpdateMode mode;\r
+       double fps;\r
+       unsigned int size;\r
+       const TCHAR* name;\r
+\r
+       static const FrameFormatDescription FormatDescriptions[FrameFormatCount];\r
+};\r
+\r
+FrameFormat GetVideoFormat(const tstring& strVideoMode);\r
+\r
+class Frame;\r
+typedef std::tr1::shared_ptr<Frame> FramePtr;\r
+\r
+class FrameManager;\r
+typedef std::tr1::shared_ptr<FrameManager> FrameManagerPtr;\r
+\r
+///////////////\r
+// Frame\r
+typedef unsigned int* FrameMetadata;\r
+typedef std::vector<caspar::audio::AudioDataChunkPtr> AudioDataChunkList;\r
+\r
+class Frame : public utils::Identifiable, private utils::Noncopyable\r
+{\r
+protected:\r
+       Frame();\r
+       virtual void HasVideo(bool bHasVideo) const {\r
+               bHasVideo_ = bHasVideo;\r
+       }\r
+\r
+public:\r
+       virtual ~Frame();\r
+\r
+       virtual unsigned char* GetDataPtr() const = 0;\r
+       virtual bool HasValidDataPtr() const = 0;\r
+       virtual unsigned int GetDataSize() const = 0;\r
+       virtual FrameMetadata GetMetadata() const {\r
+               return 0;\r
+       }\r
+\r
+       virtual void AddAudioDataChunk(caspar::audio::AudioDataChunkPtr pChunk) {\r
+               audioData_.push_back(pChunk);\r
+       }\r
+       virtual AudioDataChunkList& GetAudioData() {\r
+               return audioData_;\r
+       }\r
+\r
+       virtual bool HasVideo() const {\r
+               return bHasVideo_;\r
+       }\r
+\r
+       virtual const utils::ID& FactoryID() const = 0;\r
+\r
+private:       \r
+       mutable bool bHasVideo_;\r
+       AudioDataChunkList audioData_;\r
+};\r
+\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/frame/FrameManager.h b/server/frame/FrameManager.h
new file mode 100644 (file)
index 0000000..9729309
--- /dev/null
@@ -0,0 +1,52 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _CASPAR_FRAMEMANAGER_H__\r
+#define _CASPAR_FRAMEMANAGER_H__\r
+\r
+#include "Frame.h"\r
+\r
+#include <vector>\r
+#include <string>\r
+\r
+#include "..\utils\ID.h"\r
+\r
+namespace caspar {\r
+\r
+class FrameManager : public utils::Identifiable\r
+{\r
+public:\r
+       virtual ~FrameManager() {}\r
+       virtual FramePtr CreateFrame() = 0;\r
+       virtual const FrameFormatDescription& GetFrameFormatDescription() const = 0;\r
+       virtual bool HasFeature(const std::string& feature) const\r
+       {\r
+               return false;\r
+       }\r
+       bool Owns(const Frame& frame) const\r
+       {\r
+               return (frame.FactoryID() == ID());\r
+       }\r
+};\r
+typedef std::tr1::shared_ptr<FrameManager> FrameManagerPtr;\r
+\r
+}      //namespace caspar\r
+\r
+#endif //_CASPAR_FRAMEMANAGER_H__
\ No newline at end of file
diff --git a/server/frame/FrameMediaController.h b/server/frame/FrameMediaController.h
new file mode 100644 (file)
index 0000000..7048e53
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _CASPAR_FRAMEMEDIACONTROLLER_H__\r
+#define _CASPAR_FRAMEMEDIACONTROLLER_H__\r
+\r
+#include "..\MediaController.h"\r
+#include "FrameManager.h"\r
+#include "..\audio\AudioManager.h"\r
+\r
+#include <vector>\r
+\r
+namespace caspar {\r
+\r
+class FrameBuffer;\r
+struct MediaProducerInfo;\r
+\r
+typedef std::vector<caspar::audio::SoundBufferWorkerPtr> SoundBufferWorkerList;\r
+\r
+class FrameMediaController : public IMediaController\r
+{\r
+       FrameMediaController(const FrameMediaController&);\r
+       FrameMediaController& operator=(const FrameMediaController&);\r
+\r
+public:\r
+       FrameMediaController() {}\r
+       virtual ~FrameMediaController() {}\r
+\r
+       virtual bool Initialize(FrameManagerPtr pFrameManager) = 0;\r
+\r
+       virtual FrameBuffer& GetFrameBuffer() = 0;\r
+       virtual bool GetProducerInfo(MediaProducerInfo*) {\r
+               return false;\r
+       }\r
+\r
+       SoundBufferWorkerList& GetSoundBufferWorkers() {\r
+               return soundBufferWorkers_;\r
+       }\r
+\r
+       void AddSoundBufferWorker(caspar::audio::SoundBufferWorkerPtr pSoundBufferWorker) {\r
+               soundBufferWorkers_.push_back(pSoundBufferWorker);\r
+       }\r
+\r
+private:\r
+       SoundBufferWorkerList soundBufferWorkers_;\r
+};\r
+\r
+}      //namespace caspar\r
+\r
+#endif //_CASPAR_FRAMEMEDIACONTROLLER_H__
\ No newline at end of file
diff --git a/server/frame/FramePlaybackControl.cpp b/server/frame/FramePlaybackControl.cpp
new file mode 100644 (file)
index 0000000..3bef012
--- /dev/null
@@ -0,0 +1,591 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\stdafx.h"\r
+#include "..\VideoConsumer.h"\r
+#include "FrameMediaController.h"\r
+#include "FramePlaybackStrategy.h"\r
+#include "FramePlaybackControl.h"\r
+#include "..\cg\flashcgproxy.h"\r
+#include "..\producers\composites\TransitionProducer.h"\r
+#include "..\Application.h"\r
+#include "..\MediaProducerInfo.h"\r
+#include "..\utils\image\image.hpp"\r
+\r
+#include "..\monitor.h"\r
+\r
+namespace caspar {\r
+\r
+using namespace caspar::utils;\r
+\r
+using std::tr1::cref;\r
+using std::tr1::bind;\r
+\r
+FramePlaybackControl::FramePlaybackControl(FramePlaybackStrategyPtr pStrategy) : pStrategy_(pStrategy), bPlaybackRunning_(false), isCGEmpty_(TRUE),\r
+eventLoad_(FALSE, FALSE), eventRender_(FALSE, FALSE), eventStartPlayback_(FALSE, FALSE), eventPausePlayback_(FALSE, FALSE), eventStopPlayback_(FALSE, FALSE), eventStoppedPlayback_(FALSE, FALSE), pMonitor_(0)\r
+{\r
+       if(pStrategy_ == 0)\r
+               throw std::exception("No valid FramePlaybackStrategy provided");\r
+\r
+       pSystemFrameManager_.reset(new SystemFrameManager(pStrategy_->GetFrameManager()->GetFrameFormatDescription()));\r
+       if(pSystemFrameManager_ == 0)\r
+               throw std::exception("Failed to create SystemFrameManager");\r
+}\r
+\r
+FramePlaybackControl::~FramePlaybackControl()\r
+{\r
+       Stop();\r
+}\r
+\r
+void FramePlaybackControl::Start()\r
+{\r
+       worker_.Start(this);\r
+}\r
+\r
+void FramePlaybackControl::Stop()\r
+{\r
+       worker_.Stop();\r
+       backgroundClip_.Clear();\r
+}\r
+\r
+\r
+////////////////////////////\r
+// IPlaybackControl methods\r
+bool FramePlaybackControl::Load(MediaProducerPtr pFP, bool loop)\r
+{\r
+       if(pFP == 0)\r
+               return false;\r
+\r
+       pFP->SetLoop(loop);\r
+\r
+       FrameMediaController* pMediaController = dynamic_cast<FrameMediaController*>(pFP->QueryController(TEXT("FrameController")));\r
+       if(pMediaController == 0)\r
+               return false;\r
+\r
+       if(!pMediaController->Initialize(pStrategy_->GetFrameManager()))\r
+               return false;\r
+\r
+       GetApplication()->GetAudioManager()->CueAudio(pMediaController);\r
+\r
+       eventStopPlayback_.Set();\r
+\r
+       {\r
+               Lock lock(*this);\r
+               backgroundClip_ = ClipInfo(pFP, pMediaController);\r
+               eventLoad_.Set();\r
+       }\r
+\r
+       return true;\r
+}\r
+\r
+bool FramePlaybackControl::LoadBackground(MediaProducerPtr pFP, const TransitionInfo& transitionInfo, bool loop)\r
+{\r
+       MediaProducerPtr pMediaProducer;\r
+       if(pFP == 0)\r
+               return false;\r
+\r
+       pFP->SetLoop(loop);\r
+\r
+       ITransitionController* pTransitionController = 0;\r
+       if(transitionInfo.type_ != Cut && transitionInfo.duration_ > 0) {\r
+               //prepare transition\r
+               TransitionProducerPtr pTransitionProducer(new TransitionProducer(pFP, transitionInfo, pStrategy_->GetFrameManager()->GetFrameFormatDescription()));\r
+               pTransitionController = pTransitionProducer.get();\r
+               pMediaProducer = pTransitionProducer;\r
+       }\r
+       else {\r
+               pMediaProducer = pFP;\r
+       }\r
+\r
+       FrameMediaController* pMediaController = dynamic_cast<FrameMediaController*>(pMediaProducer->QueryController(TEXT("FrameController")));\r
+       if(pMediaController == 0)\r
+               return false;\r
+\r
+       if(!pMediaController->Initialize(pStrategy_->GetFrameManager()))\r
+               return false;\r
+\r
+       GetApplication()->GetAudioManager()->CueAudio(pMediaController);\r
+\r
+       {\r
+               Lock lock(*this);\r
+               backgroundClip_ = ClipInfo(pMediaProducer, pMediaController, pTransitionController);\r
+       }\r
+\r
+       return true;\r
+}\r
+\r
+bool FramePlaybackControl::Play()\r
+{\r
+       if(!backgroundClip_.IsEmpty()) {\r
+               eventStartPlayback_.Set();\r
+       }\r
+       else {\r
+               if(!bPlaybackRunning_) {\r
+                       LOG << LogLevel::Verbose << TEXT("Playing active clip");\r
+                       eventStartPlayback_.Set();\r
+               }\r
+               else {\r
+                       LOG << LogLevel::Verbose << TEXT("Failed to play. Already playing");\r
+                       return false;\r
+               }\r
+       }\r
+\r
+       return true;\r
+}\r
+\r
+//bool FramePlaybackControl::Pause()\r
+//{\r
+//     eventPausePlayback_.Set();\r
+//     return true;\r
+//}\r
+\r
+bool FramePlaybackControl::StopPlayback(bool block)\r
+{\r
+       eventStopPlayback_.Set();\r
+\r
+       if(block)\r
+       {\r
+               if(::WaitForSingleObject(this->eventStoppedPlayback_, 1000) != WAIT_OBJECT_0)\r
+                       return false;\r
+       }\r
+\r
+       if(pMonitor_)\r
+               pMonitor_->Inform(STOPPED);\r
+\r
+       return true;\r
+}\r
+\r
+bool FramePlaybackControl::IsRunning()\r
+{\r
+       return bPlaybackRunning_;\r
+}\r
+\r
+bool FramePlaybackControl::Param(const tstring& param)\r
+{\r
+       return false;\r
+}\r
+\r
+\r
+////////////////////////////\r
+// ICGControl methods\r
+void FramePlaybackControl::Add(int layer, const tstring& templateName, bool playOnLoad, const tstring& label, const tstring& data) {\r
+       if(isCGEmpty_ != FALSE) {\r
+               CG::FlashCGProxyPtr pNewCGProducer = CG::FlashCGProxy::Create(pMonitor_);\r
+               if(pNewCGProducer) {\r
+                       if(pNewCGProducer->Initialize(pSystemFrameManager_)) {\r
+                               taskQueue_.push_back(bind(&FramePlaybackControl::DoResetCGProducer, this, pNewCGProducer));\r
+                       }\r
+                       else {\r
+                               LOG << "Frameplayback: Failed to initialize new CGProducer";\r
+                               return;\r
+                       }\r
+               }\r
+       }\r
+\r
+       //TODO: don't use bind to generate functor with string-arguments. Does it even work with const-reference parameters?\r
+       taskQueue_.push_back(bind(&FramePlaybackControl::DoAdd, this, layer, tstring(templateName), playOnLoad, tstring(label), tstring(data)));\r
+}\r
+void FramePlaybackControl::Remove(int layer) {\r
+       taskQueue_.push_back(bind(&FramePlaybackControl::DoRemove, this, layer));\r
+}\r
+void FramePlaybackControl::Clear() {\r
+       taskQueue_.push_back(bind(&FramePlaybackControl::DoClear, this));\r
+}\r
+void FramePlaybackControl::LoadEmpty() {\r
+       taskQueue_.push_back(bind(&FramePlaybackControl::DoLoadEmpty, this));\r
+}\r
+void FramePlaybackControl::Play(int layer) {\r
+       taskQueue_.push_back(bind(&FramePlaybackControl::DoPlay, this, layer));\r
+}\r
+void FramePlaybackControl::Stop(int layer, unsigned int mixOutDuration) {\r
+       taskQueue_.push_back(bind(&FramePlaybackControl::DoStop, this, layer, mixOutDuration));\r
+}\r
+void FramePlaybackControl::Next(int layer) {\r
+       taskQueue_.push_back(bind(&FramePlaybackControl::DoNext, this, layer));\r
+}\r
+void FramePlaybackControl::Update(int layer, const tstring& data) {\r
+       //NOTE: don't use bind to generate functor with string-arguments. Does it even work with const-reference parameters?\r
+       taskQueue_.push_back(bind(&FramePlaybackControl::DoUpdate, this, layer, tstring(data)));\r
+}\r
+void FramePlaybackControl::Invoke(int layer, const tstring& label) {\r
+       //NOTE: don't use bind to generate functor with string-arguments. Does it even work with const-reference parameters?\r
+       taskQueue_.push_back(bind(&FramePlaybackControl::DoInvoke, this, layer, tstring(label)));\r
+}\r
+\r
+////////////////////////////\r
+// IRunnable methods\r
+void FramePlaybackControl::Run(HANDLE stopEvent)\r
+{\r
+       const int WaitHandleCount = 8;\r
+\r
+       HANDLE waitHandles[WaitHandleCount] = { stopEvent, eventStopPlayback_, eventStartPlayback_, eventPausePlayback_, eventLoad_, taskQueue_.GetWaitEvent(), eventRender_, 0 };\r
+\r
+       bool bQuit = false, bSingleFrame = false, bPureCG = false;\r
+    while(!bQuit)\r
+    {\r
+               if((bPlaybackRunning_ || bSingleFrame) && !activeClip_.IsEmpty()) {\r
+                       waitHandles[WaitHandleCount - 1] = activeClip_.pFrameController_->GetFrameBuffer().GetWaitHandle();\r
+                       bPureCG = false;\r
+               }\r
+               else if(pCGProducer_) {\r
+                       waitHandles[WaitHandleCount - 1] = pCGProducer_->GetFrameBuffer().GetWaitHandle();\r
+                       bPureCG = true;\r
+               }\r
+               else\r
+                       waitHandles[WaitHandleCount - 1] = 0;\r
+               \r
+               int realWaitHandleCount = (WaitHandleCount-1);\r
+               if(waitHandles[WaitHandleCount - 1] != 0)\r
+                       ++realWaitHandleCount;\r
+\r
+               DWORD waitResult = WaitForMultipleObjects(realWaitHandleCount, waitHandles, FALSE, 2500);\r
+               switch(waitResult) {\r
+                       case WAIT_OBJECT_0:             //stopEvent\r
+                               bQuit = true;\r
+                               break;\r
+\r
+                       case WAIT_OBJECT_0 + 1: //stopPlayback\r
+                               DoStopPlayback(waitHandles[WaitHandleCount - 1]);\r
+                               break;\r
+\r
+                       case WAIT_OBJECT_0 + 2: //startPlayback\r
+                               if(DoStartPlayback(waitHandles[WaitHandleCount - 1]))\r
+                                       bSingleFrame = true;\r
+                               break;\r
+\r
+                       case WAIT_OBJECT_0 + 3: //pausePlayback\r
+                               //DoPausePlayback();\r
+                               break;\r
+\r
+                       case WAIT_OBJECT_0 + 4: //load\r
+                               if(DoLoad(waitHandles[WaitHandleCount - 1]))\r
+                                       bSingleFrame = true;\r
+                               break;\r
+\r
+                       case WAIT_OBJECT_0 + 5: //cgtask waitEvent\r
+                               {\r
+                                       Task task;\r
+                                       taskQueue_.pop_front(task);\r
+                                       if(task)\r
+                                               task();\r
+                               }\r
+                               break;\r
+\r
+                       case WAIT_OBJECT_0 + 6: //render\r
+                               DoRender(waitHandles[WaitHandleCount - 1], false);\r
+                               break;\r
+\r
+                       case WAIT_OBJECT_0 + 7: //frame availible\r
+                               if(!bPureCG) {\r
+                                       if(DoGetFrame(waitHandles[WaitHandleCount - 1], bSingleFrame))\r
+                                               DoRender(waitHandles[WaitHandleCount - 1], false);\r
+                                       bSingleFrame = false;\r
+                               }\r
+                               else {\r
+                                       DoRender(waitHandles[WaitHandleCount - 1], true);\r
+                               }\r
+                               break;\r
+\r
+                       case WAIT_TIMEOUT:\r
+                               break;\r
+\r
+                       case WAIT_FAILED:\r
+                               bQuit = true;\r
+                               LOG << LogLevel::Critical << TEXT("Wait failed in FramePlayback. Aborting");\r
+                               break;\r
+               }\r
+       }\r
+\r
+       activeClip_.Clear();\r
+}\r
+\r
+bool FramePlaybackControl::DoStartPlayback(HANDLE& handle) \r
+{\r
+       bool bForceUpdate = false;\r
+\r
+       {\r
+               Lock lock(*this);\r
+\r
+               bPlaybackRunning_ = true;\r
+               if(!backgroundClip_.IsEmpty())\r
+               {\r
+                       if(backgroundClip_.pTransitionController_ != 0) {\r
+                               if(!backgroundClip_.pTransitionController_->Start(activeClip_)) {\r
+                                       backgroundClip_.lastFetchResult_ = FetchEOF;\r
+                                       bForceUpdate = true;\r
+                               }\r
+                       }\r
+                       activeClip_ = backgroundClip_;\r
+                       backgroundClip_.Clear();\r
+               }\r
+       }\r
+\r
+       if(pMonitor_)\r
+               pMonitor_->Inform(PLAY);\r
+\r
+       return bForceUpdate;\r
+}\r
+\r
+void FramePlaybackControl::DoStopPlayback(HANDLE& handle) \r
+{\r
+       activeClip_.lastFetchResult_ = FetchEOF;\r
+       if(!activeClip_.IsEmpty())\r
+               GetApplication()->GetAudioManager()->StopAudio(activeClip_.pFrameController_);\r
+\r
+       while(!frameQueue_.empty())\r
+               frameQueue_.pop();\r
+\r
+       bPlaybackRunning_ = false;\r
+       this->eventStoppedPlayback_.Set();\r
+}\r
+\r
+bool FramePlaybackControl::DoLoad(HANDLE& handle)\r
+{\r
+       Lock lock(*this);\r
+\r
+       if(!backgroundClip_.IsEmpty())\r
+       {\r
+               activeClip_ = backgroundClip_;\r
+               backgroundClip_.Clear();\r
+               return true;\r
+       }\r
+\r
+       return false;\r
+}\r
+\r
+void FramePlaybackControl::DoLoadEmpty()\r
+{\r
+       this->emptyProducer_ = GetApplication()->GetColorMediaManager()->CreateProducer(TEXT("#00000000"));\r
+       this->Load(this->emptyProducer_, false);\r
+}\r
+\r
+void FramePlaybackControl::OnCGEmpty() {\r
+       InterlockedExchange(&isCGEmpty_, TRUE);\r
+       LOG << LogLevel::Debug << TEXT("Frameplayback: Flagged CGProducer as empty");\r
+}\r
+\r
+void FramePlaybackControl::DoResetCGProducer(CG::FlashCGProxyPtr pNewCGProducer) {\r
+       if(isCGEmpty_ != FALSE) {\r
+               LOG << LogLevel::Debug << TEXT("Frameplayback: Using new CGProducer");\r
+               pCGProducer_ = pNewCGProducer;\r
+               if(pCGProducer_) {\r
+                       InterlockedExchange(&isCGEmpty_, FALSE);\r
+                       pCGProducer_->SetEmptyAlert(bind(&FramePlaybackControl::OnCGEmpty, this));\r
+               }\r
+       }\r
+}\r
+\r
+void FramePlaybackControl::DoAdd(int layer, tstring templateName, bool playOnLoad, tstring label, tstring data) {\r
+       if(pCGProducer_)        \r
+               pCGProducer_->Add(layer, templateName, playOnLoad, label, data);\r
+}\r
+\r
+void FramePlaybackControl::DoRemove(int layer) {\r
+       if(pCGProducer_)\r
+               pCGProducer_->Remove(layer);\r
+}\r
+\r
+\r
+void FramePlaybackControl::DoClear() {\r
+       if(pCGProducer_)\r
+               pCGProducer_->Stop();\r
+       else {\r
+               OnCGEmpty();\r
+       }\r
+}\r
+\r
+void FramePlaybackControl::DoPlay(int layer) {\r
+       if(pCGProducer_)\r
+               pCGProducer_->Play(layer);\r
+}\r
+\r
+void FramePlaybackControl::DoStop(int layer, unsigned int mixOutDuration) {\r
+       if(pCGProducer_)\r
+               pCGProducer_->Stop(layer, mixOutDuration);\r
+}\r
+\r
+void FramePlaybackControl::DoNext(int layer) {\r
+       if(pCGProducer_)\r
+               pCGProducer_->Next(layer);\r
+}\r
+\r
+void FramePlaybackControl::DoUpdate(int layer, tstring data) {\r
+       if(pCGProducer_)\r
+               pCGProducer_->Update(layer, data);\r
+}\r
+\r
+void FramePlaybackControl::DoInvoke(int layer, tstring label) {\r
+       if(pCGProducer_)\r
+               pCGProducer_->Invoke(layer, label);\r
+}\r
+\r
+bool FramePlaybackControl::DoGetFrame(HANDLE& handle, bool bSingleFrame)\r
+{\r
+       bool bDoRender = false;\r
+       if(!activeClip_.IsEmpty()) \r
+       {\r
+               bool bEOF = false;\r
+               FramePtr pFrame = activeClip_.pFrameController_->GetFrameBuffer().front();\r
+\r
+               if(pFrame != 0)\r
+               {\r
+                       activeClip_.pLastFrame_ = pFrame;\r
+\r
+                       frameQueue_.push(pFrame);\r
+                       if(frameQueue_.size() >= 3)\r
+                               bDoRender = true;\r
+\r
+                       //Queue audio in the audioplayback-worker\r
+                       if(!bSingleFrame) {\r
+                               GetApplication()->GetAudioManager()->PushAudioData(activeClip_.pFrameController_, pFrame);\r
+\r
+                               //check for end of file\r
+                               activeClip_.lastFetchResult_ = activeClip_.pFrameController_->GetFrameBuffer().pop_front();\r
+                               if(activeClip_.lastFetchResult_ == FetchEOF) {\r
+                                       bEOF = true;\r
+                               }\r
+                       }\r
+                       else\r
+                               bDoRender = true;\r
+               }\r
+               else {\r
+                       activeClip_.lastFetchResult_ = FetchEOF;\r
+                       bEOF = true;\r
+               }\r
+\r
+               if(bEOF) {\r
+                       //this producer is finnished, check if we should continue with another\r
+                       bPlaybackRunning_ = false;\r
+                       activeClip_.bStopped_ = true;\r
+\r
+                       MediaProducerPtr pFollowingProducer(activeClip_.pFP_->GetFollowingProducer());\r
+                       if(pFollowingProducer != 0) {\r
+                               FrameMediaController* pMediaController = dynamic_cast<FrameMediaController*>(pFollowingProducer->QueryController(TEXT("FrameController")));\r
+                               if(pMediaController != 0)\r
+                               {\r
+                                       //reinitialize following producer with the correct framemanager\r
+                                       if(pMediaController->Initialize(pStrategy_->GetFrameManager()))\r
+                                       {\r
+                                               //make following producer current\r
+                                               activeClip_ = ClipInfo(pFollowingProducer, pMediaController);\r
+                                               activeClip_.pLastFrame_ = pFrame;\r
+                                               handle = activeClip_.pFrameController_->GetFrameBuffer().GetWaitHandle();\r
+                                               bPlaybackRunning_ = true;\r
+                                               return bDoRender;\r
+                                       }\r
+                               }\r
+                       }\r
+               \r
+                       if(pMonitor_)\r
+                               pMonitor_->Inform(STOPPED);\r
+\r
+                       bDoRender = true;\r
+               }\r
+       }\r
+\r
+       return bDoRender;\r
+}\r
+\r
+void FramePlaybackControl::DoRender(HANDLE& handle, bool bPureCG) \r
+{\r
+       //Get next CG-frame if we have a CGProducer\r
+       FramePtr pCGFrame;\r
+       if(pCGProducer_) {\r
+               pCGFrame = pCGProducer_->GetFrameBuffer().front();\r
+               FrameBufferFetchResult fetchResult = pCGProducer_->GetFrameBuffer().pop_front();\r
+               if(pCGFrame != 0) {\r
+                       pLastCGFrame_ = pCGFrame;\r
+               }\r
+               else if(fetchResult != FetchEOF) {\r
+                       pCGFrame = pLastCGFrame_;\r
+               }\r
+               else {\r
+                       pCGProducer_.reset();\r
+                       LOG << LogLevel::Debug << TEXT("Frameplayback: Cleared CGProducer");\r
+                       OnCGEmpty();\r
+                       pLastCGFrame_.reset();\r
+               }\r
+       }\r
+\r
+       //Get next video frame unless we're in PureCG-mode\r
+       FramePtr pVideoFrame;\r
+       if(!bPureCG || activeClip_.bStopped_) {\r
+               if(frameQueue_.size() > 0) {\r
+                       pVideoFrame = frameQueue_.front();\r
+                       frameQueue_.pop();\r
+\r
+                       if(pVideoFrame != 0) {\r
+                               pLastVideoFrame_ = pVideoFrame;\r
+                       }\r
+               }\r
+               else {\r
+                       pVideoFrame = pLastVideoFrame_;\r
+               }\r
+\r
+               if(activeClip_.bStopped_ && !frameQueue_.empty())\r
+                       eventRender_.Set();\r
+       }\r
+       else {\r
+               pVideoFrame = pLastVideoFrame_;\r
+       }\r
+\r
+       //combine and send to consumer\r
+       FramePtr pResultFrame;\r
+       if(pCGFrame) {\r
+               if(pVideoFrame && this->activeClip_.pFP_ != this->emptyProducer_) {\r
+                       pResultFrame = pStrategy_->GetReservedFrame();\r
+                       if(pResultFrame) {\r
+                               utils::image::PreOver(pResultFrame->GetDataPtr(), pVideoFrame->GetDataPtr(), pCGFrame->GetDataPtr(), pResultFrame->GetDataSize());\r
+                       }\r
+               }\r
+               else\r
+                       pResultFrame = pCGFrame;\r
+       }\r
+       else\r
+               pResultFrame = pVideoFrame;\r
+\r
+       if(pResultFrame)\r
+               pStrategy_->DisplayFrame(pResultFrame.get());\r
+       else if(bPureCG) {\r
+               pResultFrame = pStrategy_->GetReservedFrame();\r
+               if(pResultFrame) {\r
+                       utils::image::Clear(pResultFrame->GetDataPtr(), pResultFrame->GetDataSize());\r
+                       pStrategy_->DisplayFrame(pResultFrame.get());\r
+               }\r
+       }\r
+}\r
+\r
+bool FramePlaybackControl::OnUnhandledException(const std::exception& ex) throw()\r
+{\r
+       bool bDoRestart = true;\r
+\r
+       try \r
+       {\r
+               LOG << LogLevel::Critical << TEXT("UNHANDLED EXCEPTION in frameplayback thread. Message: ") << ex.what();\r
+       }\r
+       catch(...)\r
+       {\r
+               bDoRestart = false;\r
+       }\r
+\r
+       return bDoRestart;\r
+}\r
+\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/frame/FramePlaybackControl.h b/server/frame/FramePlaybackControl.h
new file mode 100644 (file)
index 0000000..6f50c61
--- /dev/null
@@ -0,0 +1,138 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _CASPAR_FRAMEPLAYBACKCONTROL_H__\r
+#define _CASPAR_FRAMEPLAYBACKCONTROL_H__\r
+\r
+#pragma once\r
+\r
+#include <memory>\r
+#include <queue>\r
+#include "..\PlaybackControl.h"\r
+#include "..\cg\cgcontrol.h"\r
+#include "FramePlaybackStrategy.h"\r
+#include "..\utils\thread.h"\r
+#include "..\utils\lockable.h"\r
+#include "..\utils\taskqueue.h"\r
+#include "ClipInfo.h"\r
+#include "systemframemanager.h"\r
+\r
+namespace caspar {\r
+\r
+namespace CG\r
+{ \r
+class FlashCGProxy;\r
+typedef std::tr1::shared_ptr<FlashCGProxy> FlashCGProxyPtr;\r
+}\r
+\r
+class FramePlaybackControl : public IPlaybackControl, public CG::ICGControl, public utils::IRunnable, private utils::LockableObject\r
+{\r
+public:\r
+       explicit FramePlaybackControl(FramePlaybackStrategyPtr);\r
+       virtual ~FramePlaybackControl();\r
+\r
+       void Start();\r
+       void Stop();\r
+\r
+       //IPlaybackControl\r
+       virtual bool Load(MediaProducerPtr pFP, bool loop);\r
+       virtual bool LoadBackground(MediaProducerPtr pFP, const TransitionInfo& transitionInfo, bool loop);\r
+       virtual bool Play();\r
+       virtual void LoadEmpty();\r
+       //virtual bool Pause();\r
+       virtual bool StopPlayback(bool block = false);\r
+       virtual bool IsRunning();\r
+       virtual bool Param(const tstring& param);\r
+       virtual CG::ICGControl* GetCGControl() {\r
+               return this;\r
+       }\r
+       virtual void SetMonitor(Monitor* pMonitor) {\r
+               pMonitor_ = pMonitor;\r
+       }\r
+\r
+       //ICGControl\r
+       virtual void Add(int layer, const tstring& templateName, bool playOnLoad, const tstring& label, const tstring& data);\r
+       virtual void Remove(int layer);\r
+       virtual void Clear();\r
+       virtual void Play(int layer);\r
+       virtual void Stop(int layer, unsigned int mixOutDuration);\r
+       virtual void Next(int layer);\r
+       virtual void Update(int layer, const tstring& data);\r
+       virtual void Invoke(int layer, const tstring& label);\r
+\r
+       void DoResetCGProducer(CG::FlashCGProxyPtr pNewCGProducer);\r
+       void OnCGEmpty();\r
+\r
+       //IRunnable\r
+       virtual void Run(HANDLE stopEvent);\r
+       virtual bool OnUnhandledException(const std::exception& ex) throw();\r
+\r
+private:\r
+       FramePlaybackStrategyPtr pStrategy_;\r
+       SystemFrameManagerPtr pSystemFrameManager_;\r
+\r
+       volatile bool bPlaybackRunning_;\r
+       volatile LONG isCGEmpty_;\r
+\r
+       utils::Thread worker_;\r
+       ClipInfo activeClip_;\r
+       ClipInfo backgroundClip_;\r
+       CG::FlashCGProxyPtr pCGProducer_;\r
+       Monitor* pMonitor_;\r
+\r
+       utils::Event eventLoad_;\r
+       utils::Event eventRender_;\r
+       utils::Event eventStartPlayback_;\r
+       utils::Event eventPausePlayback_;\r
+       utils::Event eventStopPlayback_;\r
+       utils::Event eventStoppedPlayback_;\r
+\r
+       std::queue<FramePtr> frameQueue_;\r
+\r
+       FramePtr pLastCGFrame_;\r
+       FramePtr pLastVideoFrame_;\r
+\r
+       bool DoLoad(HANDLE& handle);\r
+       bool DoStartPlayback(HANDLE& handle);\r
+       void DoStopPlayback(HANDLE& handle);\r
+       void DoRender(HANDLE& handle, bool bPureCG);\r
+       bool DoGetFrame(HANDLE& handle, bool bForceVideoOutput);\r
+\r
+       //cg-tasks\r
+       utils::TaskQueue taskQueue_;\r
+\r
+       MediaProducerPtr emptyProducer_;\r
+\r
+       void DoLoadEmpty();\r
+       void DoAdd(int layer, tstring templateName, bool playOnLoad, tstring label, tstring data);\r
+       void DoRemove(int layer);\r
+       void DoClear();\r
+       void DoPlay(int layer);\r
+       void DoStop(int layer, unsigned int mixOutDuration);\r
+       void DoNext(int layer);\r
+       void DoUpdate(int layer, tstring data);\r
+       void DoInvoke(int layer, tstring label);\r
+};\r
+\r
+typedef std::tr1::shared_ptr<FramePlaybackControl> FramePlaybackControlPtr;\r
+\r
+}      //namespace caspar\r
+\r
+#endif //_CASPAR_FRAMEPLAYBACKCONTROL_H__
\ No newline at end of file
diff --git a/server/frame/FramePlaybackStrategy.h b/server/frame/FramePlaybackStrategy.h
new file mode 100644 (file)
index 0000000..7ca5ee0
--- /dev/null
@@ -0,0 +1,47 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _CASPAR_FRAMEPLAYBACKSTRATEGY_H__\r
+#define _CASPAR_FRAMEPLAYBACKSTRATEGY_H__\r
+\r
+#pragma once\r
+\r
+#include "FrameManager.h"\r
+#include "..\utils\Noncopyable.hpp"\r
+\r
+namespace caspar {\r
+\r
+class Frame;\r
+class IVideoConsumer;\r
+\r
+class IFramePlaybackStrategy : utils::Noncopyable\r
+{\r
+public:\r
+       virtual ~IFramePlaybackStrategy() {}\r
+\r
+       virtual FrameManagerPtr GetFrameManager() = 0;\r
+       virtual void DisplayFrame(Frame*) = 0;\r
+       virtual FramePtr GetReservedFrame() = 0;\r
+};\r
+typedef std::tr1::shared_ptr<IFramePlaybackStrategy> FramePlaybackStrategyPtr;\r
+\r
+}      //namespace caspar\r
+\r
+#endif //_CASPAR_FRAMEPLAYBACKSTRATEGY_H__
\ No newline at end of file
diff --git a/server/frame/SystemFrame.cpp b/server/frame/SystemFrame.cpp
new file mode 100644 (file)
index 0000000..1d8a664
--- /dev/null
@@ -0,0 +1,52 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\stdafx.h"\r
+#include "SystemFrame.h"\r
+\r
+namespace caspar {\r
+\r
+       SystemFrame::SystemFrame(unsigned char* pData, unsigned int dataSize, const utils::ID& factoryID) : pData_(pData), dataSize_(dataSize), factoryID_(factoryID)\r
+       {}\r
+\r
+       SystemFrame::~SystemFrame()\r
+       {}\r
+\r
+       unsigned char* SystemFrame::GetDataPtr() const \r
+       {\r
+               if(pData_ != 0)\r
+                       HasVideo(true);\r
+               return pData_;\r
+       }\r
+       bool SystemFrame::HasValidDataPtr() const\r
+       {\r
+               return (pData_ != 0);\r
+       }\r
+       unsigned int SystemFrame::GetDataSize() const\r
+       {\r
+               return dataSize_;\r
+       }\r
+\r
+       const utils::ID& SystemFrame::FactoryID() const\r
+       {\r
+               return factoryID_;\r
+       }\r
+}\r
+\r
diff --git a/server/frame/SystemFrame.h b/server/frame/SystemFrame.h
new file mode 100644 (file)
index 0000000..923cc13
--- /dev/null
@@ -0,0 +1,49 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _SYSTEMFRAME_H_\r
+#define _SYSTEMFRAME_H_\r
+\r
+#include "Frame.h"\r
+\r
+namespace caspar {\r
+\r
+class SystemFrame : public Frame\r
+{\r
+public:\r
+\r
+       SystemFrame(unsigned char* pData, unsigned int dataSize, const utils::ID& factoryID);\r
+       virtual ~SystemFrame();\r
+\r
+       virtual unsigned char* GetDataPtr() const;\r
+       virtual bool HasValidDataPtr() const;\r
+       virtual unsigned int GetDataSize() const;\r
+\r
+       const utils::ID& FactoryID() const;\r
+\r
+private:\r
+       unsigned char* pData_;\r
+       unsigned int dataSize_;\r
+       utils::ID factoryID_;\r
+};\r
+\r
+}\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/frame/SystemFrameManager.cpp b/server/frame/SystemFrameManager.cpp
new file mode 100644 (file)
index 0000000..85e190a
--- /dev/null
@@ -0,0 +1,68 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\stdafx.h"\r
+#include "SystemFrameManager.h"\r
+\r
+#include "Frame.h"\r
+#include "SystemFrame.h"\r
+\r
+namespace caspar {\r
+\r
+SystemFrameManager::LockableAllocatorAssoc SystemFrameManager::allocators;\r
+\r
+class SystemFrameManager::FrameDeallocator\r
+{\r
+public:\r
+       FrameDeallocator(const utils::FixedAllocatorPtr& pAllocator) : pAllocator_(pAllocator){}\r
+       void operator()(Frame* frame)\r
+       { \r
+               pAllocator_->Deallocate(frame->GetDataPtr()); \r
+               delete frame;\r
+       }\r
+private:\r
+       const utils::FixedAllocatorPtr pAllocator_;\r
+};\r
+\r
+SystemFrameManager::SystemFrameManager(const FrameFormatDescription& fmtDesc) : fmtDesc_(fmtDesc)\r
+{\r
+       utils::LockableObject::Lock lock(allocators);\r
+       utils::FixedAllocatorPtr& pAllocator = allocators[fmtDesc_.size];\r
+       if(!pAllocator)\r
+               pAllocator.reset(new utils::FixedAllocator<>(fmtDesc_.size));\r
+       pAllocator_ = pAllocator;       \r
+}\r
+\r
+SystemFrameManager::~SystemFrameManager()\r
+{}\r
+\r
+FramePtr SystemFrameManager::CreateFrame()\r
+{\r
+       return FramePtr(new SystemFrame(static_cast<unsigned char*>(pAllocator_->Allocate()), fmtDesc_.size, this->ID()), FrameDeallocator(pAllocator_));\r
+}\r
+\r
+const FrameFormatDescription& SystemFrameManager::GetFrameFormatDescription() const \r
+{\r
+       return fmtDesc_;\r
+}\r
+\r
+\r
+\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/frame/SystemFrameManager.h b/server/frame/SystemFrameManager.h
new file mode 100644 (file)
index 0000000..4bd4f78
--- /dev/null
@@ -0,0 +1,66 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _CASPAR_SYSTEMFRAMEMANAGER_H__\r
+#define _CASPAR_SYSTEMFRAMEMANAGER_H__\r
+\r
+#pragma once\r
+\r
+#include "..\utils\Allocator.h"\r
+#include "..\utils\Noncopyable.hpp"\r
+\r
+#include "FrameManager.h"\r
+\r
+#include <unordered_map>\r
+\r
+namespace caspar {\r
+\r
+class Frame;\r
+typedef std::tr1::shared_ptr<Frame> FramePtr;\r
+\r
+/*\r
+       SystemFrameManager\r
+\r
+       Changes:\r
+       2009-06-14 (R.N) : Refactored, note: Is thread-safe since "FixedAllocator" is thread-safe\r
+*/\r
+\r
+class SystemFrameManager : public FrameManager, private utils::Noncopyable, private utils::LockableObject\r
+{\r
+public:\r
+       explicit SystemFrameManager(const FrameFormatDescription&);\r
+       virtual ~SystemFrameManager();\r
+\r
+       virtual FramePtr CreateFrame();\r
+       virtual const FrameFormatDescription& GetFrameFormatDescription() const;\r
+\r
+private:\r
+       class FrameDeallocator;\r
+       const FrameFormatDescription fmtDesc_;\r
+       utils::FixedAllocatorPtr pAllocator_;\r
+\r
+       class LockableAllocatorAssoc : public std::tr1::unordered_map<size_t, utils::FixedAllocatorPtr>, public utils::LockableObject{};\r
+\r
+       static LockableAllocatorAssoc allocators;\r
+};\r
+typedef std::tr1::shared_ptr<SystemFrameManager> SystemFrameManagerPtr;\r
+\r
+}      //namespace caspar\r
+#endif //_CASPAR_SYSTEMFRAMEMANAGER_H__
\ No newline at end of file
diff --git a/server/frame/buffers/FrameBuffer.h b/server/frame/buffers/FrameBuffer.h
new file mode 100644 (file)
index 0000000..858f856
--- /dev/null
@@ -0,0 +1,54 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _FRAME_BUFFER_H_\r
+#define _FRAME_BUFFER_H_\r
+\r
+#include "../Frame.h"\r
+\r
+namespace caspar\r
+{\r
+\r
+enum FrameBufferFetchResult \r
+{\r
+       FetchDataAvailible,\r
+       FetchWait,\r
+       FetchEOF\r
+};\r
+\r
+class FrameBuffer\r
+{\r
+public:\r
+       virtual ~FrameBuffer() \r
+       {}\r
+\r
+       virtual FramePtr front() const = 0;\r
+       virtual FrameBufferFetchResult pop_front() = 0;\r
+\r
+       virtual void push_back(FramePtr) = 0;\r
+\r
+       virtual void clear() = 0;\r
+\r
+       virtual HANDLE GetWaitHandle() const = 0;\r
+};\r
+\r
+}\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/frame/buffers/MotionFrameBuffer.cpp b/server/frame/buffers/MotionFrameBuffer.cpp
new file mode 100644 (file)
index 0000000..3bb04fc
--- /dev/null
@@ -0,0 +1,167 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "../../StdAfx.h"\r
+\r
+#include "MotionFrameBuffer.h"\r
+\r
+namespace caspar\r
+{\r
+\r
+struct MotionFrameBuffer::Implementation : private utils::LockableObject\r
+{\r
+       Implementation() : event_(TRUE, FALSE), writeWaitEvent_(TRUE, TRUE), maxLength_(3)\r
+       {}\r
+\r
+       Implementation(unsigned int maxQueueLength) : event_(TRUE, FALSE), writeWaitEvent_(TRUE, TRUE), maxLength_(maxQueueLength)\r
+       {}\r
+\r
+       ~Implementation() \r
+       {}\r
+\r
+       FramePtr front() const \r
+       {\r
+               Lock lock(*this);\r
+\r
+               FramePtr result;\r
+               if(frameQueue_.size() != 0)\r
+                       result = frameQueue_.front();\r
+               return result;\r
+       }\r
+\r
+       FrameBufferFetchResult pop_front() \r
+       {\r
+               Lock lock(*this);\r
+\r
+               if(frameQueue_.size() == 0)\r
+               {\r
+                       event_.Reset();\r
+                       return FetchWait;\r
+               }\r
+\r
+               if(frameQueue_.front() != 0)\r
+               {\r
+                       frameQueue_.pop_front();\r
+                       \r
+                       if(frameQueue_.size() < maxLength_)\r
+                               writeWaitEvent_.Set();\r
+\r
+                       if(frameQueue_.size() == 0)\r
+                       {\r
+                               event_.Reset();\r
+                               return FetchWait;\r
+                       }\r
+\r
+                       if(frameQueue_.front() == 0)\r
+                               return FetchEOF;\r
+\r
+                       return FetchDataAvailible;\r
+               }\r
+               return FetchEOF;\r
+       }\r
+\r
+       void push_back(FramePtr pFrame) \r
+       {\r
+               Lock lock(*this);\r
+\r
+               //assert(frameQueue_.size() <= maxLength_);\r
+\r
+               frameQueue_.push_back(pFrame);\r
+               event_.Set();\r
+\r
+               if(frameQueue_.size() >= maxLength_)\r
+                       writeWaitEvent_.Reset();\r
+       }\r
+\r
+       void clear() \r
+       {\r
+               Lock lock(*this);\r
+\r
+               frameQueue_.clear();\r
+               writeWaitEvent_.Set();\r
+               event_.Reset();\r
+       }\r
+\r
+       HANDLE GetWaitHandle() const \r
+       {\r
+               return event_;\r
+       }\r
+\r
+       HANDLE GetWriteWaitHandle() \r
+       {\r
+               return writeWaitEvent_;\r
+       }\r
+\r
+       void SetCapacity(size_t capacity)\r
+       {\r
+               Lock lock(*this);\r
+               maxLength_ = capacity;\r
+               if(frameQueue_.size() < maxLength_)\r
+                       writeWaitEvent_.Set();\r
+       }\r
+\r
+       unsigned int maxLength_;\r
+       utils::Event event_;\r
+       std::list<FramePtr> frameQueue_;\r
+       utils::Event writeWaitEvent_; \r
+};\r
+       \r
+MotionFrameBuffer::MotionFrameBuffer() : pImpl_(new Implementation())\r
+{}\r
+\r
+MotionFrameBuffer::MotionFrameBuffer(unsigned int maxQueueLength) : pImpl_(new Implementation(maxQueueLength))\r
+{}\r
+\r
+FramePtr MotionFrameBuffer::front() const \r
+{\r
+       return pImpl_->front();\r
+}\r
+\r
+FrameBufferFetchResult MotionFrameBuffer::pop_front() \r
+{      \r
+       return pImpl_->pop_front();\r
+}\r
+\r
+void MotionFrameBuffer::push_back(FramePtr pFrame) \r
+{      \r
+       pImpl_->push_back(pFrame);\r
+}\r
+\r
+void MotionFrameBuffer::clear() \r
+{\r
+       pImpl_->clear();\r
+}\r
+\r
+HANDLE MotionFrameBuffer::GetWaitHandle() const \r
+{\r
+       return pImpl_->GetWaitHandle();\r
+}\r
+\r
+HANDLE MotionFrameBuffer::GetWriteWaitHandle() \r
+{\r
+       return pImpl_->GetWriteWaitHandle();\r
+}\r
+\r
+void MotionFrameBuffer::SetCapacity(size_t capacity)\r
+{\r
+       pImpl_->SetCapacity(capacity);\r
+}\r
+\r
+}
\ No newline at end of file
diff --git a/server/frame/buffers/MotionFrameBuffer.h b/server/frame/buffers/MotionFrameBuffer.h
new file mode 100644 (file)
index 0000000..0271f85
--- /dev/null
@@ -0,0 +1,58 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _MOTION_FRAME_BUFFER_H_\r
+#define _MOTION_FRAME_BUFFER_H_\r
+\r
+#include "FrameBuffer.h"\r
+#include "../Frame.h"\r
+\r
+#include "../../utils/event.h"\r
+\r
+#include <memory>\r
+\r
+namespace caspar\r
+{\r
+\r
+class MotionFrameBuffer : public FrameBuffer, private utils::Noncopyable\r
+{\r
+public:\r
+       MotionFrameBuffer();\r
+       explicit MotionFrameBuffer(unsigned int);\r
+       virtual ~MotionFrameBuffer(){}\r
+\r
+\r
+       virtual FramePtr front() const;\r
+       virtual FrameBufferFetchResult pop_front();\r
+       virtual void push_back(FramePtr);\r
+       virtual void clear();\r
+       void SetCapacity(size_t capacity);\r
+\r
+       HANDLE GetWriteWaitHandle();\r
+       virtual HANDLE GetWaitHandle() const;\r
+\r
+private:\r
+       struct Implementation;\r
+       std::tr1::shared_ptr<Implementation> pImpl_;\r
+};\r
+\r
+}\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/frame/buffers/StaticFrameBuffer.cpp b/server/frame/buffers/StaticFrameBuffer.cpp
new file mode 100644 (file)
index 0000000..fe427a4
--- /dev/null
@@ -0,0 +1,69 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "../../stdafx.h"\r
+\r
+#include "StaticFrameBuffer.h"\r
+\r
+namespace caspar\r
+{\r
+\r
+StaticFrameBuffer::StaticFrameBuffer() : event_(TRUE, FALSE) \r
+{\r
+}\r
+StaticFrameBuffer::~StaticFrameBuffer() \r
+{\r
+}\r
+\r
+FramePtr StaticFrameBuffer::front() const \r
+{\r
+       tbb::spin_mutex::scoped_lock lock(mutex_);\r
+       return pFrame_;\r
+}\r
+\r
+FrameBufferFetchResult StaticFrameBuffer::pop_front() \r
+{\r
+       tbb::spin_mutex::scoped_lock lock(mutex_);\r
+       if(pFrame_ == 0)\r
+               return FetchWait;\r
+       else\r
+               return FetchEOF;\r
+}\r
+\r
+void StaticFrameBuffer::push_back(FramePtr pFrame) \r
+{\r
+       tbb::spin_mutex::scoped_lock lock(mutex_);\r
+       pFrame_ = pFrame;\r
+       event_.Set();\r
+}\r
+\r
+void StaticFrameBuffer::clear() \r
+{\r
+       tbb::spin_mutex::scoped_lock lock(mutex_);\r
+       event_.Reset();\r
+       pFrame_.reset();\r
+}\r
+\r
+HANDLE StaticFrameBuffer::GetWaitHandle() const \r
+{\r
+       return event_;\r
+}\r
+\r
+}
\ No newline at end of file
diff --git a/server/frame/buffers/StaticFrameBuffer.h b/server/frame/buffers/StaticFrameBuffer.h
new file mode 100644 (file)
index 0000000..e5f5b0e
--- /dev/null
@@ -0,0 +1,52 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _STATIC_FRAME_BUFFER_\r
+#define _STATIC_FRAME_BUFFER_\r
+\r
+#include "FrameBuffer.h"\r
+#include "../Frame.h"\r
+\r
+#include <tbb/spin_mutex.h>\r
+\r
+namespace caspar\r
+{\r
+\r
+class StaticFrameBuffer : public FrameBuffer, private utils::Noncopyable\r
+{      \r
+public:\r
+       StaticFrameBuffer();\r
+       virtual ~StaticFrameBuffer();\r
+\r
+       virtual FramePtr front() const;\r
+       virtual FrameBufferFetchResult pop_front();\r
+       virtual void push_back(FramePtr);\r
+       virtual void clear();\r
+       virtual HANDLE GetWaitHandle() const;\r
+\r
+private:\r
+       utils::Event event_;\r
+       FramePtr pFrame_;\r
+       mutable tbb::spin_mutex mutex_;\r
+};\r
+\r
+}\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/io/AsyncEventServer.cpp b/server/io/AsyncEventServer.cpp
new file mode 100644 (file)
index 0000000..5fdd76a
--- /dev/null
@@ -0,0 +1,579 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+// AsyncEventServer.cpp: implementation of the AsyncEventServer class.\r
+//\r
+//////////////////////////////////////////////////////////////////////\r
+\r
+#include "..\stdafx.h"\r
+\r
+#include "AsyncEventServer.h"\r
+#include "SocketInfo.h"\r
+\r
+#include <string>\r
+#include <algorithm>\r
+\r
+namespace caspar {\r
+namespace IO {\r
+\r
+using namespace utils;\r
+\r
+#define CASPAR_MAXIMUM_SOCKET_CLIENTS  (MAXIMUM_WAIT_OBJECTS-1)        \r
+\r
+long AsyncEventServer::instanceCount_ = 0;\r
+//////////////////////////////\r
+// AsyncEventServer constructor\r
+// PARAMS: port(TCP-port the server should listen to)\r
+// COMMENT: Initializes the WinSock2 library\r
+AsyncEventServer::AsyncEventServer(int port) : port_(port)\r
+{\r
+       if(instanceCount_ == 0) {\r
+               WSADATA wsaData;\r
+               if(WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR)\r
+                       throw std::exception("Error initializing WinSock2");\r
+               else {\r
+                       LOG << TEXT("WinSock2 Initialized.") << LogStream::Flush;\r
+               }\r
+       }\r
+\r
+       InterlockedIncrement(&instanceCount_);\r
+}\r
+\r
+/////////////////////////////\r
+// AsyncEventServer destructor\r
+AsyncEventServer::~AsyncEventServer() {\r
+       Stop();\r
+\r
+       InterlockedDecrement(&instanceCount_);\r
+       if(instanceCount_ == 0)\r
+               WSACleanup();\r
+}\r
+\r
+void AsyncEventServer::SetClientDisconnectHandler(ClientDisconnectEvent handler) {\r
+       socketInfoCollection_.onSocketInfoRemoved = handler;\r
+}\r
+\r
+//////////////////////////////\r
+// AsyncEventServer::Start\r
+// RETURNS: true at successful startup\r
+bool AsyncEventServer::Start() {\r
+       if(listenThread_.IsRunning())\r
+               return false;\r
+\r
+       socketInfoCollection_.Clear();\r
+\r
+       sockaddr_in sockAddr;\r
+       ZeroMemory(&sockAddr, sizeof(sockAddr));\r
+       sockAddr.sin_family = AF_INET;\r
+       sockAddr.sin_addr.s_addr = INADDR_ANY;\r
+       sockAddr.sin_port = htons(port_);\r
+       \r
+       SOCKET listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);\r
+       if(listenSocket == INVALID_SOCKET) {\r
+               LOG << TEXT("Failed to create listenSocket");\r
+               return false;\r
+       }\r
+       \r
+       pListenSocketInfo_ = SocketInfoPtr(new SocketInfo(listenSocket, this));\r
+\r
+       if(WSAEventSelect(pListenSocketInfo_->socket_, pListenSocketInfo_->event_, FD_ACCEPT|FD_CLOSE) == SOCKET_ERROR) {\r
+               LOG << TEXT("Failed to enter EventSelect-mode for listenSocket");\r
+               return false;\r
+       }\r
+\r
+       if(bind(pListenSocketInfo_->socket_, (sockaddr*)&sockAddr, sizeof(sockAddr)) == SOCKET_ERROR) {\r
+               LOG << TEXT("Failed to bind listenSocket");\r
+               return false;\r
+       }\r
+\r
+       if(listen(pListenSocketInfo_->socket_, SOMAXCONN) == SOCKET_ERROR) {\r
+               LOG << TEXT("Failed to listen");\r
+               return false;\r
+       }\r
+\r
+       socketInfoCollection_.AddSocketInfo(pListenSocketInfo_);\r
+\r
+       //start thread: the entrypoint is Run(EVENT stopEvent)\r
+       if(!listenThread_.Start(this)) {\r
+               LOG << TEXT("Failed to create ListenThread");\r
+               return false;\r
+       }\r
+\r
+       LOG << TEXT("Listener successfully initialized");\r
+       return true;\r
+}\r
+\r
+void AsyncEventServer::Run(HANDLE stopEvent)\r
+{\r
+       WSANETWORKEVENTS networkEvents;\r
+\r
+       HANDLE waitHandlesCopy[MAXIMUM_WAIT_OBJECTS];\r
+       waitHandlesCopy[0] = stopEvent;\r
+\r
+       while(true)     {\r
+               //Update local copy of the array of wait-handles if nessecery\r
+               if(socketInfoCollection_.IsDirty()) {\r
+                       socketInfoCollection_.CopyCollectionToArray(&(waitHandlesCopy[1]), CASPAR_MAXIMUM_SOCKET_CLIENTS);\r
+                       socketInfoCollection_.ClearDirty();\r
+               }\r
+\r
+               DWORD waitResult = WSAWaitForMultipleEvents(min(static_cast<DWORD>(socketInfoCollection_.Size()+1), MAXIMUM_WAIT_OBJECTS), waitHandlesCopy, FALSE, 1500, FALSE);\r
+               if(waitResult == WAIT_TIMEOUT)\r
+                       continue;\r
+               else if(waitResult == WAIT_FAILED)\r
+                       break;\r
+               else {\r
+                       DWORD eventIndex = waitResult - WAIT_OBJECT_0;\r
+\r
+                       HANDLE waitEvent = waitHandlesCopy[eventIndex];\r
+                       SocketInfoPtr pSocketInfo;\r
+\r
+                       if(eventIndex == 0)     //stopEvent\r
+                               break;\r
+                       else if(socketInfoCollection_.FindSocketInfo(waitEvent, pSocketInfo)) {\r
+                               WSAEnumNetworkEvents(pSocketInfo->socket_, waitEvent, &networkEvents);\r
+\r
+                               if(networkEvents.lNetworkEvents & FD_ACCEPT) {\r
+                                       if(networkEvents.iErrorCode[FD_ACCEPT_BIT] == 0)\r
+                                               OnAccept(pSocketInfo);\r
+                                       else {\r
+                                               LOG << LogLevel::Debug << TEXT("OnAccept (ErrorCode: ") << networkEvents.iErrorCode[FD_ACCEPT_BIT] << TEXT(")");\r
+                                               OnError(waitEvent, networkEvents.iErrorCode[FD_ACCEPT_BIT]);\r
+                                       }\r
+                               }\r
+\r
+                               if(networkEvents.lNetworkEvents & FD_CLOSE) {\r
+                                       if(networkEvents.iErrorCode[FD_CLOSE_BIT] == 0)\r
+                                               OnClose(pSocketInfo);\r
+                                       else {\r
+                                               LOG << LogLevel::Debug << TEXT("OnClose (ErrorCode: ") << networkEvents.iErrorCode[FD_CLOSE_BIT] << TEXT(")");\r
+                                               OnError(waitEvent, networkEvents.iErrorCode[FD_CLOSE_BIT]);\r
+                                       }\r
+                                       continue;\r
+                               }\r
+\r
+                               if(networkEvents.lNetworkEvents & FD_READ) {\r
+                                       if(networkEvents.iErrorCode[FD_READ_BIT] == 0)\r
+                                               OnRead(pSocketInfo);\r
+                                       else {\r
+                                               LOG << LogLevel::Debug << TEXT("OnRead (ErrorCode: ") << networkEvents.iErrorCode[FD_READ_BIT] << TEXT(")");\r
+                                               OnError(waitEvent, networkEvents.iErrorCode[FD_READ_BIT]);\r
+                                       }\r
+                               }\r
+\r
+                               if(networkEvents.lNetworkEvents & FD_WRITE) {\r
+                                       if(networkEvents.iErrorCode[FD_WRITE_BIT] == 0)\r
+                                               OnWrite(pSocketInfo);\r
+                                       else {\r
+                                               LOG << LogLevel::Debug << TEXT("OnWrite (ErrorCode: ") << networkEvents.iErrorCode[FD_WRITE_BIT] << TEXT(")");\r
+                                               OnError(waitEvent, networkEvents.iErrorCode[FD_WRITE_BIT]);\r
+                                       }\r
+                               }\r
+                       }\r
+                       else {\r
+                               //Could not find the waitHandle in the SocketInfoCollection.\r
+                               //It must have been removed during the last call to WSAWaitForMultipleEvents\r
+                       }\r
+               }\r
+       }\r
+}\r
+\r
+bool AsyncEventServer::OnUnhandledException(const std::exception& ex) throw() {\r
+       bool bDoRestart = true;\r
+\r
+       try \r
+       {\r
+               LOG << TEXT("UNHANDLED EXCEPTION in TCPServers listeningthread. Message: ") << ex.what();\r
+       }\r
+       catch(...)\r
+       {\r
+               bDoRestart = false;\r
+       }\r
+\r
+       return bDoRestart;\r
+}\r
+\r
+///////////////////////////////\r
+// AsyncEventServer:Stop\r
+// COMMENT: Shuts down\r
+void AsyncEventServer::Stop()\r
+{\r
+       //TODO: initiate shutdown on all clients connected\r
+//     for(int i=0; i < _totalActiveSockets; ++i) {\r
+//             shutdown(_pSocketInfo[i]->_socket, SD_SEND);\r
+//     }\r
+\r
+       if(!listenThread_.Stop()) {\r
+               LOG << TEXT("Wait for listenThread timed out.");\r
+       }\r
+\r
+       socketInfoCollection_.Clear();\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////\r
+//\r
+// MESSAGE HANDLERS   \r
+//\r
+////////////////////////////////////////////////////////////////////\r
+\r
+\r
+//////////////////////////////\r
+// AsyncEventServer::OnAccept\r
+// PARAMS: ...\r
+// COMMENT: Called when a new client connects\r
+bool AsyncEventServer::OnAccept(SocketInfoPtr& pSI) {\r
+       sockaddr_in     clientAddr;\r
+       int addrSize = sizeof(clientAddr);\r
+       SOCKET clientSocket = WSAAccept(pSI->socket_, (sockaddr*)&clientAddr, &addrSize, NULL, NULL);\r
+       if(clientSocket == INVALID_SOCKET) {\r
+               LogSocketError(TEXT("Accept"));\r
+               return false;\r
+       }\r
+\r
+       SocketInfoPtr pClientSocket(new SocketInfo(clientSocket, this));\r
+\r
+       //Determine if we can handle one more client\r
+       if(socketInfoCollection_.Size() >= CASPAR_MAXIMUM_SOCKET_CLIENTS) {\r
+               LOG << TEXT("Could not accept (too many connections).");\r
+               return true;\r
+       }\r
+\r
+       if(WSAEventSelect(pClientSocket->socket_, pClientSocket->event_, FD_READ | FD_WRITE | FD_CLOSE) == SOCKET_ERROR) {\r
+               LogSocketError(TEXT("Accept (failed create event for new client)"));\r
+               return false;\r
+       }\r
+\r
+       TCHAR addressBuffer[32];\r
+       MultiByteToWideChar(CP_ACP, 0, inet_ntoa(clientAddr.sin_addr), -1, addressBuffer, 32);\r
+       pClientSocket->host_ = addressBuffer;\r
+\r
+       socketInfoCollection_.AddSocketInfo(pClientSocket);\r
+\r
+       LOG << TEXT("Accepted connection from ") << pClientSocket->host_.c_str();\r
+\r
+       return true;\r
+}\r
+\r
+bool ConvertMultiByteToWideChar(UINT codePage, char* pSource, int sourceLength, caspar::utils::DataBuffer<wchar_t>& wideBuffer, int& countLeftovers)\r
+{\r
+       if(codePage == CP_UTF8) {\r
+               countLeftovers = 0;\r
+               //check from the end of pSource for ev. uncompleted UTF-8 byte sequence\r
+               if(pSource[sourceLength-1] & 0x80) {\r
+                       //The last byte is part of a multibyte sequence. If the sequence is not complete, we need to save the partial sequence\r
+                       int bytesToCheck = min(4, sourceLength);        //a sequence contains a maximum of 4 bytes\r
+                       int currentLeftoverIndex = sourceLength-1;\r
+                       for(; bytesToCheck > 0; --bytesToCheck, --currentLeftoverIndex) {\r
+                               ++countLeftovers;\r
+                               if(pSource[currentLeftoverIndex] & 0x80) {\r
+                                       if(pSource[currentLeftoverIndex] & 0x40) { //The two high-bits are set, this is the "header"\r
+                                               int expectedSequenceLength = 2;\r
+                                               if(pSource[currentLeftoverIndex] & 0x20)\r
+                                                       ++expectedSequenceLength;\r
+                                               if(pSource[currentLeftoverIndex] & 0x10)\r
+                                                       ++expectedSequenceLength;\r
+\r
+                                               if(countLeftovers < expectedSequenceLength) {\r
+                                                       //The sequence is incomplete. Leave the leftovers to be interpreted with the next call\r
+                                                       break;\r
+                                               }\r
+                                               //The sequence is complete, there are no leftovers. \r
+                                               //...OR...\r
+                                               //error. Let the conversion-function take the hit.\r
+                                               countLeftovers = 0;\r
+                                               break;\r
+                                       }\r
+                               }\r
+                               else {\r
+                                       //error. Let the conversion-function take the hit.\r
+                                       countLeftovers = 0;\r
+                                       break;\r
+                               }\r
+                       }\r
+                       if(countLeftovers == 4) {\r
+                               //error. Let the conversion-function take the hit.\r
+                               countLeftovers = 0;\r
+                       }\r
+               }\r
+       }\r
+\r
+       int charsWritten = 0;\r
+       int sourceBytesToProcess = sourceLength-countLeftovers;\r
+       int wideBufferCapacity = MultiByteToWideChar(codePage, 0, pSource, sourceBytesToProcess, NULL, NULL);\r
+       if(wideBufferCapacity > 0) \r
+       {\r
+               wideBuffer.Realloc(wideBufferCapacity);\r
+               charsWritten = MultiByteToWideChar(codePage, 0, pSource, sourceBytesToProcess, wideBuffer.GetPtr(), wideBuffer.GetCapacity());\r
+       }\r
+       //copy the leftovers to the front of the buffer\r
+       if(countLeftovers > 0) {\r
+               memcpy(pSource, &(pSource[sourceBytesToProcess]), countLeftovers);\r
+       }\r
+\r
+       wideBuffer.SetLength(charsWritten);\r
+       return (charsWritten > 0);\r
+}\r
+\r
+//////////////////////////////\r
+// AsyncEventServer::OnRead\r
+// PARAMS: ...\r
+// COMMENT: Called then something arrives on the socket that has to be read\r
+bool AsyncEventServer::OnRead(SocketInfoPtr& pSI) {\r
+       int recvResult = SOCKET_ERROR;\r
+\r
+       int maxRecvLength = sizeof(pSI->recvBuffer_)-pSI->recvLeftoverOffset_;\r
+       recvResult = recv(pSI->socket_, pSI->recvBuffer_+pSI->recvLeftoverOffset_, maxRecvLength, 0);\r
+       while(recvResult != SOCKET_ERROR) {\r
+               if(recvResult == 0) {\r
+                       LOG << TEXT("Client ") << pSI->host_.c_str() << TEXT(" disconnected");\r
+\r
+                       socketInfoCollection_.RemoveSocketInfo(pSI);\r
+                       return true;\r
+               }\r
+\r
+               if(pProtocolStrategy_ != 0) {\r
+                       //Convert to widechar\r
+                       if(ConvertMultiByteToWideChar(pProtocolStrategy_->GetCodepage(), pSI->recvBuffer_, recvResult + pSI->recvLeftoverOffset_, pSI->wideRecvBuffer_, pSI->recvLeftoverOffset_))\r
+                               pProtocolStrategy_->Parse(pSI->wideRecvBuffer_.GetPtr(), pSI->wideRecvBuffer_.GetLength(), pSI);\r
+                       else\r
+                       {\r
+                               LOG << TEXT("Read from ") << pSI->host_.c_str() << TEXT(" failed, could not convert command to UNICODE");\r
+                       }\r
+               }\r
+\r
+               maxRecvLength = sizeof(pSI->recvBuffer_)-pSI->recvLeftoverOffset_;\r
+               recvResult = recv(pSI->socket_, pSI->recvBuffer_+pSI->recvLeftoverOffset_, maxRecvLength, 0);\r
+       }\r
+\r
+       if(recvResult == SOCKET_ERROR) {\r
+               int errorCode = WSAGetLastError();\r
+               if(errorCode == WSAEWOULDBLOCK)\r
+                       return true;\r
+               else {\r
+                       LogSocketError(TEXT("Read"), errorCode);\r
+                       OnError(pSI->event_, errorCode);\r
+               }\r
+       }\r
+\r
+       return false;\r
+}\r
+\r
+//////////////////////////////\r
+// AsyncEventServer::OnWrite\r
+// PARAMS: ...\r
+// COMMENT: Called when the socket is ready to send more data\r
+void AsyncEventServer::OnWrite(SocketInfoPtr& pSI) {\r
+       DoSend(*pSI);   \r
+}\r
+\r
+bool ConvertWideCharToMultiByte(UINT codePage, const std::wstring& wideString, caspar::utils::DataBuffer<char>& destBuffer)\r
+{\r
+       int bytesWritten = 0;\r
+       int multibyteBufferCapacity = WideCharToMultiByte(codePage, 0, wideString.c_str(), static_cast<int>(wideString.length()), 0, 0, NULL, NULL);\r
+       if(multibyteBufferCapacity > 0) \r
+       {\r
+               destBuffer.Realloc(multibyteBufferCapacity);\r
+               bytesWritten = WideCharToMultiByte(codePage, 0, wideString.c_str(), static_cast<int>(wideString.length()), destBuffer.GetPtr(), destBuffer.GetCapacity(), NULL, NULL);\r
+       }\r
+       destBuffer.SetLength(bytesWritten);\r
+       return (bytesWritten > 0);\r
+}\r
+\r
+void AsyncEventServer::DoSend(SocketInfo& socketInfo) {\r
+       //Locks the socketInfo-object so that no one else tampers with the sendqueue at the same time\r
+       SocketInfo::Lock lock(socketInfo);\r
+\r
+       while(!socketInfo.sendQueue_.empty() || socketInfo.currentlySending_.GetLength() > 0) {\r
+               if(socketInfo.currentlySending_.GetLength() == 0) {\r
+                       //Read the next string in the queue and convert to UTF-8\r
+                       if(!ConvertWideCharToMultiByte(pProtocolStrategy_->GetCodepage(), socketInfo.sendQueue_.front(), socketInfo.currentlySending_))\r
+                       {\r
+                               LOG << TEXT("Send to ") << socketInfo.host_.c_str() << TEXT(" failed, could not convert response to UTF-8");\r
+                       }\r
+                       socketInfo.currentlySendingOffset_ = 0;\r
+               }\r
+\r
+               if(socketInfo.currentlySending_.GetLength() > 0) {\r
+                       int bytesToSend = static_cast<int>(socketInfo.currentlySending_.GetLength()-socketInfo.currentlySendingOffset_);\r
+                       int sentBytes = send(socketInfo.socket_, socketInfo.currentlySending_.GetPtr(socketInfo.currentlySendingOffset_), bytesToSend, 0);\r
+                       if(sentBytes == SOCKET_ERROR) {\r
+                               int errorCode = WSAGetLastError();\r
+                               if(errorCode == WSAEWOULDBLOCK) {\r
+                                       LOG << LogLevel::Debug << TEXT("Send to ") << socketInfo.host_.c_str() << TEXT(" would block, sending later");\r
+                                       break;\r
+                               }\r
+                               else {\r
+                                       LogSocketError(TEXT("Send"), errorCode);\r
+                                       OnError(socketInfo.event_, errorCode);\r
+\r
+                                       socketInfo.currentlySending_.SetLength(0);\r
+                                       socketInfo.currentlySendingOffset_ = 0;\r
+                                       socketInfo.sendQueue_.pop();\r
+                                       break;\r
+                               }\r
+                       }\r
+                       else {\r
+                               if(sentBytes == bytesToSend) {\r
+                                       if(sentBytes < 200)\r
+                                               LOG << LogLevel::Verbose << TEXT("Sent ") << socketInfo.sendQueue_.front().c_str() << TEXT(" to ") << socketInfo.host_.c_str();\r
+                                       else\r
+                                               LOG << LogLevel::Verbose << TEXT("Sent more than 200 bytes to ") << socketInfo.host_.c_str();\r
+\r
+                                       socketInfo.currentlySending_.SetLength(0);\r
+                                       socketInfo.currentlySendingOffset_ = 0;\r
+                                       socketInfo.sendQueue_.pop();\r
+                               }\r
+                               else {\r
+                                       socketInfo.currentlySendingOffset_ += sentBytes;\r
+                                       LOG << LogLevel::Verbose << TEXT("Sent partial message to ") << socketInfo.host_.c_str();\r
+                               }\r
+                       }\r
+               }\r
+               else\r
+                       socketInfo.sendQueue_.pop();\r
+       }\r
+}\r
+\r
+//////////////////////////////\r
+// AsyncEventServer::OnClose\r
+// PARAMS: ...\r
+// COMMENT: Called when a client disconnects / is disconnected\r
+void AsyncEventServer::OnClose(SocketInfoPtr& pSI) {\r
+       LOG << TEXT("Client ") << pSI->host_.c_str() << TEXT(" was disconnected");\r
+\r
+       socketInfoCollection_.RemoveSocketInfo(pSI);\r
+}\r
+\r
+//////////////////////////////\r
+// AsyncEventServer::OnError\r
+// PARAMS: ...\r
+// COMMENT: Called when an errorcode is recieved\r
+void AsyncEventServer::OnError(HANDLE waitEvent, int errorCode) {\r
+       if(errorCode == WSAENETDOWN || errorCode == WSAECONNABORTED || errorCode == WSAECONNRESET || errorCode == WSAESHUTDOWN || errorCode == WSAETIMEDOUT || errorCode == WSAENOTCONN || errorCode == WSAENETRESET) {\r
+               SocketInfoPtr pSocketInfo;\r
+               if(socketInfoCollection_.FindSocketInfo(waitEvent, pSocketInfo)) {\r
+                       LOG << TEXT("Client ") << pSocketInfo->host_.c_str() << TEXT(" was disconnected, Errorcode ") << errorCode;\r
+               }\r
+\r
+               socketInfoCollection_.RemoveSocketInfo(waitEvent);\r
+       }\r
+}\r
+\r
+//////////////////////////////\r
+// AsyncEventServer::DisconnectClient\r
+// PARAMS: ...\r
+// COMMENT: The client is removed from the actual client-list when an FD_CLOSE notification is recieved\r
+void AsyncEventServer::DisconnectClient(SocketInfo& socketInfo) {\r
+       int result = shutdown(socketInfo.socket_, SD_SEND);\r
+       if(result == SOCKET_ERROR)\r
+               OnError(socketInfo.event_, result);\r
+}\r
+\r
+//////////////////////////////\r
+// AsyncEventServer::LogSocketError\r
+void AsyncEventServer::LogSocketError(const TCHAR* pStr, int socketError) {\r
+       if(socketError == 0)\r
+               socketError = WSAGetLastError();\r
+\r
+       LOG << TEXT("Failed to ") << pStr << TEXT(" Errorcode: ") << socketError;\r
+}\r
+\r
+\r
+//////////////////////////////\r
+//  SocketInfoCollection\r
+//////////////////////////////\r
+\r
+AsyncEventServer::SocketInfoCollection::SocketInfoCollection() : bDirty_(false) {\r
+}\r
+\r
+AsyncEventServer::SocketInfoCollection::~SocketInfoCollection() {\r
+}\r
+\r
+bool AsyncEventServer::SocketInfoCollection::AddSocketInfo(SocketInfoPtr& pSocketInfo) {\r
+       Lock lock(*this);\r
+\r
+       waitEvents_.resize(waitEvents_.size()+1);\r
+       bool bSuccess = socketInfoMap_.insert(SocketInfoMap::value_type(pSocketInfo->event_, pSocketInfo)).second;\r
+       if(bSuccess) {\r
+               waitEvents_[waitEvents_.size()-1] = pSocketInfo->event_;\r
+               bDirty_ = true;\r
+       }\r
+\r
+       return bSuccess;\r
+}\r
+\r
+void AsyncEventServer::SocketInfoCollection::RemoveSocketInfo(SocketInfoPtr& pSocketInfo) {\r
+       if(pSocketInfo != 0) {\r
+               RemoveSocketInfo(pSocketInfo->event_);\r
+       }\r
+}\r
+void AsyncEventServer::SocketInfoCollection::RemoveSocketInfo(HANDLE waitEvent) {\r
+       Lock lock(*this);\r
+\r
+       //Find instance\r
+       SocketInfoPtr pSocketInfo;\r
+       SocketInfoMap::iterator it = socketInfoMap_.find(waitEvent);\r
+       SocketInfoMap::iterator end = socketInfoMap_.end();\r
+       if(it != end)\r
+               pSocketInfo = it->second;\r
+\r
+       if(pSocketInfo) {\r
+               pSocketInfo->pServer_ = NULL;\r
+\r
+               socketInfoMap_.erase(waitEvent);\r
+\r
+               HandleVector::iterator it = std::find(waitEvents_.begin(), waitEvents_.end(), waitEvent);\r
+               if(it != waitEvents_.end()) {\r
+                       std::swap((*it), waitEvents_.back());\r
+                       waitEvents_.resize(waitEvents_.size()-1);\r
+\r
+                       bDirty_ = true;\r
+               }\r
+       }\r
+       if(onSocketInfoRemoved)\r
+               onSocketInfoRemoved(pSocketInfo);\r
+}\r
+\r
+bool AsyncEventServer::SocketInfoCollection::FindSocketInfo(HANDLE key, SocketInfoPtr& pResult) {\r
+       Lock lock(*this);\r
+\r
+       SocketInfoMap::iterator it = socketInfoMap_.find(key);\r
+       SocketInfoMap::iterator end = socketInfoMap_.end();\r
+       if(it != end)\r
+               pResult = it->second;\r
+\r
+       return (it != end);\r
+}\r
+\r
+void AsyncEventServer::SocketInfoCollection::CopyCollectionToArray(HANDLE* pDest, int maxCount) {\r
+       Lock lock(*this);\r
+\r
+       memcpy(pDest, &(waitEvents_[0]), min( maxCount, static_cast<int>(waitEvents_.size()) ) * sizeof(HANDLE) );\r
+}\r
+\r
+void AsyncEventServer::SocketInfoCollection::Clear() {\r
+       Lock lock(*this);\r
+\r
+       socketInfoMap_.clear();\r
+       waitEvents_.clear();\r
+}\r
+\r
+}      //namespace IO\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/io/AsyncEventServer.h b/server/io/AsyncEventServer.h
new file mode 100644 (file)
index 0000000..70f4338
--- /dev/null
@@ -0,0 +1,135 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+// AsyncEventServer.h: interface for the AsyncServer class.\r
+//////////////////////////////////////////////////////////////////////\r
+\r
+#if !defined(AFX_ASYNCEVENTSERVER_H__0BFA29CB_BE4C_46A0_9CAE_E233ED27A8EC__INCLUDED_)\r
+#define AFX_ASYNCEVENTSERVER_H__0BFA29CB_BE4C_46A0_9CAE_E233ED27A8EC__INCLUDED_\r
+\r
+#if _MSC_VER > 1000\r
+#pragma once\r
+#endif // _MSC_VER > 1000\r
+\r
+#include <string>\r
+#include <map>\r
+#include <vector>\r
+#include <functional>\r
+\r
+#include "..\utils\thread.h"\r
+#include "..\utils\lockable.h"\r
+\r
+#include "ProtocolStrategy.h"\r
+#include "..\controller.h"\r
+#include "SocketInfo.h"\r
+\r
+namespace caspar {\r
+namespace IO {\r
+\r
+typedef std::function<void(caspar::IO::SocketInfoPtr)> ClientDisconnectEvent;\r
+\r
+class AsyncEventServer : public utils::IRunnable, public caspar::IController\r
+{\r
+       static long instanceCount_;\r
+\r
+       AsyncEventServer();\r
+       AsyncEventServer(const AsyncEventServer&);\r
+       AsyncEventServer& operator=(const AsyncEventServer&);\r
+\r
+public:\r
+       explicit AsyncEventServer(int port);\r
+       ~AsyncEventServer();\r
+\r
+       bool Start();\r
+       void SetProtocolStrategy(ProtocolStrategyPtr pPS) {\r
+               pProtocolStrategy_ = pPS;\r
+       }\r
+\r
+       void Stop();\r
+\r
+       void SetClientDisconnectHandler(ClientDisconnectEvent handler);\r
+       \r
+private:\r
+       utils::Thread   listenThread_;\r
+       void Run(HANDLE stopEvent);\r
+       bool OnUnhandledException(const std::exception&) throw();\r
+\r
+       bool OnAccept(SocketInfoPtr&);\r
+       bool OnRead(SocketInfoPtr&);\r
+       void OnWrite(SocketInfoPtr&);\r
+       void OnClose(SocketInfoPtr&);\r
+       void OnError(HANDLE waitEvent, int errorCode);\r
+\r
+       SocketInfoPtr           pListenSocketInfo_;\r
+       ProtocolStrategyPtr     pProtocolStrategy_;\r
+       int                                     port_;\r
+\r
+       friend class SocketInfo;\r
+       void DoSend(SocketInfo&);\r
+       void DisconnectClient(SocketInfo&);\r
+\r
+       void LogSocketError(const TCHAR* pStr, int socketError = 0);\r
+\r
+       class SocketInfoCollection : private utils::LockableObject\r
+       {\r
+               SocketInfoCollection(const SocketInfoCollection&);\r
+               SocketInfoCollection& operator=(const SocketInfoCollection&);\r
+\r
+               typedef std::map<HANDLE, SocketInfoPtr> SocketInfoMap;\r
+               typedef std::vector<HANDLE> HandleVector;\r
+\r
+       public:\r
+               SocketInfoCollection();\r
+               ~SocketInfoCollection();\r
+\r
+               bool AddSocketInfo(SocketInfoPtr& pSocketInfo);\r
+               void RemoveSocketInfo(SocketInfoPtr& pSocketInfo);\r
+               void RemoveSocketInfo(HANDLE);\r
+               void CopyCollectionToArray(HANDLE*, int maxCount);\r
+\r
+               bool FindSocketInfo(HANDLE, SocketInfoPtr& pResult);\r
+\r
+               bool IsDirty() {\r
+                       return bDirty_;\r
+               }\r
+               void ClearDirty() {\r
+                       bDirty_ = false;\r
+               }\r
+\r
+               std::size_t Size() {\r
+                       return waitEvents_.size();\r
+               }\r
+               void Clear();\r
+\r
+               ClientDisconnectEvent onSocketInfoRemoved;\r
+\r
+       private:\r
+               SocketInfoMap socketInfoMap_;\r
+               HandleVector waitEvents_;\r
+               bool bDirty_;\r
+       };\r
+       SocketInfoCollection socketInfoCollection_;\r
+};\r
+typedef std::tr1::shared_ptr<AsyncEventServer> AsyncEventServerPtr;\r
+\r
+}      //namespace IO\r
+}      //namespace caspar\r
+\r
+#endif // !defined(AFX_ASYNCEVENTSERVER_H__0BFA29CB_BE4C_46A0_9CAE_E233ED27A8EC__INCLUDED_)\r
diff --git a/server/io/ClientInfo.h b/server/io/ClientInfo.h
new file mode 100644 (file)
index 0000000..dcae66c
--- /dev/null
@@ -0,0 +1,51 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _CLIENTINFO_H__\r
+#define _CLIENTINFO_H__\r
+\r
+#pragma once\r
+\r
+#include <string>\r
+\r
+namespace caspar {\r
+namespace IO {\r
+\r
+class ClientInfo \r
+{\r
+protected:\r
+       ClientInfo()\r
+       {}\r
+\r
+public:\r
+       virtual ~ClientInfo() {\r
+       }\r
+\r
+       virtual void Send(const tstring& data) = 0;\r
+       virtual void Disconnect() = 0;\r
+\r
+       tstring         currentMessage_;\r
+};\r
+typedef std::tr1::shared_ptr<ClientInfo> ClientInfoPtr;\r
+\r
+}      //namespace IO\r
+}      //namespace caspar\r
+\r
+#endif //_CLIENTINFO_H__
\ No newline at end of file
diff --git a/server/io/ProtocolStrategy.h b/server/io/ProtocolStrategy.h
new file mode 100644 (file)
index 0000000..9c7ea63
--- /dev/null
@@ -0,0 +1,47 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _PROTOCOLSTRATEGY_H__\r
+#define _PROTOCOLSTRATEGY_H__\r
+\r
+#pragma once\r
+\r
+#include <string>\r
+#include "clientInfo.h"\r
+\r
+namespace caspar {\r
+namespace IO {\r
+\r
+class IProtocolStrategy\r
+{\r
+public:\r
+       virtual ~IProtocolStrategy()\r
+       {}\r
+\r
+       virtual void Parse(const TCHAR* pData, int charCount, ClientInfoPtr pClientInfo) = 0;\r
+       virtual UINT GetCodepage() = 0;\r
+};\r
+\r
+typedef std::tr1::shared_ptr<IProtocolStrategy> ProtocolStrategyPtr;\r
+\r
+}      //namespace IO\r
+}      //namespace caspar\r
+\r
+#endif //_PROTOCOLSTRATEGY_H__
\ No newline at end of file
diff --git a/server/io/SerialPort.cpp b/server/io/SerialPort.cpp
new file mode 100644 (file)
index 0000000..294bade
--- /dev/null
@@ -0,0 +1,502 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\StdAfx.h"\r
+\r
+#include "SerialPort.h"\r
+\r
+#include "..\application.h"\r
+\r
+\r
+namespace caspar {\r
+namespace IO {\r
+\r
+using namespace utils;\r
+\r
+void LogCommError(const tstring& msg, int errorCode);\r
+\r
+\r
+/* From winbase.h \r
+#define NOPARITY            0\r
+#define ODDPARITY           1\r
+#define EVENPARITY          2\r
+#define MARKPARITY          3\r
+#define SPACEPARITY         4\r
+\r
+#define ONESTOPBIT          0\r
+#define ONE5STOPBITS        1\r
+#define TWOSTOPBITS         2\r
+*/\r
+\r
+SerialPort::SerialPort(DWORD baudRate, BYTE parity, BYTE dataBits, BYTE stopBits, const tstring& portName) : hPort_(0), portName_(portName)\r
+{\r
+       pClientInfo_ = SerialPortClientInfoPtr(new SerialPortClientInfo(this));\r
+       ZeroMemory(&commSettings_, sizeof(DCB));\r
+       commSettings_.DCBlength = sizeof(commSettings_);\r
+       commSettings_.BaudRate = baudRate;\r
+       commSettings_.fBinary = TRUE;\r
+       commSettings_.Parity = parity;\r
+       if(parity != 0)\r
+               commSettings_.fParity = TRUE;\r
+\r
+       commSettings_.ByteSize = dataBits;\r
+       commSettings_.StopBits = stopBits;\r
+       commSettings_.fNull = TRUE;\r
+}\r
+\r
+SerialPort::~SerialPort() {\r
+       Stop();\r
+}\r
+\r
+\r
+bool SerialPort::Start() {\r
+       if(pProtocolStrategy_ == 0)\r
+               return false;\r
+\r
+       pListener_ = ListenerPtr(new Listener(this, pProtocolStrategy_));\r
+\r
+       if(hPort_ == 0) {\r
+\r
+               //Open the port\r
+               HANDLE port = CreateFile(portName_.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);\r
+               if(port == INVALID_HANDLE_VALUE) {\r
+                       //TODO: Throw Win32ErrorException\r
+                       LogCommError(TEXT("Failed to open port. Error: "), GetLastError());\r
+\r
+                       return false;\r
+               }\r
+\r
+               //Setup port\r
+               if(!SetCommState(port, &commSettings_)) {\r
+                       //TODO: Throw Win32ErrorException\r
+                       LogCommError(TEXT("Failed to set com-settings. Error: "), GetLastError());\r
+\r
+                       CloseHandle(port);\r
+                       return false;\r
+               }\r
+\r
+               COMMTIMEOUTS timeouts;\r
+               ZeroMemory(&timeouts, sizeof(timeouts));\r
+               timeouts.ReadIntervalTimeout = MAXDWORD;\r
+               SetCommTimeouts(port, &timeouts);\r
+\r
+               hPort_ = port;\r
+\r
+               if(listenerThread_.Start(pListener_.get())) {\r
+                       if(GetApplication()->GetSetting(TEXT("spy")) == TEXT("true")) {\r
+                               //don't send anything if we're spying, it would most likely trash the incomming data\r
+                               return true;\r
+                       }\r
+                       else {\r
+                               pWriter_ = WriterPtr(new Writer(hPort_));\r
+                               return writerThread_.Start(pWriter_.get());\r
+                       }\r
+               }\r
+       }\r
+\r
+       return false;\r
+}\r
+\r
+void SerialPort::Stop() {\r
+       if(hPort_ != 0) {\r
+               if(listenerThread_.IsRunning())\r
+                       listenerThread_.Stop();\r
+\r
+               if(writerThread_.IsRunning())\r
+                       writerThread_.Stop();\r
+\r
+               CloseHandle(hPort_);\r
+               hPort_ = 0;\r
+       }\r
+}\r
+\r
+\r
+/// Listener\r
+//////////////\r
+const int SerialPort::Listener::WaitTimeout = 1000;\r
+const int SerialPort::Listener::InputBufferSize = 256;\r
+\r
+SerialPort::Listener::Listener(SerialPort* port, ProtocolStrategyPtr pPS) : pPort_(port), pProtocolStrategy_(pPS), overlappedReadEvent_(TRUE, FALSE), bWaitingOnRead_(false), pInputBuffer_(new char[InputBufferSize]), queuedChars_(0) {\r
+       ZeroMemory(&overlappedRead_, sizeof(OVERLAPPED));\r
+       overlappedRead_.hEvent = overlappedReadEvent_;\r
+\r
+       ZeroMemory(pInputBuffer_, InputBufferSize);\r
+}\r
+\r
+SerialPort::Listener::~Listener() {\r
+       if(pInputBuffer_ != 0) {\r
+               delete[] pInputBuffer_;\r
+               pInputBuffer_ = 0;\r
+       }\r
+}\r
+\r
+void SerialPort::Listener::Run(HANDLE eventStop) {\r
+       OVERLAPPED overlappedStatus;\r
+       ZeroMemory(&overlappedStatus, sizeof(OVERLAPPED));\r
+\r
+       utils::Event eventStatus(TRUE, FALSE);\r
+       overlappedStatus.hEvent = eventStatus;\r
+\r
+       SetCommMask(pPort_->hPort_, EV_BREAK | EV_CTS | EV_DSR | EV_ERR | EV_RING | EV_RLSD | EV_RXCHAR | EV_RXFLAG | EV_TXEMPTY);\r
+\r
+       const int StopEvent = 0;\r
+       const int StatusEvent = 1;\r
+       const int ReadEvent = 2;\r
+\r
+       HANDLE waitEvents[3] =  { eventStop, eventStatus, overlappedReadEvent_ };\r
+\r
+       DWORD resultEventMask = 0;\r
+       bool bContinue = true, bWaitingOnStatusEvent = false;\r
+       while(bContinue) {\r
+               if(!bWaitingOnStatusEvent) {\r
+                       if(WaitCommEvent(pPort_->hPort_, &resultEventMask, &overlappedStatus)) {\r
+                               ProcessStatusEvent(resultEventMask);\r
+                       }\r
+                       else {\r
+                               //WaitCommEvent did not complete. Is it pending or did an error occur?\r
+                               DWORD errorCode = GetLastError();\r
+                               if(errorCode == ERROR_IO_PENDING) {\r
+                                       bWaitingOnStatusEvent = true;\r
+                               }\r
+                               else {\r
+                                       //error in WaitCommEvent\r
+                                       LogCommError(TEXT("Error in WaitCommEvent. Error: "), errorCode);\r
+                                       bContinue = false;\r
+                               }\r
+                       }\r
+               }\r
+\r
+               if(bWaitingOnStatusEvent) {\r
+                       HRESULT waitResult = WaitForMultipleObjects((bWaitingOnRead_ ? 3 : 2), waitEvents, FALSE, WaitTimeout);\r
+                       switch(waitResult) {\r
+                               case WAIT_TIMEOUT:\r
+                               {\r
+                                       break;\r
+                               }\r
+\r
+                               case WAIT_FAILED:\r
+                               {\r
+                                       LOG << TEXT("WaitForMultipleObjects Failed.") << LogStream::Flush;\r
+                                       bContinue = false;\r
+                                       break;\r
+                               }\r
+\r
+                               default:\r
+                               {\r
+                                       int alertObject = waitResult - WAIT_OBJECT_0;\r
+\r
+                                       if(alertObject == StopEvent) {\r
+                                               LOG << TEXT("Got stopEvent. Stopping listener-thread.") << LogStream::Flush;\r
+                                               bContinue = false;\r
+                                       }\r
+                                       else if(alertObject == StatusEvent) {\r
+                                               DWORD numBytes = 0;\r
+                                               if(GetOverlappedResult(pPort_->hPort_, &overlappedStatus, &numBytes, FALSE)) {\r
+                                                       ProcessStatusEvent(resultEventMask);\r
+                                               }\r
+                                               else {\r
+                                                       LogCommError(TEXT("GetOverlappedResult Failed (StatusEvent). Error: "), GetLastError());\r
+                                               }\r
+                                               bWaitingOnStatusEvent = false;\r
+                                       }\r
+                                       else if(alertObject == ReadEvent) {\r
+                                               overlappedReadEvent_.Reset();\r
+                                               DWORD numBytesRead = 0;\r
+                                               if(GetOverlappedResult(pPort_->hPort_, &overlappedRead_, &numBytesRead, FALSE)) {\r
+                                                       bWaitingOnRead_ = false;\r
+                                                       LOG << TEXT("Overlapped completion sucessful.") << LogStream::Flush;\r
+                                                       OnRead(numBytesRead);\r
+                                               }\r
+                                               else {\r
+                                                       LogCommError(TEXT("GetOverlappedResult Failed (ReadEvent). Error: "), GetLastError());\r
+                                               }\r
+                                       }\r
+                                       else {\r
+                                               //unexpected error\r
+                                               LogCommError(TEXT("Unexpected wait-result. Result: "), waitResult);\r
+                                               bContinue = false;\r
+                                       }\r
+                                       break;\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+}\r
+\r
+bool SerialPort::Listener::OnUnhandledException(const std::exception& ex) throw() {\r
+       bool bDoRestart = true;\r
+\r
+       try \r
+       {\r
+               LOG << LogLevel::Critical << TEXT("UNHANDLED EXCEPTION in serialport listener. Message: ") << ex.what() << LogStream::Flush;\r
+\r
+               //TODO: Cleanup and prepare for restart\r
+       }\r
+       catch(...)\r
+       {\r
+               bDoRestart = false;\r
+       }\r
+\r
+       return bDoRestart;\r
+}\r
+\r
+\r
+void SerialPort::Listener::ProcessStatusEvent(DWORD eventMask) {\r
+       DWORD errors = 0;\r
+       COMSTAT commStat;\r
+       ZeroMemory(&commStat, sizeof(COMSTAT));\r
+\r
+       ClearCommError(pPort_->hPort_, &errors, &commStat);\r
+\r
+       if((eventMask & EV_RXCHAR) && (commStat.cbInQue > 0)) {\r
+               queuedChars_ += static_cast<int>(commStat.cbInQue);\r
+               if(!bWaitingOnRead_) {\r
+                       DoRead();\r
+               }\r
+               else {\r
+                       LOG << TEXT("Could not read, already waiting on overlapped completion") << LogStream::Flush;\r
+               }\r
+       }\r
+}\r
+\r
+void SerialPort::Listener::DoRead() {\r
+       bool bContinue;\r
+       do {\r
+               bContinue = false;\r
+               DWORD numBytesRead = 0;\r
+               int bytesToRead = min(InputBufferSize, queuedChars_);\r
+               if(ReadFile(pPort_->hPort_, pInputBuffer_, bytesToRead, &numBytesRead, &overlappedRead_)) {\r
+                       bContinue = OnRead(numBytesRead);\r
+               } else {\r
+                       DWORD errorCode = GetLastError();\r
+                       if(errorCode == ERROR_IO_PENDING) {\r
+                               LOG << TEXT("Could not complete read. Mark as waiting for overlapped completion") << LogStream::Flush;\r
+                               bWaitingOnRead_ = true;\r
+                       }\r
+                       else\r
+                               LogCommError(TEXT("ReadFile Failed. Error: "), errorCode);\r
+               }\r
+       }\r
+       while(bContinue);\r
+}\r
+\r
+bool ConvertMultiByteToWideChar(char* pSource, int sourceLength, caspar::utils::DataBuffer<wchar_t>& wideBuffer)\r
+{\r
+       //28591 = ISO 8859-1 Latin I\r
+       int charsWritten = 0;\r
+       int wideBufferCapacity = MultiByteToWideChar(28591, 0, pSource, sourceLength, NULL, NULL);\r
+       if(wideBufferCapacity > 0) \r
+       {\r
+               wideBuffer.Realloc(wideBufferCapacity);\r
+               charsWritten = MultiByteToWideChar(28591, 0, pSource, sourceLength, wideBuffer.GetPtr(), wideBuffer.GetCapacity());\r
+       }\r
+\r
+       wideBuffer.SetLength(charsWritten);\r
+       return (charsWritten > 0);\r
+}\r
+\r
+bool SerialPort::Listener::OnRead(int numBytesRead) {\r
+       queuedChars_ -= numBytesRead;\r
+       _ASSERT(queuedChars_ >= 0);\r
+\r
+       //just to be safe\r
+       queuedChars_ = max(queuedChars_, 0);\r
+\r
+       if(pProtocolStrategy_ != 0) {\r
+               //TODO: Convert from LATIN-1 codepage to wide chars\r
+               if(ConvertMultiByteToWideChar(pInputBuffer_, numBytesRead, wideRecvBuffer_)) {\r
+                       pProtocolStrategy_->Parse(wideRecvBuffer_.GetPtr(), wideRecvBuffer_.GetLength(), pPort_->pClientInfo_);\r
+               }\r
+               else {\r
+                       LOG << TEXT("Read failed, could not convert command to UNICODE") << LogStream::Flush;\r
+               }\r
+       }\r
+\r
+       ZeroMemory(pInputBuffer_, InputBufferSize);\r
+\r
+       return  (queuedChars_ > 0);\r
+}\r
+\r
+void SerialPort::Write(const tstring& str) {\r
+       if(pWriter_ != 0)\r
+               pWriter_->push_back(str);\r
+}\r
+\r
+void SerialPort::SerialPortClientInfo::Send(const tstring& data) {\r
+       pSerialPort_->Write(data);\r
+}\r
+\r
+SerialPort::Writer::Writer(HANDLE port) : port_(port), newStringEvent_(FALSE, FALSE) {\r
+}\r
+\r
+void SerialPort::Writer::push_back(const tstring& str) {\r
+       Lock lock(*this);\r
+\r
+       sendQueue_.push(str);\r
+       newStringEvent_.Set();\r
+}\r
+\r
+bool ConvertWideCharToLatin1(const std::wstring& wideString, caspar::utils::DataBuffer<char>& destBuffer)\r
+{\r
+       //28591 = ISO 8859-1 Latin I\r
+       int bytesWritten = 0;\r
+       int multibyteBufferCapacity = WideCharToMultiByte(28591, 0, wideString.c_str(), static_cast<int>(wideString.length()), 0, 0, NULL, NULL);\r
+       if(multibyteBufferCapacity > 0) \r
+       {\r
+               destBuffer.Realloc(multibyteBufferCapacity);\r
+               bytesWritten = WideCharToMultiByte(28591, 0, wideString.c_str(), static_cast<int>(wideString.length()), destBuffer.GetPtr(), destBuffer.GetCapacity(), NULL, NULL);\r
+       }\r
+       destBuffer.SetLength(bytesWritten);\r
+       return (bytesWritten > 0);\r
+}\r
+\r
+void SerialPort::Writer::Run(HANDLE stopEvent) {\r
+       OVERLAPPED overlappedWrite;\r
+       ZeroMemory(&overlappedWrite, sizeof(OVERLAPPED));\r
+       utils::Event overlappedWriteEvent(TRUE, FALSE);\r
+       overlappedWrite.hEvent = overlappedWriteEvent;\r
+       bool writePending = false;\r
+       int bytesToSend = 0;\r
+\r
+       caspar::utils::DataBuffer<char> currentlySending;\r
+       tstring currentlySendingString;\r
+       unsigned int currentlySendingOffset = 0;\r
+\r
+       HANDLE waitHandles[3] =  { stopEvent, newStringEvent_, overlappedWriteEvent };\r
+\r
+       while(true) {\r
+               HRESULT waitResult = WaitForMultipleObjects(3, waitHandles, FALSE, 2500);\r
+               if(waitResult == WAIT_TIMEOUT)\r
+                       continue;\r
+               else if(waitResult == WAIT_FAILED)\r
+                       break;\r
+\r
+               HRESULT currentEvent = waitResult - WAIT_OBJECT_0;\r
+               if(currentEvent == 0) {                 //stopEvent\r
+                       //TODO: Cancel ev. pending write?\r
+                       break;\r
+               }\r
+               else if(currentEvent == 1) {    //newStringEvent_\r
+                       if(!writePending) {\r
+                               if(currentlySending.GetLength() == 0)\r
+                               {\r
+                                       Lock lock(*this);\r
+                                       //Read the next string in the queue and convert to ISO 8859-1 LATIN-1\r
+                                       currentlySendingString = sendQueue_.front();\r
+                                       sendQueue_.pop();\r
+                                       if(!ConvertWideCharToLatin1(currentlySendingString, currentlySending))\r
+                                       {\r
+                                               LOG << TEXT("Send failed, could not convert response to ISO 8859-1") << LogStream::Flush;\r
+                                       }\r
+                                       currentlySendingOffset = 0;\r
+                               }\r
+\r
+                               if(currentlySending.GetLength() > 0) {\r
+                                       bytesToSend = static_cast<int>(currentlySending.GetLength()-currentlySendingOffset);\r
+                                       DWORD bytesWritten = 0;\r
+                                       if(!WriteFile(port_, currentlySending.GetPtr(currentlySendingOffset), bytesToSend, &bytesWritten, &overlappedWrite)) {\r
+                                               DWORD errorCode = GetLastError();\r
+                                               if(errorCode == ERROR_IO_PENDING) {\r
+                                                       writePending = true;\r
+                                               }\r
+                                               else {\r
+                                                       //TODO: Log and handle critical error\r
+                                                       LOG << TEXT("Failed to send, errorcode: ") << errorCode << LogStream::Flush;\r
+\r
+                                                       currentlySending.SetLength(0);\r
+                                                       currentlySendingOffset = 0;\r
+                                                       break;\r
+                                               }\r
+                                       }\r
+                                       else {  //WriteFile completed successfully\r
+                                               if(bytesToSend == bytesWritten) {\r
+                                                       currentlySending.SetLength(0);\r
+                                                       currentlySendingOffset = 0;\r
+\r
+                                                       LOG << LogLevel::Debug << TEXT("Sent serialdata (imediately): ") << currentlySendingString.c_str() << LogStream::Flush;\r
+                                               }\r
+                                               else {\r
+                                                       currentlySendingOffset += bytesWritten;\r
+                                                       newStringEvent_.Set();\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+               else if(currentEvent == 2) {    //overlappedWriteEvent\r
+                       overlappedWriteEvent.Reset();\r
+                       DWORD bytesWritten = 0;\r
+                       if(!GetOverlappedResult(port_, &overlappedWrite, &bytesWritten, FALSE)) {\r
+                               DWORD errorCode = GetLastError();\r
+                               LOG << TEXT("Failed to send, errorcode: ") << errorCode << LogStream::Flush;\r
+\r
+                               currentlySending.SetLength(0);\r
+                               currentlySendingOffset = 0;\r
+                               break;\r
+                       }\r
+                       else {\r
+                               writePending = false;\r
+                               if(bytesToSend == bytesWritten) {\r
+                                       currentlySending.SetLength(0);\r
+                                       currentlySendingOffset = 0;\r
+\r
+                                       LOG << LogLevel::Debug << TEXT("Sent serialdata (overlapped): ") << currentlySendingString.c_str() << LogStream::Flush;\r
+                                       {\r
+                                               Lock lock(*this);\r
+                                               if(sendQueue_.size() > 0)\r
+                                                       newStringEvent_.Set();\r
+                                       }\r
+                               }\r
+                               else {\r
+                                       currentlySendingOffset += bytesWritten;\r
+                                       newStringEvent_.Set();\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+}\r
+\r
+bool SerialPort::Writer::OnUnhandledException(const std::exception& ex) throw() {\r
+       bool bDoRestart = true;\r
+\r
+       try \r
+       {\r
+               LOG << LogLevel::Critical << TEXT("UNHANDLED EXCEPTION in serialport writer. Message: ") << ex.what() << LogStream::Flush;\r
+\r
+               //TODO: Cleanup and prepare for restart\r
+       }\r
+       catch(...)\r
+       {\r
+               bDoRestart = false;\r
+       }\r
+\r
+       return bDoRestart;\r
+}\r
+\r
+void LogCommError(const tstring& msg, int errorCode) {\r
+       TCHAR strNumber[65];\r
+       _itot_s(errorCode, strNumber, 10);\r
+       tstring error = msg;\r
+       error.append(strNumber);\r
+       LOG << error << LogStream::Flush;\r
+}\r
+\r
+}      //namespace IO\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/io/SerialPort.h b/server/io/SerialPort.h
new file mode 100644 (file)
index 0000000..b899639
--- /dev/null
@@ -0,0 +1,156 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+\r
+#include <string>\r
+#include <queue>\r
+#include "..\utils\thread.h"\r
+#include "..\utils\lockable.h"\r
+#include "ProtocolStrategy.h"\r
+#include "..\controller.h"\r
+#include "..\utils\databuffer.h"\r
+\r
+namespace caspar {\r
+namespace IO {\r
+\r
+class SerialPort : public caspar::IController\r
+{\r
+       class SerialPortClientInfo;\r
+       typedef std::tr1::shared_ptr<SerialPortClientInfo> SerialPortClientInfoPtr;\r
+       friend class SerialPortClientInfo;\r
+\r
+       class Listener;\r
+       typedef std::tr1::shared_ptr<Listener> ListenerPtr;\r
+       friend class Listener;\r
+\r
+       class Writer;\r
+       typedef std::tr1::shared_ptr<Writer> WriterPtr;\r
+       friend class Writer;\r
+\r
+       SerialPort(const SerialPort&);\r
+       SerialPort& operator=(const SerialPort&);\r
+\r
+public:\r
+       explicit SerialPort(DWORD baudRate, BYTE parity, BYTE dataBits, BYTE stopBits, const tstring& portName);\r
+       virtual ~SerialPort();\r
+\r
+       bool Start();\r
+       void Stop();\r
+\r
+       void SetProtocolStrategy(ProtocolStrategyPtr pPS) {\r
+               pProtocolStrategy_ = pPS;\r
+       }\r
+\r
+private:\r
+       void Setup();\r
+       void Write(const tstring&);\r
+\r
+       ProtocolStrategyPtr             pProtocolStrategy_;\r
+       tstring portName_;\r
+       HANDLE hPort_;\r
+       DCB commSettings_;\r
+\r
+       utils::Thread listenerThread_;\r
+       ListenerPtr pListener_;\r
+\r
+       utils::Thread writerThread_;\r
+       WriterPtr pWriter_;\r
+\r
+       SerialPortClientInfoPtr pClientInfo_;\r
+\r
+// Listener\r
+/////////////\r
+       class Listener : public utils::IRunnable\r
+       {\r
+               friend SerialPort;\r
+\r
+               Listener(const Listener&);\r
+               Listener& operator=(const Listener&);\r
+\r
+       public:\r
+               explicit Listener(SerialPort* pSerialPort, ProtocolStrategyPtr pPS);\r
+               virtual ~Listener();\r
+\r
+               void Run(HANDLE stopEvent);\r
+               bool OnUnhandledException(const std::exception& ex) throw();\r
+\r
+       private:\r
+               void ProcessStatusEvent(DWORD eventMask);\r
+               void DoRead();\r
+               bool OnRead(int numBytesRead);\r
+\r
+               static const int WaitTimeout;\r
+               static const int InputBufferSize;\r
+\r
+               SerialPort*                             pPort_;\r
+               ProtocolStrategyPtr             pProtocolStrategy_;\r
+\r
+               utils::Event            overlappedReadEvent_;\r
+               OVERLAPPED      overlappedRead_;\r
+               bool            bWaitingOnRead_;\r
+\r
+               char*           pInputBuffer_;\r
+               int                     queuedChars_;\r
+               utils::DataBuffer<wchar_t> wideRecvBuffer_;\r
+       };\r
+\r
+// Writer\r
+/////////////\r
+       class Writer : public utils::IRunnable, private utils::LockableObject\r
+       {\r
+       public:\r
+               Writer(HANDLE port);\r
+               virtual ~Writer() \r
+               {}\r
+\r
+       public:\r
+               void push_back(const tstring&);\r
+\r
+               void Run(HANDLE stopEvent);\r
+               bool OnUnhandledException(const std::exception& ex) throw();\r
+\r
+       private:\r
+               utils::Event newStringEvent_;\r
+               std::queue<tstring> sendQueue_;\r
+               HANDLE port_;\r
+       };\r
+\r
+// ClientInfo\r
+///////////////\r
+       class SerialPortClientInfo : public caspar::IO::ClientInfo\r
+       {\r
+               SerialPort* pSerialPort_;\r
+       public:\r
+               SerialPortClientInfo(SerialPort* pSP) : pSerialPort_(pSP) {\r
+               }\r
+               virtual ~SerialPortClientInfo() \r
+               {}\r
+\r
+               void Send(const tstring& data);\r
+               void Disconnect() \r
+               {}\r
+       };\r
+};\r
+\r
+typedef std::tr1::shared_ptr<SerialPort> SerialPortPtr;\r
+\r
+}      //namespace IO\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/io/SocketInfo.cpp b/server/io/SocketInfo.cpp
new file mode 100644 (file)
index 0000000..7387852
--- /dev/null
@@ -0,0 +1,63 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\stdafx.h"\r
+#include "SocketInfo.h"\r
+#include "AsyncEventServer.h"\r
+\r
+namespace caspar {\r
+namespace IO {\r
+\r
+SocketInfo::SocketInfo(SOCKET socket, AsyncEventServer* pServer) : socket_(socket), pServer_(pServer), recvLeftoverOffset_(0), currentlySendingOffset_(0)\r
+{\r
+       event_ = WSACreateEvent();\r
+       if(event_ == WSA_INVALID_EVENT) {\r
+               throw std::exception("Failed to create WSAEvent");\r
+       }\r
+}\r
+\r
+SocketInfo::~SocketInfo() {\r
+\r
+       WSACloseEvent(event_);\r
+       event_ = 0;\r
+\r
+       closesocket(socket_);\r
+       socket_ = 0;\r
+}\r
+\r
+void SocketInfo::Send(const tstring& data) {\r
+       if(pServer_ != 0 && data.length() > 0) {\r
+               {\r
+                       //The lock has to be let go before DoSend is called since that too tries to lock to object\r
+                       Lock lock(*this);\r
+                       sendQueue_.push(data);\r
+               }\r
+\r
+               pServer_->DoSend(*this);\r
+       }\r
+}\r
+\r
+void SocketInfo::Disconnect() {\r
+       if(pServer_)\r
+               pServer_->DisconnectClient(*this);\r
+}\r
+\r
+}      //namespace IO\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/io/SocketInfo.h b/server/io/SocketInfo.h
new file mode 100644 (file)
index 0000000..7c8693d
--- /dev/null
@@ -0,0 +1,63 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+\r
+#include "..\utils\lockable.h"\r
+#include "ClientInfo.h"\r
+#include <queue>\r
+#include <vector>\r
+#include "..\utils\databuffer.h"\r
+\r
+namespace caspar {\r
+namespace IO {\r
+\r
+class AsyncEventServer;\r
+class SocketInfo : public ClientInfo, private utils::LockableObject\r
+{\r
+       SocketInfo(const SocketInfo&);\r
+       SocketInfo& operator=(const SocketInfo&);\r
+\r
+public:\r
+       SocketInfo(SOCKET, AsyncEventServer*);\r
+       virtual ~SocketInfo();\r
+\r
+       void Send(const tstring& data);\r
+       void Disconnect();\r
+\r
+       SOCKET                  socket_;\r
+       HANDLE                  event_;\r
+       tstring host_;\r
+private:\r
+       friend class AsyncEventServer;\r
+       std::queue<tstring> sendQueue_;\r
+       AsyncEventServer* pServer_;\r
+\r
+       caspar::utils::DataBuffer<char> currentlySending_;\r
+       unsigned int currentlySendingOffset_;\r
+\r
+       caspar::utils::DataBuffer<wchar_t> wideRecvBuffer_;\r
+       char recvBuffer_[512];\r
+       int recvLeftoverOffset_;\r
+};\r
+typedef std::tr1::shared_ptr<SocketInfo> SocketInfoPtr;\r
+\r
+}      //namespace IO\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/producers/color/ColorManager.cpp b/server/producers/color/ColorManager.cpp
new file mode 100644 (file)
index 0000000..406ff5f
--- /dev/null
@@ -0,0 +1,160 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\..\stdafx.h"\r
+\r
+#include "ColorManager.h"\r
+#include "..\..\frame\FrameManager.h"\r
+#include "..\..\frame\buffers\StaticFrameBuffer.h"\r
+#include "..\..\frame\FrameMediaController.h"\r
+#include "..\..\utils\FileInputStream.h"\r
+#include "..\..\FileInfo.h"\r
+\r
+#include <intrin.h>\r
+#pragma intrinsic(__movsd, __stosd)\r
+#pragma intrinsic(__movsw, __stosw)\r
+\r
+void memset_w(unsigned short* pBuffer, unsigned short value, std::size_t count)\r
+{\r
+       __stosw(pBuffer, value, count);\r
+}\r
+\r
+void memset_d(unsigned long* pBuffer, unsigned long value, std::size_t count)\r
+{\r
+       __stosd(pBuffer, value, count);\r
+}\r
+\r
+namespace caspar {\r
+\r
+///////////////////////////////\r
+//  ColorProducer declaration\r
+//\r
+class ColorProducer : public MediaProducer, FrameMediaController\r
+{\r
+public:\r
+       explicit ColorProducer(unsigned long colorValue);\r
+       virtual ~ColorProducer();\r
+\r
+       virtual IMediaController* QueryController(const tstring& id);\r
+\r
+       virtual bool Initialize(FrameManagerPtr pFrameManager);\r
+       virtual FrameBuffer& GetFrameBuffer() {\r
+               return frameBuffer_;\r
+       }\r
+\r
+       virtual bool IsEmpty() const\r
+       {\r
+               return colorValue_ == 0;\r
+       }\r
+\r
+private:\r
+       StaticFrameBuffer frameBuffer_;\r
+       unsigned long colorValue_;\r
+};\r
+\r
+union Color {\r
+       struct Components {\r
+               unsigned char a;\r
+               unsigned char r;\r
+               unsigned char g;\r
+               unsigned char b;\r
+       } comp;\r
+\r
+       unsigned long value;\r
+};\r
+\r
+//////////////////////////////\r
+//  ColorManager definition\r
+//\r
+MediaProducerPtr ColorManager::CreateProducer(const tstring& parameter)\r
+{\r
+       MediaProducerPtr result;\r
+       if(parameter[0] == '#') {\r
+               unsigned long value;\r
+               if(GetPixelColorValueFromString(parameter, &value))\r
+                       result = MediaProducerPtr(new ColorProducer(value));\r
+       }\r
+\r
+       return result;\r
+}\r
+\r
+bool ColorManager::getFileInfo(FileInfo* pFileInfo)\r
+{\r
+       if(pFileInfo != 0) {\r
+               pFileInfo->length = 1;\r
+               pFileInfo->type = TEXT("still");\r
+               pFileInfo->encoding = TEXT("NA");\r
+               return true;\r
+       }\r
+       return false;\r
+}\r
+\r
+bool ColorManager::GetPixelColorValueFromString(const tstring& parameter, unsigned long* outValue)\r
+{\r
+       tstring colorCode;\r
+       if(parameter.length() == 9 && parameter[0] == '#')\r
+       {\r
+               colorCode = parameter.substr(1);\r
+\r
+               Color theCol;\r
+               theCol.value = _tcstoul(colorCode.c_str(),0,16);\r
+               unsigned char temp = theCol.comp.a;\r
+               theCol.comp.a = theCol.comp.b;\r
+               theCol.comp.b = temp;\r
+               temp = theCol.comp.r;\r
+               theCol.comp.r = theCol.comp.g;\r
+               theCol.comp.g = temp;\r
+\r
+               *outValue = theCol.value;\r
+               return true;\r
+       }\r
+       return false;\r
+}\r
+\r
+\r
+///////////////////////////////\r
+//  ColorProducer definition\r
+//\r
+ColorProducer::ColorProducer(unsigned long colorValue) : colorValue_(colorValue) {\r
+}\r
+\r
+ColorProducer::~ColorProducer() {\r
+}\r
+\r
+IMediaController* ColorProducer::QueryController(const tstring& id) {\r
+       if(id == TEXT("FrameController"))\r
+               return this;\r
+       \r
+       return 0;\r
+}\r
+\r
+bool ColorProducer::Initialize(FrameManagerPtr pFrameManager) {\r
+       if(pFrameManager != 0) {\r
+               FramePtr pFrame = pFrameManager->CreateFrame();\r
+               if(pFrame != 0) {\r
+                       memset_d(reinterpret_cast<unsigned long*>(pFrame->GetDataPtr()), colorValue_, pFrame->GetDataSize() / sizeof(unsigned long));\r
+                       frameBuffer_.push_back(pFrame);\r
+                       return true;\r
+               }\r
+       }\r
+       return false;\r
+}\r
+\r
+}
\ No newline at end of file
diff --git a/server/producers/color/ColorManager.h b/server/producers/color/ColorManager.h
new file mode 100644 (file)
index 0000000..8a01542
--- /dev/null
@@ -0,0 +1,44 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+\r
+#include "..\..\MediaManager.h"\r
+#include "..\..\MediaProducer.h"\r
+\r
+#include <string>\r
+\r
+namespace caspar {\r
+\r
+class FileInfo;\r
+\r
+class ColorManager : public IMediaManager\r
+{\r
+public:\r
+       ColorManager() {}\r
+       virtual ~ColorManager() {}\r
+\r
+       virtual MediaProducerPtr CreateProducer(const tstring& parameter);\r
+       virtual bool getFileInfo(FileInfo* pFileInfo);\r
+\r
+       static bool GetPixelColorValueFromString(const tstring& parameter, unsigned long* outValue);\r
+};\r
+\r
+}      //namespace caspar\r
diff --git a/server/producers/composites/FrameCompositeProducer.cpp b/server/producers/composites/FrameCompositeProducer.cpp
new file mode 100644 (file)
index 0000000..5362745
--- /dev/null
@@ -0,0 +1,123 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\..\StdAfx.h"\r
+\r
+#include "FrameCompositeProducer.h"\r
+#include "..\..\SystemFrameManager.h"\r
+#include "..\..\transitioninfo.h"\r
+\r
+namespace caspar {\r
+\r
+FrameCompositeProducer::FrameCompositeProducer() : pCompositionStrategy_(0), currentFrameIndex_(0) {\r
+       pIntermediateFrameManager_.reset(new SystemFrameManager(fmtDesc));\r
+}\r
+\r
+FrameCompositeProducerPtr FrameCompositeProducer::CreateOverlayComposite() {\r
+       FrameCompositeProducerPtr result;\r
+       return result;\r
+}\r
+\r
+FrameCompositeProducerPtr FrameCompositeProducer::CreateTransitionComposite(const TransitionInfo& transitionInfo) {\r
+       FrameCompositeProducerPtr result;\r
+       return result;\r
+}\r
+\r
+FrameCompositeProducer::~FrameCompositeProducer() {\r
+       worker_.Stop();\r
+\r
+       if(pCompositionStrategy_ != 0) {\r
+               delete pCompositionStrategy_;\r
+               pCompositionStrategy_ = 0;\r
+       }\r
+}\r
+\r
+//MediaProducer\r
+IMediaController* FrameCompositeProducer::QueryController(const tstring& id) {\r
+       if(id == TEXT("FrameController")) {\r
+               return this;\r
+       }\r
+       return 0;\r
+}\r
+\r
+MediaProducerPtr FrameCompositeProducer::GetFollowingProducer() {\r
+}\r
+\r
+//FrameMediaController\r
+bool FrameCompositeProducer::Initialize(FrameManagerPtr pFrameManager) {\r
+}\r
+\r
+\r
+//IRunnable\r
+void FrameCompositeProducer::Run(HANDLE stopEvent) {\r
+       LOG << LogLevel::Verbose << TEXT("Composition: readAhead thread started");\r
+\r
+       const DWORD waitHandlesCount = 2;\r
+       HANDLE waitHandles[waitHandlesCount] = { stopEvent, frameBuffer_.GetWriteWaitHandle() };\r
+\r
+       bool bQuit = false;\r
+       while(!bQuit) {\r
+               HRESULT waitResult = WaitForMultipleObjects(waitHandlesCount, waitHandles, FALSE, 2000);\r
+               switch(waitResult) \r
+               {\r
+               //stopEvent\r
+               case (WAIT_OBJECT_0):\r
+                       bQuit = true;\r
+                       break;\r
+\r
+               //write possible\r
+               case (WAIT_OBJECT_O+1):\r
+                       if(pCompositionStrategy_ != 0) {\r
+                               if(pCompositionStrategy_->GenerateFrame(stopEvent, currentFrameIndex_)) {\r
+                                       ++currentFrameIndex_;\r
+                               }\r
+                       }\r
+                       break;\r
+\r
+               case (WAIT_TIMEOUT):\r
+                       break;\r
+\r
+               default:\r
+                       LOG << LogLevel::Critical << TEXT("Composition: write-wait failed. Aborting");\r
+                       bQuit = true;\r
+                       break:\r
+               }\r
+       }\r
+\r
+       FramePtr pNullFrame;\r
+       frameBuffer_.push_back(pNullFrame);\r
+       LOG << LogLevel::Verbose << TEXT("Composition: readAhead thread ended");\r
+}\r
+\r
+bool FrameCompositeProducer::OnUnhandledException(const std::exception& ex) throw() {\r
+       try \r
+       {\r
+               FramePtr pNullFrame;\r
+               frameBuffer_.push_back(pNullFrame);\r
+\r
+               LOG << LogLevel::Critical << TEXT("UNHANDLED EXCEPTION in compositionthread. Message: ") << ex.what();\r
+       }\r
+       catch(...)\r
+       {}\r
+\r
+       return false;\r
+}\r
+\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/producers/composites/FrameCompositeProducer.h b/server/producers/composites/FrameCompositeProducer.h
new file mode 100644 (file)
index 0000000..2b6a557
--- /dev/null
@@ -0,0 +1,73 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+\r
+#include "..\..\MediaProducer.h"\r
+#include "..\..\FrameManager.h"\r
+#include "..\..\FrameMediaController.h"\r
+#include "..\..\SystemFrameManager.h"\r
+#include "..\..\utils\thread.h"\r
+\r
+namespace caspar {\r
+\r
+class TransitionInfo;\r
+\r
+class IFrameCompositionStrategy\r
+{\r
+public:\r
+       bool GenerateFrame(HANDLE stopEvent, unsigned int frameIndex) = 0;\r
+};\r
+\r
+class FrameCompositeProducer : public MediaProducer, public FrameMediaController, public utils::IRunnable\r
+{\r
+       FrameCompositeProducer();\r
+\r
+public:\r
+       static FrameCompositeProducerPtr CreateOverlayComposite();\r
+       static FrameCompositeProducerPtr CreateTransitionComposite(const TransitionInfo& transitionInfo);\r
+       virtual ~FrameCompositeProducer();\r
+\r
+       //MediaProducer\r
+       virtual IMediaController* QueryController(const tstring& id);\r
+       virtual MediaProducerPtr GetFollowingProducer();\r
+\r
+       //FrameMediaController\r
+       virtual bool Initialize(FrameManagerPtr pFrameManager);\r
+       virtual FrameBuffer& GetFrameBuffer() {\r
+               return frameBuffer_;\r
+       }\r
+\r
+       //IRunnable\r
+       virtual void Run(HANDLE stopEvent);\r
+       virtual bool OnUnhandledException(const std::exception& ex) throw();\r
+\r
+private:\r
+       IFrameCompositionStrategy* pCompositionStrategy_;\r
+       unsigned int currentFrameIndex_;\r
+\r
+       FrameManagerPtr                 pResultFrameManager_;\r
+       SystemFrameManagerPtr   pIntermediateFrameManager_;\r
+\r
+       utils::Thread worker_;\r
+       MotionFrameBuffer frameBuffer_;\r
+};\r
+\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/producers/composites/TransitionProducer.cpp b/server/producers/composites/TransitionProducer.cpp
new file mode 100644 (file)
index 0000000..70a7916
--- /dev/null
@@ -0,0 +1,529 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\..\stdafx.h"\r
+\r
+#include <math.h>\r
+#include <algorithm>\r
+#include <functional>\r
+\r
+#include "TransitionProducer.h"\r
+#include "..\..\application.h"\r
+#include "..\..\utils\pixmapdata.h"\r
+#include "..\..\utils\image\image.hpp"\r
+#include "..\..\utils\thread.h"\r
+#include "..\..\frame\clipinfo.h"\r
+#include "..\..\transitioninfo.h"\r
+#include "..\..\utils\taskqueue.h"\r
+#include "..\..\frame\buffers\MotionFrameBuffer.h"\r
+\r
+namespace caspar\r
+{\r
+\r
+using namespace utils;\r
+\r
+struct TransitionProducer::Implementation\r
+{\r
+       TransitionProducer*             self_;\r
+\r
+       FrameManagerPtr                 pResultFrameManager_;\r
+       SystemFrameManagerPtr   pIntermediateFrameManager_;\r
+       ClipInfo                                sourceClip_;\r
+       ClipInfo                                destinationClip_;\r
+       std::vector<HANDLE>             readWaitHandles_;\r
+\r
+       unsigned short                  totalFrames_, currentFrame_;\r
+\r
+       std::tr1::function<void (Implementation*, unsigned char*, unsigned char*, unsigned char*)> generateFrameFun_;\r
+\r
+       TransitionInfo                  transitionInfo_;\r
+       unsigned long                   borderColorValue_;\r
+       utils::PixmapDataPtr    pBorderImage_;\r
+\r
+       utils::Thread worker_;\r
+       utils::TaskQueue taskQueue_;\r
+       MotionFrameBuffer frameBuffer_;\r
+\r
+       Implementation(TransitionProducer*      self, MediaProducerPtr pDest, const TransitionInfo& transitionInfo, const FrameFormatDescription& fmtDesc)\r
+       :       \r
+       self_(self), \r
+       totalFrames_(transitionInfo.duration_+1), \r
+       currentFrame_(1),\r
+       transitionInfo_(transitionInfo), \r
+       borderColorValue_(0)\r
+       {\r
+               pIntermediateFrameManager_.reset(new SystemFrameManager(fmtDesc));\r
+\r
+               if(pDest != 0) {\r
+                       FrameMediaController* pDestFrameController = dynamic_cast<FrameMediaController*>(pDest->QueryController(TEXT("FrameController")));\r
+                       destinationClip_ = ClipInfo(pDest, pDestFrameController);\r
+                       if(!destinationClip_.IsEmpty())\r
+                               readWaitHandles_.push_back(destinationClip_.pFrameController_->GetFrameBuffer().GetWaitHandle());\r
+               }\r
+\r
+               switch(transitionInfo_.type_) {\r
+               case Slide:\r
+               case Push:\r
+               case Wipe:\r
+                       generateFrameFun_ = &Implementation::GenerateWipeFrame;\r
+                       break;\r
+               case Mix:\r
+               default:\r
+                       generateFrameFun_ = &Implementation::GenerateMixFrame;\r
+                       break;\r
+               };\r
+       }\r
+\r
+       ~Implementation() \r
+       {\r
+               worker_.Stop();\r
+       }\r
+\r
+\r
+       IMediaController* QueryController(const tstring& id) \r
+       {\r
+               //The transition only supports FrameController if its destination also supports it\r
+               if(!destinationClip_.IsEmpty()) {\r
+                       if(id == TEXT("FrameController")) {\r
+                               return self_;\r
+                       }\r
+               }\r
+               return NULL;\r
+       }\r
+\r
+       MediaProducerPtr GetFollowingProducer() \r
+       {\r
+               return destinationClip_.pFP_;\r
+       }\r
+\r
+       bool Initialize(FrameManagerPtr pFrameManager)\r
+       {\r
+               if(pFrameManager) {\r
+                       if(!worker_.IsRunning()) {\r
+                               pResultFrameManager_ = pFrameManager;\r
+                               if(pResultFrameManager_ != 0 && !destinationClip_.IsEmpty()) {\r
+                                       //Cue audio for destination clip\r
+                                       GetApplication()->GetAudioManager()->CueAudio(destinationClip_.pFrameController_);\r
+\r
+                                       return destinationClip_.pFrameController_->Initialize(pIntermediateFrameManager_);\r
+                               }\r
+                       }\r
+                       else {\r
+                               //Create a task that replace pResultFrameManager_ but is executed in the worker thread\r
+                               taskQueue_.push_back(bind(&TransitionProducer::Implementation::DoUpdateFrameManager, this, pFrameManager));\r
+                               return true;\r
+                       }\r
+               }\r
+               return false;\r
+       }\r
+\r
+       void DoUpdateFrameManager(FrameManagerPtr pFrameManager) {\r
+               pResultFrameManager_ = pFrameManager;\r
+       }\r
+\r
+       FrameBuffer& GetFrameBuffer() \r
+       {\r
+               return frameBuffer_;\r
+       }\r
+\r
+       bool Start(const ClipInfo& srcClipInfo) \r
+       {\r
+               sourceClip_ = srcClipInfo;\r
+               if(!sourceClip_.IsEmpty() && !destinationClip_.IsEmpty()) {\r
+                       if(sourceClip_.pFrameController_->Initialize(pIntermediateFrameManager_)) {\r
+                               readWaitHandles_.push_back(sourceClip_.pFrameController_->GetFrameBuffer().GetWaitHandle());\r
+\r
+                               //AUDIO\r
+                               {\r
+                                       //copy all workers from the source to this\r
+                                       self_->GetSoundBufferWorkers().insert(self_->GetSoundBufferWorkers().end(), sourceClip_.pFrameController_->GetSoundBufferWorkers().begin(), sourceClip_.pFrameController_->GetSoundBufferWorkers().end());\r
+\r
+                                       //copy all workers from the destination to this\r
+                                       self_->GetSoundBufferWorkers().insert(self_->GetSoundBufferWorkers().end(), destinationClip_.pFrameController_->GetSoundBufferWorkers().begin(), destinationClip_.pFrameController_->GetSoundBufferWorkers().end());\r
+                               }\r
+\r
+                               return worker_.Start(self_);\r
+                       }\r
+               }\r
+               return false;\r
+       }\r
+\r
+       void Run(HANDLE stopEvent)\r
+       {\r
+               LOG << LogLevel::Verbose << TEXT("Transition: readAhead thread started");\r
+               currentFrame_ = 1;\r
+\r
+               HANDLE waitHandles[3] = { stopEvent, taskQueue_.GetWaitEvent(), frameBuffer_.GetWriteWaitHandle() };\r
+               DWORD waitHandlesCount = sizeof(waitHandles) / sizeof(HANDLE);\r
+\r
+               bool bQuit = false;\r
+               while(bQuit == false && currentFrame_ <= totalFrames_) {\r
+                       HRESULT waitResult = WaitForMultipleObjects(waitHandlesCount, waitHandles, FALSE, 2000);\r
+                       switch(waitResult) {\r
+                               case WAIT_OBJECT_0:\r
+                                       LOG << LogLevel::Debug << TEXT("Transition: Recieved stopEvent");\r
+                                       bQuit = true;\r
+                                       break;\r
+\r
+                               case WAIT_OBJECT_0+1:\r
+                                       taskQueue_.pop_and_execute_front();\r
+                                       break;\r
+\r
+                               case WAIT_OBJECT_0+2:\r
+                                       {\r
+                                               bool bWriteSuccess = false;\r
+                                               if(WriteFrame(bWriteSuccess)) {\r
+                                                       if(bWriteSuccess)\r
+                                                               ++currentFrame_;\r
+                                               }\r
+                                               else {\r
+                                                       LOG << TEXT("Transition: WriteFrame returned false. Abort transition");\r
+                                                       bQuit = true;\r
+                                               }\r
+                                       }\r
+                                       break;\r
+\r
+                               case WAIT_TIMEOUT:\r
+                                       break;\r
+\r
+                               default:\r
+                                       LOG << LogLevel::Critical << TEXT("Transition: write-wait failed. Aborting");\r
+                                       bQuit = true;\r
+                                       break;\r
+                       }\r
+               }\r
+\r
+               //ALMOST SAME BUT OLD: This does not include a complete frame from the destination as the last frame\r
+/*             for(currentFrame_ = 1; currentFrame_< totalFrames_; ++currentFrame_) {\r
+                       HRESULT waitResult = WaitForMultipleObjects(waitHandlesCount, waitHandles, FALSE, 2000);\r
+                       if(waitResult == (WAIT_OBJECT_0+2)) {\r
+                               if(!WriteFrame()) {\r
+                                       LOG << LogLevel::Debug << TEXT("Transition: WriteFrame returned false. Abort transition");\r
+                                       break;\r
+                               }\r
+                       }\r
+                       else if(waitResult == WAIT_OBJECT_0 + 1) {\r
+                               --currentFrame_;\r
+\r
+                               Task task;\r
+                               taskQueue_.pop_front(task);\r
+                               if(task)\r
+                                       task();\r
+                       }\r
+                       else if(waitResult == WAIT_OBJECT_0) {\r
+                               LOG << LogLevel::Debug << TEXT("Transition: Recieved stopEvent");\r
+                               break;\r
+                       }\r
+                       else if(waitResult == WAIT_TIMEOUT) {\r
+                               //retry the same frame\r
+                               --currentFrame_;\r
+                       }\r
+                       else {\r
+                               //Iiik, Critical error\r
+                               LOG << LogLevel::Critical << TEXT("Transition: write-wait failed. Aborting");\r
+                               break;\r
+                       }\r
+               }*/\r
+\r
+               FramePtr pNullFrame;\r
+               frameBuffer_.push_back(pNullFrame);\r
+               LOG << LogLevel::Verbose << TEXT("Transition: readAhead thread ended");\r
+       }\r
+\r
+       bool OnUnhandledException(const std::exception& ex) throw() \r
+       {\r
+               try \r
+               {\r
+                       FramePtr pNullFrame;\r
+                       frameBuffer_.push_back(pNullFrame);\r
+\r
+                       LOG << LogLevel::Critical << TEXT("UNHANDLED EXCEPTION in transitionthread. Message: ") << ex.what();\r
+               }\r
+               catch(...)\r
+               {}\r
+\r
+               return false;\r
+       }\r
+\r
+       bool WriteFrame(bool &bWriteSuccess) \r
+       {\r
+               //Wait for source-feeds\r
+               HRESULT waitResult = WAIT_OBJECT_0;\r
+               if(readWaitHandles_.size() > 0)\r
+                       waitResult = WaitForMultipleObjects(static_cast<DWORD>(readWaitHandles_.size()), &(readWaitHandles_[0]), TRUE, 250);\r
+\r
+               switch(waitResult) \r
+               {\r
+                       case WAIT_OBJECT_0:                     \r
+                               if(DoWriteFrame())\r
+                                       bWriteSuccess = true;\r
+                               else\r
+                                       return false;\r
+                               break;\r
+\r
+                       case WAIT_TIMEOUT:\r
+                               Sleep(0);\r
+                               break;\r
+\r
+                       default:        //An error occured\r
+                               LOG << LogLevel::Critical << TEXT("Transition: read-wait failed. Aborting");\r
+                               return false;\r
+               }\r
+\r
+               return true;\r
+       }\r
+\r
+       bool DoWriteFrame()\r
+       {\r
+               FrameBuffer& srcFrameBuffer = sourceClip_.pFrameController_->GetFrameBuffer();\r
+               FrameBuffer& destFrameBuffer = destinationClip_.pFrameController_->GetFrameBuffer();\r
+\r
+               //Make member of ClipInfo\r
+               FramePtr pSrcFrame =  (sourceClip_.lastFetchResult_ == FetchEOF) ? sourceClip_.pLastFrame_ : srcFrameBuffer.front();\r
+               FramePtr pDestFrame = (destinationClip_.lastFetchResult_ == FetchEOF)? destinationClip_.pLastFrame_ : destFrameBuffer.front();\r
+\r
+               //Bail if no data is availible\r
+               if(pSrcFrame == 0 || pDestFrame == 0) \r
+               {\r
+                       LOG << LogLevel::Debug << TEXT("Transition: WriteFrame(): GetFrameBuffer().front() returned null");\r
+                       return false;\r
+               }\r
+\r
+               FramePtr pResultFrame = pResultFrameManager_->CreateFrame();\r
+               if(pResultFrame != 0 && pResultFrame->GetDataPtr() != 0) \r
+               {\r
+                       generateFrameFun_(this, pResultFrame->GetDataPtr(), pSrcFrame->GetDataPtr(), pDestFrame->GetDataPtr());\r
+                       //AUDIO\r
+                       {\r
+                               //copy all sounddatachunks from source\r
+                               pResultFrame->GetAudioData().insert(pResultFrame->GetAudioData().end(), pSrcFrame->GetAudioData().begin(), pSrcFrame->GetAudioData().end());\r
+\r
+                               //copy sounddatachunk from destination\r
+                               pResultFrame->GetAudioData().insert(pResultFrame->GetAudioData().end(), pDestFrame->GetAudioData().begin(), pDestFrame->GetAudioData().end());\r
+                       }\r
+\r
+                       frameBuffer_.push_back(pResultFrame);\r
+\r
+                       if(sourceClip_.lastFetchResult_ != FetchEOF) \r
+                       {\r
+                               sourceClip_.pLastFrame_                 = pSrcFrame;\r
+                               sourceClip_.lastFetchResult_    = srcFrameBuffer.pop_front();\r
+\r
+                               //remove from readWaitHandles\r
+                               if(sourceClip_.lastFetchResult_ == FetchEOF)                                                    \r
+                                       readWaitHandles_.erase(std::find(readWaitHandles_.begin(), readWaitHandles_.end(), srcFrameBuffer.GetWaitHandle()));            \r
+                       }\r
+\r
+                       if(destinationClip_.lastFetchResult_ != FetchEOF)\r
+                       {\r
+                               destinationClip_.pLastFrame_            = pDestFrame;\r
+                               destinationClip_.lastFetchResult_       = destFrameBuffer.pop_front();\r
+\r
+                               //remove from readWaitHandles\r
+                               if(destinationClip_.lastFetchResult_ == FetchEOF)                                                       \r
+                                       readWaitHandles_.erase(std::find(readWaitHandles_.begin(), readWaitHandles_.end(), destFrameBuffer.GetWaitHandle()));                                                                   \r
+                       }\r
+               }\r
+               else \r
+               {\r
+                       Sleep(0);\r
+               }               \r
+\r
+               return true;\r
+       }\r
+\r
+       /////////////////////////////\r
+       // Frame-generating functions\r
+       void GenerateMixFrame(unsigned char* pResultData, unsigned char* pSourceData, unsigned char* pDestData)\r
+       {\r
+               image::Lerp(pResultData, pSourceData, pDestData, 1.0f-static_cast<float>(currentFrame_)/static_cast<float>(totalFrames_), pResultFrameManager_->GetFrameFormatDescription().size);\r
+       }\r
+\r
+       // TODO: Move into "image" library, seperate push, slide, wipe? (R.N)\r
+       void GenerateWipeFrame(unsigned char* pResultData, unsigned char* pSourceData, unsigned char* pDestData)\r
+       {\r
+               const FrameFormatDescription& fmtDesc = pResultFrameManager_->GetFrameFormatDescription();\r
+\r
+               if(currentFrame_ < totalFrames_) {\r
+                       int totalWidth = fmtDesc.width + transitionInfo_.borderWidth_;\r
+                       \r
+                       float fStep   = totalWidth / (float)totalFrames_;\r
+                       float fOffset = fStep * (float)currentFrame_;\r
+\r
+                       int halfStep = static_cast<int>(fStep/2.0);\r
+                       int offset   = static_cast<int>(fOffset+0.5f);\r
+                       \r
+                       //read source to buffer\r
+                       for(int row = 0, even = 0; row < fmtDesc.height; ++row, even ^= 1)\r
+                       {\r
+                               int fieldCorrectedOffset = offset + (halfStep*even);\r
+                               if(fieldCorrectedOffset < fmtDesc.width)\r
+                               {\r
+                                       if(transitionInfo_.direction_ != FromLeft)\r
+                                       {\r
+                                               if(transitionInfo_.type_ == Push)\r
+                                                       memcpy(&(pResultData[4*row*fmtDesc.width]), &(pSourceData[4*(row*fmtDesc.width+fieldCorrectedOffset)]), (fmtDesc.width-fieldCorrectedOffset)*4);\r
+                                               else    //Slide | Wipe\r
+                                                       memcpy(&(pResultData[4*row*fmtDesc.width]), &(pSourceData[4*row*fmtDesc.width]), (fmtDesc.width-fieldCorrectedOffset)*4);\r
+                                       }\r
+                                       else // if (direction == LEFT)\r
+                                       {                               \r
+                                               if(transitionInfo_.type_ == Push)\r
+                                                       memcpy(&(pResultData[4*(row*fmtDesc.width+fieldCorrectedOffset)]), &(pSourceData[4*(row*fmtDesc.width)]), (fmtDesc.width-fieldCorrectedOffset)*4);\r
+                                               else    //slide eller wipe\r
+                                                       memcpy(&(pResultData[4*(row*fmtDesc.width+fieldCorrectedOffset)]), &(pSourceData[4*(row*fmtDesc.width+fieldCorrectedOffset)]), (fmtDesc.width-fieldCorrectedOffset)*4);\r
+                                       }\r
+                               }\r
+                       }\r
+\r
+                       //write border to buffer\r
+                       if(transitionInfo_.borderWidth_ > 0)\r
+                       {\r
+                               for(int row = 0, even = 0; row < fmtDesc.height; ++row, even ^= 1)\r
+                               {\r
+                                       int fieldCorrectedOffset = offset + (halfStep*even);\r
+                                       int length = transitionInfo_.borderWidth_;\r
+                                       int start = 0;\r
+\r
+                                       if(transitionInfo_.direction_ != FromLeft)\r
+                                       {\r
+                                               if(fieldCorrectedOffset > fmtDesc.width)\r
+                                               {\r
+                                                       length -= fieldCorrectedOffset-fmtDesc.width;\r
+                                                       start += fieldCorrectedOffset-fmtDesc.width;\r
+                                                       fieldCorrectedOffset = fmtDesc.width;\r
+                                               }\r
+                                               else if(fieldCorrectedOffset < length)\r
+                                               {\r
+                                                       length = fieldCorrectedOffset;\r
+                                               }\r
+\r
+                                               if(pBorderImage_ != 0)\r
+                                               {\r
+                                                       unsigned char* pBorderImageData = pBorderImage_->GetDataPtr();\r
+                                                       memcpy(&(pResultData[4*(row*fmtDesc.width+fmtDesc.width-fieldCorrectedOffset)]), &(pBorderImageData[4*(row*pBorderImage_->width+start)]), length*4);\r
+                                               }\r
+                                               else\r
+                                               {\r
+                                                       for(int i=0;i<length;++i)\r
+                                                               memcpy(&(pResultData[4*(row*fmtDesc.width+fmtDesc.width-fieldCorrectedOffset+i)]), &borderColorValue_, 4);\r
+                                               }\r
+                                       }\r
+                                       else // if (direction == LEFT)\r
+                                       {\r
+                                               if(fieldCorrectedOffset > fmtDesc.width)\r
+                                               {\r
+                                                       length -= fieldCorrectedOffset-fmtDesc.width;\r
+                                                       start = 0;\r
+                                                       fieldCorrectedOffset -= transitionInfo_.borderWidth_-length;\r
+                                               }\r
+                                               else if(fieldCorrectedOffset < length)\r
+                                               {\r
+                                                       length = fieldCorrectedOffset;\r
+                                                       start = transitionInfo_.borderWidth_-fieldCorrectedOffset;\r
+                                               }\r
+\r
+                                               if(pBorderImage_ != 0 && length > 0)\r
+                                               {\r
+                                                       unsigned char* pBorderImageData = pBorderImage_->GetDataPtr();\r
+                                                       memcpy(&(pResultData[4*(row*fmtDesc.width+fieldCorrectedOffset-length)]), &(pBorderImageData[4*(row*pBorderImage_->width+start)]), length*4);\r
+                                               }\r
+                                               else\r
+                                               {\r
+                                                       for(int i=0;i<length;++i)\r
+                                                               memcpy(&(pResultData[4*(row*fmtDesc.width+fieldCorrectedOffset-length+i)]), &borderColorValue_, 4);\r
+                                               }\r
+                                       }\r
+\r
+                               }\r
+                       }\r
+\r
+                       //read dest to buffer\r
+                       offset -= transitionInfo_.borderWidth_;\r
+                       if(offset > 0)\r
+                       {\r
+                               for(int row = 0, even = 0; row < fmtDesc.height; ++row, even ^= 1)\r
+                               {\r
+                                       int fieldCorrectedOffset = offset + (halfStep*even);\r
+\r
+                                       if(transitionInfo_.direction_ != FromLeft)\r
+                                       {\r
+                                               if(transitionInfo_.type_ == Wipe)\r
+                                                       memcpy(&(pResultData[4*(row*fmtDesc.width+fmtDesc.width-fieldCorrectedOffset)]), &(pDestData[4*(row*fmtDesc.width+fmtDesc.width-fieldCorrectedOffset)]), fieldCorrectedOffset*4);\r
+                                               else\r
+                                                       memcpy(&(pResultData[4*(row*fmtDesc.width+fmtDesc.width-fieldCorrectedOffset)]), &(pDestData[4*row*fmtDesc.width]), fieldCorrectedOffset*4);\r
+                                       }\r
+                                       else // if (direction == LEFT)\r
+                                       {                               \r
+                                               if(transitionInfo_.type_ == Wipe)\r
+                                                       memcpy(&(pResultData[4*(row*fmtDesc.width)]), &(pDestData[4*(row*fmtDesc.width)]), fieldCorrectedOffset*4);\r
+                                               else\r
+                                                       memcpy(&(pResultData[4*(row*fmtDesc.width)]), &(pDestData[4*(row*fmtDesc.width+fmtDesc.width-fieldCorrectedOffset)]), fieldCorrectedOffset*4);  \r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+               else {\r
+                       //currentFrame_ == totalFrames_\r
+                       image::Copy(pResultData, pDestData, fmtDesc.size);\r
+               }\r
+       }\r
+};\r
+\r
+\r
+TransitionProducer::TransitionProducer(MediaProducerPtr pDest, const TransitionInfo& transitionInfo, const FrameFormatDescription& fmtDesc) : pImpl_(new Implementation(this, pDest, transitionInfo, fmtDesc)){}\r
+TransitionProducer::~TransitionProducer() {}\r
+\r
+IMediaController* TransitionProducer::QueryController(const tstring& id)\r
+{\r
+       return pImpl_->QueryController(id);\r
+}\r
+\r
+MediaProducerPtr TransitionProducer::GetFollowingProducer() \r
+{\r
+       return pImpl_->GetFollowingProducer();\r
+}\r
+\r
+bool TransitionProducer::Initialize(FrameManagerPtr pFrameManager) \r
+{\r
+       return pImpl_->Initialize(pFrameManager);\r
+}\r
+\r
+FrameBuffer& TransitionProducer::GetFrameBuffer() \r
+{\r
+       return pImpl_->GetFrameBuffer();\r
+}\r
+\r
+bool TransitionProducer::Start(const ClipInfo& srcClipInfo) \r
+{\r
+       return pImpl_->Start(srcClipInfo);\r
+}\r
+\r
+void TransitionProducer::Run(HANDLE stopEvent)\r
+{\r
+       pImpl_->Run(stopEvent);\r
+}\r
+\r
+bool TransitionProducer::OnUnhandledException(const std::exception& ex) throw()\r
+{\r
+       return pImpl_->OnUnhandledException(ex);\r
+}\r
+\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/producers/composites/TransitionProducer.h b/server/producers/composites/TransitionProducer.h
new file mode 100644 (file)
index 0000000..d06007c
--- /dev/null
@@ -0,0 +1,77 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+\r
+#include "..\..\MediaProducer.h"\r
+#include "..\..\frame\FrameManager.h"\r
+#include "..\..\frame\FrameMediaController.h"\r
+#include "..\..\frame\SystemFrameManager.h"\r
+#include "..\..\utils\runnable.h"\r
+#include "..\..\utils\Noncopyable.hpp"\r
+\r
+#include <vector>\r
+\r
+namespace caspar {\r
+\r
+       class ClipInfo;\r
+       class TransitionInfo;\r
+\r
+namespace utils {\r
+       class PixmapData;\r
+       typedef std::tr1::shared_ptr<PixmapData> PixmapDataPtr;\r
+}\r
+\r
+// TODO: Put into its own header? (R.N)\r
+class ITransitionController\r
+{\r
+public:\r
+       virtual bool Start(const ClipInfo& srcClipInfo) = 0;\r
+};\r
+\r
+class TransitionProducer : public MediaProducer, public FrameMediaController, public ITransitionController, public utils::IRunnable, private utils::Noncopyable\r
+{\r
+public:\r
+       TransitionProducer(MediaProducerPtr pDestination, const TransitionInfo& transitionInfo, const FrameFormatDescription& fmtDesc);\r
+       virtual ~TransitionProducer();\r
+\r
+       //MediaProducer\r
+       virtual IMediaController* QueryController(const tstring& id);\r
+       virtual MediaProducerPtr GetFollowingProducer();\r
+\r
+       //FrameMediaController\r
+       virtual bool Initialize(FrameManagerPtr pFrameManager);\r
+       virtual FrameBuffer& GetFrameBuffer();\r
+\r
+       //ITransitionController\r
+       virtual bool Start(const ClipInfo& srcClipInfo);\r
+\r
+       //IRunnable\r
+       virtual void Run(HANDLE stopEvent);\r
+       virtual bool OnUnhandledException(const std::exception& ex) throw();\r
+\r
+private:\r
+\r
+       struct Implementation;\r
+       std::tr1::shared_ptr<Implementation> pImpl_;\r
+};\r
+typedef std::tr1::shared_ptr<TransitionProducer> TransitionProducerPtr;\r
+\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/producers/ffmpeg/FFMPEGException.h b/server/producers/ffmpeg/FFMPEGException.h
new file mode 100644 (file)
index 0000000..c05b756
--- /dev/null
@@ -0,0 +1,189 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+\r
+#ifndef _FFFMPEG_EXCEPTION_H_\r
+#define _FFFMPEG_EXCEPTION_H_\r
+\r
+#include <exception>\r
+#include <system_error>\r
+\r
+#ifdef _MSC_VER\r
+#pragma warning(push)\r
+#pragma warning(disable : 4482)\r
+#endif\r
+\r
+namespace caspar\r
+{\r
+       namespace ffmpeg\r
+       {\r
+               \r
+namespace ffmpeg_errc\r
+{\r
+       enum ffmpeg_errc_t\r
+       {\r
+               unknown = 0,\r
+               sws_failure = 604,\r
+\r
+               invalid_file = 610,\r
+                       no_streams = 611,\r
+                       decoder_not_found = 612,\r
+                       invalid_codec = 613,\r
+                       unknown_codec = 614,\r
+                       invalid_video_codec = 615,\r
+                       invalid_audio_codec = 616,\r
+\r
+               invalid_packet = 620,\r
+                       decode_failed = 621,\r
+                       decode_video_failed = 622,\r
+                       decode_audio_failed = 623,\r
+                       deinterlace_failed = 624,\r
+\r
+               invalid_audio_frame_size = 630\r
+       };\r
+}\r
+\r
+typedef ffmpeg_errc::ffmpeg_errc_t ffmpeg_errn;\r
+\r
+inline std::error_code ffmpeg_make_averror_code(int averror)\r
+{\r
+       return std::make_error_code(static_cast<std::generic_errno>(-min(0, averror)));\r
+}\r
+\r
+class ffmpeg_category_impl : public std::error_category\r
+{\r
+public:\r
+       virtual const char* name() const\r
+       {\r
+               return "ffmpeg";\r
+       }\r
+\r
+       virtual std::string message(int ev) const\r
+       { \r
+               switch (ev)\r
+               {\r
+               case ffmpeg_errn::decoder_not_found:\r
+                       return "Decoder for specified codec not found.";\r
+               case ffmpeg_errn::unknown_codec:\r
+                       return "Codec not supported.";\r
+               case ffmpeg_errn::invalid_video_codec:\r
+                       return "Could not open video codec.";\r
+               case ffmpeg_errn::invalid_audio_codec:\r
+                       return "Could not open audio codec.";\r
+               case ffmpeg_errn::decode_video_failed:\r
+                       return "Could not decode video packet.";\r
+               case ffmpeg_errn::decode_audio_failed:\r
+                       return "Could not decode audio packet.";\r
+               case ffmpeg_errn::deinterlace_failed:\r
+                       return "Could not deinterlace video packet. Make sure packet has not been scaled before deinterlacing.";          \r
+               }\r
+               return "Unknown";\r
+       }\r
+\r
+       const std::error_category& ffmpeg_category()\r
+       {\r
+               static ffmpeg_category_impl instance;\r
+               return instance;\r
+       }\r
+\r
+       std::error_code make_error_code(ffmpeg_errn e)\r
+       {\r
+               return std::error_code(static_cast<int>(e), ffmpeg_category());\r
+       }\r
+\r
+       std::error_condition make_error_condition(ffmpeg_errn e)\r
+       {\r
+               return std::error_condition(static_cast<int>(e), ffmpeg_category());\r
+       }\r
+\r
+       virtual bool equivalent(int code, const std::error_condition& condition) const\r
+       {\r
+               // TODO: Impletement\r
+               return false;\r
+       }\r
+\r
+       virtual bool equivalent(const std::error_code& code, int condition) const\r
+       {\r
+               // TODO: Impletement\r
+               return false;\r
+       }\r
+\r
+};\r
+\r
+inline std::error_code ffmpeg_make_error_code(ffmpeg_errn errn)\r
+{      \r
+       return ffmpeg_category_impl().make_error_code(errn);\r
+}\r
+\r
+class ffmpeg_error : std::runtime_error\r
+{\r
+public:\r
+       \r
+       explicit ffmpeg_error(std::error_code error_code, const std::string& message = "")\r
+               : \r
+               std::runtime_error(message), code_(error_code)\r
+       {               \r
+       }\r
+\r
+       ffmpeg_error(std::error_code error_code, const char* message)\r
+               : \r
+               std::runtime_error(message), code_(error_code)\r
+       {\r
+       }\r
+\r
+       ffmpeg_error(std::error_code::value_type error_value, const std::error_category& error_category, const std::string& message = "")\r
+               : \r
+               std::runtime_error(message), code_(error_value, error_category)\r
+       {\r
+       }\r
+\r
+       ffmpeg_error(std::error_code::value_type error_value, const std::error_category& error_category, const char *message) \r
+               :\r
+               std::runtime_error(message), code_(error_value, error_category)\r
+       {\r
+       }\r
+\r
+       const std::error_code& code() const throw()\r
+       {\r
+               return code_;\r
+       }\r
+\r
+private:\r
+       std::error_code code_;\r
+};\r
+\r
+       }\r
+\r
+}\r
+\r
+//namespace std\r
+//{\r
+//     template <>\r
+//     struct std::is_error_code_enum<caspar::ffmpeg::ffmpeg_errn::ffmpeg_errn_t>: public std::true_type {};\r
+//}\r
+\r
+\r
+#if defined(_MSC_VER)\r
+#pragma warning(pop)\r
+#pragma warning(disable : 4482)\r
+#endif\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/producers/ffmpeg/FFMPEGFrameOutput.cpp b/server/producers/ffmpeg/FFMPEGFrameOutput.cpp
new file mode 100644 (file)
index 0000000..b766604
--- /dev/null
@@ -0,0 +1,92 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "../../stdafx.h"\r
+\r
+#include "FFMPEGFrameOutput.h"\r
+\r
+#include "FFMPEGProducer.h"\r
+#include "FFMPEGPacket.h"\r
+#include "video/FFMPEGVideoDecoder.h"\r
+#include "audio/FFMPEGAudioDecoder.h"\r
+\r
+#include "../../utils/image/Image.hpp"\r
+\r
+#include <tbb/concurrent_queue.h>\r
+\r
+#include <deque>\r
+\r
+namespace caspar\r
+{\r
+       namespace ffmpeg\r
+       {\r
+\r
+struct FrameOutputFilter::Implementation : public FFMPEGFilterImpl<FFMPEGPacket>\r
+{\r
+       void* process(FFMPEGPacket* pPacket)\r
+       {               \r
+               if(pPacket->type == FFMPEGVideoPacket::packet_type)\r
+               {\r
+                       FFMPEGVideoPacket* pVideoPacket = static_cast<FFMPEGVideoPacket*>(pPacket);\r
+                       if(pVideoPacket->pFrame != nullptr)\r
+                               videoFrameQueue_.push_back(new FFMPEGVideoFrame(pVideoPacket));\r
+               }\r
+               else if(pPacket->type == FFMPEGAudioPacket::packet_type)\r
+               {\r
+                       FFMPEGAudioPacket* pAudioPacket = static_cast<FFMPEGAudioPacket*>(pPacket);     \r
+                       if(pAudioPacket->audioDataChunks.size() > 0)\r
+                               audioChunkQueue_.insert(audioChunkQueue_.end(), pAudioPacket->audioDataChunks.begin(), pAudioPacket->audioDataChunks.end());\r
+               }\r
+\r
+               delete pPacket;\r
+                                       \r
+               while(!videoFrameQueue_.empty() && (!audioChunkQueue_.empty() || !videoFrameQueue_.front()->hasAudio))\r
+               {\r
+                       if(videoFrameQueue_.front()->hasAudio)\r
+                       {\r
+                               videoFrameQueue_.front()->pFrame->AddAudioDataChunk(audioChunkQueue_.front());\r
+                               audioChunkQueue_.pop_front();\r
+                       }\r
+                               \r
+                       FFMPEGVideoFrame* pVideoFrame = videoFrameQueue_.front();\r
+                       videoFrameQueue_.pop_front();\r
+                       return pVideoFrame;\r
+               }\r
+                               \r
+               return nullptr;\r
+       }\r
+       \r
+       std::deque<FFMPEGVideoFrame*> videoFrameQueue_;\r
+       std::deque<audio::AudioDataChunkPtr> audioChunkQueue_;\r
+};\r
+\r
+FrameOutputFilter::FrameOutputFilter()\r
+       : tbb::filter(serial_in_order), pImpl_(new Implementation())\r
+{\r
+}\r
+\r
+void* FrameOutputFilter::operator()(void* item)\r
+{\r
+       return (*pImpl_)(item);\r
+}\r
+\r
+\r
+       }\r
+}
\ No newline at end of file
diff --git a/server/producers/ffmpeg/FFMPEGFrameOutput.h b/server/producers/ffmpeg/FFMPEGFrameOutput.h
new file mode 100644 (file)
index 0000000..6457cef
--- /dev/null
@@ -0,0 +1,65 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _FFMPEG_FRAME_OUTPUT_H_\r
+#define _FFMPEG_FRAME_OUTPUT_H_\r
+\r
+#include "FFMPEGPacket.h"\r
+\r
+#include "../../utils/Noncopyable.hpp"\r
+#include "../../audio/audiomanager.h"\r
+\r
+#include <memory>\r
+\r
+namespace caspar\r
+{\r
+       namespace ffmpeg\r
+       {\r
+\r
+///=================================================================================================\r
+/// <summary>  Merges video with audio and produces finished frames. </summary>\r
+///\r
+/// <remarks>  Rona 2010-06-19. </remarks>\r
+///=================================================================================================\r
+class FrameOutputFilter : public tbb::filter, private utils::Noncopyable\r
+{\r
+public:\r
+\r
+       FrameOutputFilter();\r
+\r
+       ///=================================================================================================\r
+       /// <summary>   Merges video with audio. </summary>\r
+       ///\r
+       /// <remarks>   Rona 2010-06-19. </remarks>\r
+       ///\r
+       /// <returns>   Finished frame. </returns>\r
+       ///=================================================================================================\r
+       void* operator()(void* item);\r
+                               \r
+private:\r
+       struct Implementation;\r
+       std::tr1::shared_ptr<Implementation> pImpl_;\r
+};\r
+typedef std::tr1::shared_ptr<FrameOutputFilter> FrameOutputFilterPtr;\r
+\r
+       }\r
+}\r
+\r
+#endif\r
diff --git a/server/producers/ffmpeg/FFMPEGInput.cpp b/server/producers/ffmpeg/FFMPEGInput.cpp
new file mode 100644 (file)
index 0000000..7b5a0c9
--- /dev/null
@@ -0,0 +1,284 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "../../stdafx.h"\r
+\r
+#include "FFMPEGInput.h"\r
+\r
+#include "FFMPEGException.h"\r
+#include "video/FFMPEGVideoDecoder.h"\r
+#include "audio/FFMPEGAudioDecoder.h"\r
+\r
+#include "../../utils/Logger.h"\r
+#include "../../utils/LogLevel.h"\r
+#include "../../utils/image/Image.hpp"\r
+#include "../../utils/UnhandledException.h"\r
+#include "../../utils/scope_exit.h"\r
+\r
+#include <tbb/concurrent_queue.h>\r
+#include <tbb/pipeline.h>\r
+#include <tbb/spin_mutex.h>\r
+\r
+#include <errno.h>\r
+#include <system_error>\r
+#include <algorithm>\r
+\r
+#pragma warning(disable : 4482)\r
+\r
+namespace caspar\r
+{\r
+       namespace ffmpeg\r
+       {\r
+               \r
+struct InputFilter::Implementation\r
+{\r
+       Implementation() \r
+               : \r
+               videoFrameRate_(25.0),\r
+               videoStreamIndex_(-1),\r
+               audioStreamIndex_(-1),\r
+               pVideoCodec_(nullptr),\r
+               pAudioCodec_(nullptr)\r
+       {\r
+               loop_ = false;\r
+               isRunning_ = false;\r
+       }\r
+\r
+       void Load(const std::string& filename, std::error_code& errc = std::error_code())\r
+       {       \r
+               isRunning_ = false;\r
+\r
+               CASPAR_SCOPE_EXIT([&]\r
+               {\r
+                       if(!isRunning_)\r
+                       {\r
+                               pVideoCodecContext_.reset();\r
+                               pAudioCodecContext_.reset();\r
+                               pFormatContext_.reset();\r
+                               videoFrameRate_ = 25.0;\r
+                               videoStreamIndex_ = -1;\r
+                               audioStreamIndex_ = -1;\r
+                       }\r
+               });\r
+\r
+               AVFormatContext* pWeakFormatContext;\r
+               errc = ffmpeg_make_averror_code(av_open_input_file(&pWeakFormatContext, filename.c_str(), nullptr, 0, nullptr));\r
+               pFormatContext_.reset(pWeakFormatContext, av_close_input_file);\r
+               if(errc)\r
+                       throw ffmpeg_error(errc);\r
+                       \r
+               errc = ffmpeg_make_averror_code(av_find_stream_info(pFormatContext_.get()));\r
+               if(errc)\r
+                       throw ffmpeg_error(errc);\r
+\r
+               pVideoCodecContext_ = OpenVideoStream();\r
+                       \r
+               videoFrameRate_ = static_cast<double>(pVideoCodecContext_->time_base.den) / static_cast<double>(pVideoCodecContext_->time_base.num);\r
+\r
+               try\r
+               {\r
+                       pAudioCodecContext_ = OpenAudioStream();\r
+               }\r
+               catch(std::system_error& er) // Audio is non critical\r
+               {\r
+                       errc = er.code();\r
+                       LOG << utils::LogLevel::Verbose \r
+                               << TEXT("[ffmpeg::InputFilter] Failed to Load AudioStream. Continuing without Audio. Error: " \r
+                               << errc.message().c_str());\r
+               }\r
+\r
+               isRunning_ = true;\r
+       }\r
+               \r
+       std::shared_ptr<AVCodecContext> OpenVideoStream()\r
+       {\r
+               bool succeeded = false;\r
+\r
+               CASPAR_SCOPE_EXIT([&]\r
+               {\r
+                       if(!succeeded)\r
+                       {\r
+                               videoStreamIndex_ = -1;\r
+                               pVideoCodec_ = nullptr;\r
+                       }\r
+               });\r
+\r
+               AVStream** streams_end = pFormatContext_->streams+pFormatContext_->nb_streams;\r
+               AVStream** videoStream = std::find_if(pFormatContext_->streams, streams_end, \r
+                       [](AVStream* stream) { return stream != nullptr && stream->codec->codec_type == CODEC_TYPE_VIDEO ;});\r
+\r
+               videoStreamIndex_ = videoStream != streams_end ? (*videoStream)->index : -1;\r
+               if(videoStreamIndex_ == -1) \r
+                       throw ffmpeg_error(ffmpeg_make_error_code(ffmpeg_errc::no_streams));\r
+               \r
+               pVideoCodec_ = avcodec_find_decoder((*videoStream)->codec->codec_id);                   \r
+               if(pVideoCodec_ == nullptr)\r
+                       throw ffmpeg_error(ffmpeg_make_error_code(ffmpeg_errc::decoder_not_found));\r
+                       \r
+               std::error_code errc = ffmpeg_make_averror_code(avcodec_open((*videoStream)->codec, pVideoCodec_));\r
+               if(errc)                \r
+                       throw ffmpeg_error(errc);\r
+\r
+               succeeded = true;\r
+\r
+               return std::shared_ptr<AVCodecContext>((*videoStream)->codec, avcodec_close);\r
+       }\r
+\r
+       std::shared_ptr<AVCodecContext> OpenAudioStream()\r
+       {       \r
+               bool succeeded = false;\r
+\r
+               CASPAR_SCOPE_EXIT([&]\r
+               {\r
+                       if(!succeeded)\r
+                       {\r
+                               audioStreamIndex_ = -1;\r
+                               pAudioCodec_ = nullptr;\r
+                       }\r
+               });\r
+\r
+               AVStream** streams_end = pFormatContext_->streams+pFormatContext_->nb_streams;\r
+               AVStream** audioStream = std::find_if(pFormatContext_->streams, streams_end, \r
+                       [](AVStream* stream) { return stream != nullptr && stream->codec->codec_type == CODEC_TYPE_AUDIO;});\r
+\r
+               audioStreamIndex_ = audioStream != streams_end ? (*audioStream)->index : -1;\r
+               if(audioStreamIndex_ == -1)\r
+                       return nullptr;\r
+               \r
+               pAudioCodec_ = avcodec_find_decoder((*audioStream)->codec->codec_id);\r
+               if(pAudioCodec_ == 0)\r
+                       throw ffmpeg_error(ffmpeg_make_error_code(ffmpeg_errc::decoder_not_found));\r
+               \r
+               std::error_code errc = ffmpeg_make_averror_code(avcodec_open((*audioStream)->codec, pAudioCodec_));\r
+               if(errc)                \r
+                       throw ffmpeg_error(errc);               \r
+\r
+               succeeded = true;\r
+\r
+               return std::shared_ptr<AVCodecContext>((*audioStream)->codec, avcodec_close);\r
+       }       \r
+\r
+       void* operator()(void*)\r
+       {\r
+               assert(pFrameManager_); // NOTE: FrameManager must be initialized before filter is run\r
+\r
+               while(isRunning_)\r
+               {\r
+                       AVPacket packet;\r
+                       std::shared_ptr<AVPacket> pPacket(&packet, av_free_packet);\r
+\r
+                       if (av_read_frame(pFormatContext_.get(), pPacket.get()) >= 0 && isRunning_) // NOTE: Packet is only valid until next call of av_read_frame or av_close_input_file\r
+                       {\r
+                               if(pPacket->stream_index == videoStreamIndex_)                          \r
+                               {\r
+                                       tbb::spin_mutex::scoped_lock lock(mutex_);\r
+                                       return new FFMPEGVideoPacket(pPacket, pFrameManager_->CreateFrame(), pFrameManager_->GetFrameFormatDescription(), // NOTE: FFMPEGVideoPacket makes a copy of AVPacket\r
+                                                                                                pVideoCodecContext_.get(), pVideoCodec_, audioStreamIndex_ != -1);             \r
+                               }\r
+                               else if(pPacket->stream_index == audioStreamIndex_)     \r
+                               {\r
+                                       return new FFMPEGAudioPacket(pPacket, pAudioCodecContext_.get(), pAudioCodec_, videoFrameRate_);                        \r
+                               }\r
+                               else\r
+                                       assert(false && "Unknown packet type");\r
+                       }\r
+                       else if(!loop_ || av_seek_frame(pFormatContext_.get(), -1, 0, AVSEEK_FLAG_BACKWARD) < 0) // TODO: av_seek_frame does not work for all formats\r
+                       {\r
+                               isRunning_ = false;\r
+                       }\r
+               }\r
+\r
+               return nullptr;\r
+       }\r
+       \r
+       void Stop()\r
+       {\r
+               isRunning_ = false;\r
+       }\r
+       \r
+       void SetFactory(const FrameManagerPtr& pFrameManger)\r
+       {\r
+               tbb::spin_mutex::scoped_lock lock(mutex_);\r
+               pFrameManager_ = pFrameManger;\r
+       }\r
+       \r
+       double videoFrameRate_;\r
+       \r
+       std::shared_ptr<AVFormatContext>        pFormatContext_;        // Destroy this last\r
+\r
+       std::shared_ptr<AVCodecContext>         pVideoCodecContext_;\r
+       AVCodec*                                                        pVideoCodec_;\r
+\r
+       std::shared_ptr<AVCodecContext>         pAudioCodecContext_;\r
+       AVCodec*                                                        pAudioCodec_;\r
+\r
+       tbb::atomic<bool>                                       isRunning_;\r
+       tbb::atomic<bool>                                       loop_;\r
+       int                                                                     videoStreamIndex_;\r
+       int                                                                     audioStreamIndex_;\r
+       FrameManagerPtr                                         pFrameManager_;\r
+       tbb::spin_mutex                                         mutex_;\r
+};\r
+\r
+InputFilter::InputFilter() : tbb::filter(serial_in_order), pImpl_(new Implementation())\r
+{\r
+}\r
+\r
+void InputFilter::Load(const std::string& filename, std::error_code& errc)\r
+{\r
+       pImpl_->Load(filename, errc);\r
+}\r
+\r
+void InputFilter::SetFactory(const FrameManagerPtr& pFrameManger)\r
+{\r
+       pImpl_->SetFactory(pFrameManger);\r
+}\r
+\r
+void* InputFilter::operator()(void*)\r
+{\r
+       return (*pImpl_)(NULL);\r
+}\r
+\r
+void InputFilter::SetLoop(bool value)\r
+{\r
+       pImpl_->loop_ = value;\r
+}\r
+\r
+void InputFilter::Stop()\r
+{\r
+       pImpl_->Stop();\r
+}\r
+\r
+const FrameManagerPtr InputFilter::GetFrameManager() const\r
+{\r
+       return pImpl_->pFrameManager_;\r
+}\r
+\r
+const std::shared_ptr<AVCodecContext>& InputFilter::VideoCodecContext() const\r
+{\r
+       return pImpl_->pVideoCodecContext_;\r
+}\r
+\r
+const std::shared_ptr<AVCodecContext>& InputFilter::AudioCodecContext() const\r
+{\r
+       return pImpl_->pAudioCodecContext_;\r
+}\r
+       }\r
+}
\ No newline at end of file
diff --git a/server/producers/ffmpeg/FFMPEGInput.h b/server/producers/ffmpeg/FFMPEGInput.h
new file mode 100644 (file)
index 0000000..c03a4db
--- /dev/null
@@ -0,0 +1,133 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _FFMPEG_INPUT_H_\r
+#define _FFMPEG_INPUT_H_\r
+\r
+#include "FFMPEGPacket.h"\r
+\r
+#include "../../frame/FrameManager.h"\r
+#include "../../utils/Noncopyable.hpp"\r
+\r
+#include <tbb/pipeline.h>\r
+\r
+#include <memory>\r
+#include <system_error>\r
+\r
+namespace caspar\r
+{\r
+       namespace ffmpeg\r
+       {\r
+       \r
+typedef std::tr1::shared_ptr<AVFormatContext> AVFormatContextPtr;\r
+\r
+///=================================================================================================\r
+/// <summary>  Reads and creates packets from file. </summary>\r
+///\r
+/// <remarks>  Rona 2010-06-19. </remarks>\r
+///=================================================================================================\r
+class InputFilter : public tbb::filter, private utils::Noncopyable\r
+{\r
+public:\r
+\r
+       ///=================================================================================================\r
+       /// <summary>   Default constructor. </summary>\r
+       ///\r
+       /// <remarks>   Rona 2010-06-19. </remarks>\r
+       ///=================================================================================================\r
+       InputFilter();\r
+\r
+       ///=================================================================================================\r
+       /// <summary>   Loads the given file. </summary>\r
+       ///\r
+       /// <remarks>   Rona 2010-06-19. </remarks>\r
+       ///\r
+       /// <param name="filename">     Filename of the file. </param>\r
+       /// <param name="errc">         [in,out] The errc. </param>\r
+       ///=================================================================================================\r
+       void Load(const std::string& filename, std::error_code& errc = std::error_code());\r
+\r
+       ///=================================================================================================\r
+       /// <summary>   Sets the factory used for allocating frames. </summary>\r
+       ///\r
+       /// <remarks>   Rona 2010-06-19. </remarks>\r
+       ///\r
+       /// <param name="pFrameManger"> The frame manger. </param>\r
+       ///\r
+       /// <throws>    Does not throw. </throws>\r
+       ///\r
+       /// <returns>   true if it succeeds, false if it fails. </returns>\r
+       ///=================================================================================================\r
+       void SetFactory(const FrameManagerPtr& pFrameManger);\r
+\r
+       ///=================================================================================================\r
+       /// <summary>   Video codec context. </summary>\r
+       ///\r
+       /// <returns>   . </returns>\r
+       ///=================================================================================================\r
+       const std::shared_ptr<AVCodecContext>& VideoCodecContext() const;\r
+\r
+       ///=================================================================================================\r
+       /// <summary>   Audio codec context. </summary>\r
+       ///\r
+       /// <returns>   . </returns>\r
+       ///=================================================================================================\r
+       const std::shared_ptr<AVCodecContext>& AudioCodecContext() const;\r
+\r
+       ///=================================================================================================\r
+       /// <summary>   Reads a packet from file. </summary>\r
+       ///\r
+       /// <remarks>   Rona 2010-06-19. </remarks>\r
+       ///\r
+       /// <returns>   A FFMPEG packet. </returns>\r
+       ///=================================================================================================\r
+       void* operator()(void*);\r
+\r
+       ///=================================================================================================\r
+       /// <summary>   Sets wheter the video should loop once finished. </summary>\r
+       ///\r
+       /// <remarks>   Rona 2010-06-19. </remarks>\r
+       ///\r
+       /// <param name="value">        true to value. </param>\r
+       ///=================================================================================================\r
+       void SetLoop(bool value);\r
+\r
+       ///=================================================================================================\r
+       /// <summary>   Gets the frame manager. </summary>\r
+       ///\r
+       /// <returns>   The frame manager. </returns>\r
+       ///=================================================================================================\r
+       const FrameManagerPtr GetFrameManager() const;\r
+\r
+       ///=================================================================================================\r
+       /// <summary>   Stops this object. </summary>\r
+       ///=================================================================================================\r
+       void Stop();\r
+\r
+private:\r
+       struct Implementation;\r
+       std::tr1::shared_ptr<Implementation> pImpl_;\r
+};\r
+typedef std::tr1::shared_ptr<InputFilter> InputFilterPtr;\r
+\r
+       }\r
+}\r
+\r
+#endif\r
diff --git a/server/producers/ffmpeg/FFMPEGOutput.cpp b/server/producers/ffmpeg/FFMPEGOutput.cpp
new file mode 100644 (file)
index 0000000..863ca00
--- /dev/null
@@ -0,0 +1,159 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "../../stdafx.h"\r
+\r
+#include "FFMPEGOutput.h"\r
+\r
+#include "FFMPEGProducer.h"\r
+#include "FFMPEGPacket.h"\r
+#include "video/FFMPEGVideoDecoder.h"\r
+#include "audio/FFMPEGAudioDecoder.h"\r
+\r
+#include "../../frame/buffers/MotionFrameBuffer.h"\r
+#include "../../utils/image/Image.hpp"\r
+#include "../../utils/Event.h"\r
+\r
+#include <tbb/concurrent_queue.h>\r
+\r
+#include <memory>\r
+#include <queue>\r
+\r
+namespace caspar\r
+{\r
+       namespace ffmpeg\r
+       {\r
+\r
+struct OutputFilter::Implementation : public FFMPEGFilterImpl<FFMPEGVideoFrame>\r
+{\r
+       Implementation() : master_(tbb::this_tbb_thread::get_id()), stopEvent_(true, false)\r
+       {\r
+               isRunning_ = true;\r
+               isBuffered_ = false;\r
+               SetCapacity(FFMPEGProducer::DEFAULT_BUFFER_SIZE);\r
+       }\r
+               \r
+       void* process(FFMPEGVideoFrame* pVideoFrame)\r
+       {                               \r
+               if(isRunning_)\r
+               {                                               \r
+                       deferred_.push(pVideoFrame->pFrame);\r
+               \r
+                       if(isBuffered_)\r
+                               SendFrames();                                   \r
+                       else\r
+                               isBuffered_ =  bufferTarget_ < deferred_.size();                \r
+               }\r
+\r
+               delete pVideoFrame;\r
+\r
+               return nullptr;\r
+       }\r
+\r
+       void SendFrames()\r
+       {               \r
+               HANDLE handles[2] = { stopEvent_, frameBuffer.GetWriteWaitHandle() };\r
+               DWORD timeout = tbb::this_tbb_thread::get_id() == master_ ? INFINITE : 0; // Only block on master thread\r
+               while(!deferred_.empty() && WaitForMultipleObjects(2, handles, FALSE, timeout) == WAIT_OBJECT_0 + 1 && isRunning_)\r
+               {\r
+                       frameBuffer.push_back(deferred_.front());\r
+                       deferred_.pop();\r
+               }\r
+       }\r
+       \r
+       void Stop()\r
+       {\r
+               if(isRunning_.fetch_and_store(false))\r
+                       frameBuffer.push_back(nullptr);\r
+               stopEvent_.Set();\r
+       }\r
+                       \r
+       void SetCapacity(size_t capacity)\r
+       {\r
+               if(capacity < 2)\r
+                       throw std::exception("[FFMPEGOutput::SetCapacity] Invalid Argument: capacity");\r
+               frameBuffer.SetCapacity(capacity);\r
+               bufferTarget_ = min(FFMPEGProducer::LOAD_TARGET_BUFFER_SIZE, capacity);\r
+       }       \r
+\r
+       void SetMaster(tbb::tbb_thread::id master)\r
+       {\r
+               master_ = master;\r
+       }\r
+\r
+       void Flush() // Flush frames that were not sent by the master thread while running\r
+       {                       \r
+               SendFrames();\r
+               if(isRunning_.fetch_and_store(false))\r
+                       frameBuffer.push_back(nullptr);\r
+       }\r
+       \r
+       FrameBuffer& GetFrameBuffer()\r
+       {\r
+               return frameBuffer;\r
+       }\r
+                               \r
+       MotionFrameBuffer frameBuffer;\r
+\r
+       utils::Event stopEvent_;\r
+       std::queue<FramePtr> deferred_;\r
+       tbb::tbb_thread::id master_;\r
+       tbb::atomic<int> bufferTarget_;\r
+       tbb::atomic<bool> isRunning_;\r
+       tbb::atomic<bool> isBuffered_;\r
+};\r
+\r
+OutputFilter::OutputFilter() : tbb::filter(serial_in_order), pImpl_(new Implementation())\r
+{\r
+}\r
+\r
+void* OutputFilter::operator()(void* item)\r
+{\r
+       return (*pImpl_)(item);\r
+}\r
+\r
+void OutputFilter::Stop()\r
+{\r
+       pImpl_->Stop();\r
+}\r
+\r
+void OutputFilter::SetCapacity(size_t capacity)\r
+{\r
+       pImpl_->SetCapacity(capacity); \r
+}\r
+\r
+void OutputFilter::SetMaster(tbb::tbb_thread::id master)\r
+{\r
+       pImpl_->SetMaster(master);\r
+}\r
+\r
+void OutputFilter::Flush()\r
+{\r
+       pImpl_->Flush();\r
+}\r
+\r
+FrameBuffer& OutputFilter::GetFrameBuffer()\r
+{\r
+       return pImpl_->GetFrameBuffer();\r
+}\r
+\r
+\r
+       }\r
+}
\ No newline at end of file
diff --git a/server/producers/ffmpeg/FFMPEGOutput.h b/server/producers/ffmpeg/FFMPEGOutput.h
new file mode 100644 (file)
index 0000000..65c8d71
--- /dev/null
@@ -0,0 +1,108 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _FFMPEG_OUTPUT_H_\r
+#define _FFMPEG_OUTPUT_H_\r
+\r
+#include "FFMPEGPacket.h"\r
+\r
+#include "../../frame/buffers/FrameBuffer.h"\r
+#include "../../utils/Noncopyable.hpp"\r
+\r
+#include <tbb/tbb_thread.h>\r
+\r
+#include <memory>\r
+#include <functional>\r
+\r
+namespace caspar\r
+{\r
+       namespace ffmpeg\r
+       {\r
+\r
+///=================================================================================================\r
+/// <summary>  Pushes frames into framebuffer. </summary>\r
+///\r
+/// <remarks>  Rona 2010-06-19. </remarks>\r
+///=================================================================================================\r
+class OutputFilter : public tbb::filter, private utils::Noncopyable\r
+{\r
+public:\r
+\r
+       ///=================================================================================================\r
+       /// <summary>   Default constructor. </summary>\r
+       ///\r
+       /// <remarks>   Rona 2010-06-19. </remarks>\r
+       ///=================================================================================================\r
+       OutputFilter();\r
+\r
+       ///=================================================================================================\r
+       /// <summary>   Pushes frames into framebuffer. Is blocking. </summary>\r
+       ///\r
+       /// <remarks>   Rona 2010-06-19. </remarks>\r
+       ///\r
+       /// <returns>   null </returns>\r
+       ///=================================================================================================\r
+       void* operator()(void* item);\r
+\r
+       ///=================================================================================================\r
+       /// <summary>   Unblocks and flushes frame queue. </summary>\r
+       ///=================================================================================================\r
+       void Stop();    \r
+\r
+       ///=================================================================================================\r
+       /// <summary>   Sends deferred frames to framebuffer. </summary>\r
+       ///=================================================================================================\r
+       void Flush();\r
+\r
+       ///=================================================================================================\r
+       /// <summary>   Gets the frame buffer. </summary>\r
+       ///\r
+       /// <returns>   The frame buffer. </returns>\r
+       ///=================================================================================================\r
+       FrameBuffer& GetFrameBuffer();\r
+\r
+       ///=================================================================================================\r
+       /// <summary>   Sets the framebuffer capacity. </summary>\r
+       ///\r
+       /// <remarks>   Rona 2010-06-19. </remarks>\r
+       ///\r
+       /// <param name="capacity">     The capacity. </param>\r
+       ///=================================================================================================\r
+       void SetCapacity(size_t capacity);\r
+\r
+       ///=================================================================================================\r
+       /// <summary>   Sets the master thread which is allowed to block. </summary>\r
+       ///\r
+       /// <remarks>   Rona 2010-06-19. </remarks>\r
+       ///\r
+       /// <param name="master">       The master thread. </param>\r
+       ///=================================================================================================\r
+       void SetMaster(tbb::tbb_thread::id master);\r
+                       \r
+private:\r
+       struct Implementation;\r
+       std::tr1::shared_ptr<Implementation> pImpl_;\r
+};\r
+typedef std::tr1::shared_ptr<OutputFilter> OutputFilterPtr;\r
+\r
+       }\r
+}\r
+\r
+#endif\r
diff --git a/server/producers/ffmpeg/FFMPEGPacket.cpp b/server/producers/ffmpeg/FFMPEGPacket.cpp
new file mode 100644 (file)
index 0000000..fb0822a
--- /dev/null
@@ -0,0 +1,33 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "../../stdafx.h"\r
+\r
+#include "FFMPEGPacket.h"\r
+\r
+namespace caspar\r
+{\r
+       namespace ffmpeg\r
+       {\r
+\r
+tbb::cache_aligned_allocator<uint8_t> FFMPEGPacket::allocator_;\r
+\r
+       }\r
+}
\ No newline at end of file
diff --git a/server/producers/ffmpeg/FFMPEGPacket.h b/server/producers/ffmpeg/FFMPEGPacket.h
new file mode 100644 (file)
index 0000000..b024ea6
--- /dev/null
@@ -0,0 +1,242 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _FFMPEG_PACKET_H_\r
+#define _FFMPEG_PACKET_H_\r
+\r
+#include "FFMPEGException.h"\r
+\r
+#include "../../audio/audiomanager.h"\r
+#include "../../utils/Noncopyable.hpp"\r
+\r
+#include <tbb/pipeline.h>\r
+#include <tbb/cache_aligned_allocator.h>\r
+\r
+#include <vector>\r
+#include <memory>\r
+#include <type_traits>\r
+\r
+#include <boost/noncopyable.hpp>\r
+\r
+extern "C" \r
+{\r
+       #define __STDC_CONSTANT_MACROS\r
+       #define __STDC_LIMIT_MACROS\r
+       #include <libavformat/avformat.h>\r
+}\r
+\r
+namespace caspar\r
+{\r
+       namespace ffmpeg\r
+       {\r
+                               \r
+typedef std::tr1::shared_ptr<AVFrame> AVFramePtr;      \r
+typedef std::tr1::shared_ptr<AVPacket> AVPacketPtr;\r
+typedef std::tr1::shared_ptr<unsigned char> BytePtr;\r
+\r
+struct av_frame_allocator\r
+{\r
+       static AVFrame* construct()\r
+       { return avcodec_alloc_frame(); }\r
+       static void destroy(AVFrame* const block)\r
+       { av_free(block); }\r
+};\r
+\r
+///=================================================================================================\r
+/// <summary>  Values that represent different packet types used in ffmpeg pipeline. </summary>\r
+///\r
+/// <remarks>  Rona 2010-06-19. </remarks>\r
+///=================================================================================================\r
+enum FFMPEGPacketType\r
+{\r
+       VideoPacket = 1,\r
+       AudioPacket = 2,\r
+       VideoFrame = 4,\r
+       UnkownPacket = 8,\r
+       Any = VideoPacket | AudioPacket | VideoFrame | UnkownPacket\r
+};\r
+\r
+///=================================================================================================\r
+/// <summary>  Base class for packets used in ffmpeg pipeline. </summary>\r
+///\r
+/// <remarks>  Rona 2010-06-19. </remarks>\r
+///=================================================================================================\r
+struct FFMPEGPacket : boost::noncopyable\r
+{      \r
+       enum  { packet_type = Any };\r
+\r
+       virtual ~FFMPEGPacket()\r
+       {\r
+               if(data != nullptr)\r
+                       allocator_.deallocate(data, size);\r
+       }\r
+\r
+       AVCodecContext* codecContext;\r
+       AVCodec*        codec;\r
+       size_t          size;\r
+       uint8_t*        data;\r
+       const FFMPEGPacketType type;\r
+       static tbb::cache_aligned_allocator<uint8_t> allocator_;\r
+\r
+protected:\r
+       FFMPEGPacket(FFMPEGPacketType type) : type(type), data(nullptr) {}\r
+       FFMPEGPacket(const AVPacketPtr& packet, FFMPEGPacketType type, AVCodecContext* codecContext, AVCodec* codec) \r
+               : \r
+               size(packet->size), \r
+               type(type), \r
+               codecContext(codecContext), codec(codec)\r
+       {\r
+               data = allocator_.allocate(packet->size);\r
+               memcpy(data, packet->data, packet->size);\r
+       }\r
+};\r
+typedef std::shared_ptr<FFMPEGPacket> FFMPEGPacketPtr;\r
+\r
+///=================================================================================================\r
+/// <summary>  Used to avoid returning nullptr from input filter and stopping the producer for for packets of unknown type. </summary>\r
+///\r
+/// <remarks>  Rona 2010-06-19. </remarks>\r
+///=================================================================================================\r
+struct FFMPEGUnknownPacket : public FFMPEGPacket\r
+{\r
+       enum  { packet_type = UnkownPacket };\r
+\r
+       FFMPEGUnknownPacket() : FFMPEGPacket(UnkownPacket){}\r
+};\r
+\r
+///=================================================================================================\r
+/// <summary>  FFMPEG video packet. </summary>\r
+///\r
+/// <remarks>  Rona 2010-06-19. </remarks>\r
+///=================================================================================================\r
+struct FFMPEGVideoPacket : public FFMPEGPacket\r
+{\r
+       enum  { packet_type = VideoPacket };\r
+\r
+       FFMPEGVideoPacket(const AVPacketPtr& packet, const FramePtr& pFrame, const FrameFormatDescription& frameFormat, AVCodecContext* codecContext, AVCodec* codec, bool hasAudio) \r
+               : \r
+               FFMPEGPacket(packet, VideoPacket, codecContext, codec), pFrame(pFrame), frameFormat(frameFormat), hasAudio(hasAudio)\r
+       {\r
+       }\r
+       \r
+       bool                                    hasAudio;\r
+       FrameFormatDescription  frameFormat;\r
+       FramePtr                                pFrame;\r
+       AVFramePtr                              pDecodedFrame;\r
+};     \r
+\r
+///=================================================================================================\r
+/// <summary>  FFMPEG audio packet. </summary>\r
+///\r
+/// <remarks>  Rona 2010-06-19. </remarks>\r
+///=================================================================================================\r
+struct FFMPEGAudioPacket : public FFMPEGPacket\r
+{\r
+       enum  { packet_type = AudioPacket };\r
+\r
+       FFMPEGAudioPacket(const AVPacketPtr& packet, AVCodecContext* codecContext, AVCodec* codec, double videoFrameRate = 25.0) \r
+               : \r
+               FFMPEGPacket(packet, AudioPacket, codecContext, codec)\r
+       {\r
+               int bytesPerSec = (codecContext->sample_rate * codecContext->channels * 2);\r
+\r
+               if(bytesPerSec / 25 == 0)\r
+                       throw ffmpeg_error(ffmpeg_make_error_code(ffmpeg_errc::invalid_audio_frame_size));              \r
+\r
+               audioFrameSize = bytesPerSec / 25;\r
+               sourceAudioFrameSize = static_cast<int>(static_cast<double>(bytesPerSec) / videoFrameRate);\r
+\r
+               //make sure the framesize is a multiple of the samplesize\r
+               int sourceSizeMod = sourceAudioFrameSize % (codecContext->channels * 2);\r
+               if(sourceSizeMod != 0)\r
+                       sourceAudioFrameSize += (codecContext->channels * 2) - sourceSizeMod;\r
+\r
+               if(audioFrameSize == 0)\r
+                       throw ffmpeg_error(ffmpeg_make_error_code(ffmpeg_errc::invalid_audio_frame_size));\r
+       }\r
+               \r
+       std::vector<audio::AudioDataChunkPtr> audioDataChunks;\r
+       int sourceAudioFrameSize;\r
+       int audioFrameSize;\r
+};\r
+\r
+///=================================================================================================\r
+/// <summary>  Used to allow deallocation of unused memory in finished video and audio packets. </summary>\r
+///\r
+/// <remarks>  Rona 2010-06-19. </remarks>\r
+///=================================================================================================\r
+struct FFMPEGVideoFrame : public FFMPEGPacket\r
+{\r
+       enum  { packet_type = VideoFrame };\r
+\r
+       FFMPEGVideoFrame() : FFMPEGPacket(VideoFrame){}\r
+       FFMPEGVideoFrame(FramePtr pFrame) : FFMPEGPacket(VideoFrame), pFrame(pFrame){}\r
+       FFMPEGVideoFrame(const FFMPEGVideoPacket* pPacket) : FFMPEGPacket(VideoFrame), pFrame(pPacket->pFrame), hasAudio(pPacket->hasAudio){}\r
+       FramePtr pFrame;\r
+       bool hasAudio;\r
+};\r
+typedef std::shared_ptr<FFMPEGVideoFrame> FFMPEGVideoFramePtr;\r
+\r
+///=================================================================================================\r
+/// <summary>  Ffmpeg filter implementation. </summary>\r
+///\r
+/// <remarks>  Rona, 2010-06-20. </remarks>\r
+///=================================================================================================\r
+template <typename PacketType>\r
+class FFMPEGFilterImpl\r
+{\r
+protected:\r
+       ~FFMPEGFilterImpl(){}\r
+public:\r
+       void* operator()(void* item)\r
+       {                               \r
+               if(item == nullptr)\r
+                       return nullptr;\r
+\r
+               FFMPEGPacket* pPacket = static_cast<FFMPEGPacket*>(item);\r
+\r
+               if((pPacket->type & PacketType::packet_type) == 0)\r
+                       return item;\r
+\r
+               PacketType* pLocalPacket = static_cast<PacketType*>(pPacket); \r
+\r
+               if(!is_valid(pLocalPacket))\r
+                       return pLocalPacket;\r
+\r
+               return process(pLocalPacket);\r
+       }\r
+\r
+       virtual void finalize(void* item)\r
+       {\r
+               delete static_cast<FFMPEGPacket*>(item);\r
+       }\r
+       \r
+private:\r
+       virtual void* process(PacketType* pPacket) = 0;\r
+       virtual bool is_valid(PacketType* pPacket)\r
+       {\r
+               return pPacket != nullptr;\r
+       }\r
+};\r
+\r
+       }\r
+}\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/producers/ffmpeg/FFMPEGProducer.cpp b/server/producers/ffmpeg/FFMPEGProducer.cpp
new file mode 100644 (file)
index 0000000..c7e0088
--- /dev/null
@@ -0,0 +1,194 @@
+#include "../../stdafx.h"\r
+\r
+#include "FFMPEGException.h"\r
+#include "FFMPEGProducer.h"\r
+#include "FFMPEGInput.h"\r
+#include "FFMPEGFrameOutput.h"\r
+#include "FFMPEGOutput.h"\r
+\r
+#include "video/FFMPEGVideoDecoder.h"\r
+#include "video/FFMPEGVideoScaler.h"\r
+#include "video/FFMPEGVideoDeinterlacer.h"\r
+#include "audio/FFMPEGAudioDecoder.h"\r
+\r
+#include "../../Application.h"\r
+#include "../../MediaProducerInfo.h"\r
+#include "../../string_convert.h"\r
+#include "../../frame/FrameManager.h"\r
+#include "../../frame/FrameMediaController.h"\r
+#include "../../audio/audiomanager.h"\r
+#include "../../utils/Logger.h"\r
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "../../utils/LogLevel.h"\r
+#include "../../utils/UnhandledException.h"\r
+#include "../../utils/scope_exit.h"\r
+#include "../../utils/image/image.hpp"\r
+#include "../../string_convert.h"\r
+\r
+#include <tbb/task_group.h>\r
+#include <tbb/pipeline.h>\r
+#include <tbb/mutex.h>\r
+\r
+#include <boost/lexical_cast.hpp>\r
+#include <boost/thread.hpp>\r
+\r
+#include <string>\r
+#include <queue>\r
+#include <functional>\r
+\r
+namespace caspar{ namespace ffmpeg{\r
+\r
+struct FFMPEGProducer::Implementation : public FrameMediaController, private utils::Noncopyable\r
+{\r
+public:\r
+       Implementation(const tstring& filename, FFMPEGProducer* self) : self_(self)\r
+       {\r
+               if(filename.empty())\r
+                       throw std::exception("[FFMPEGProducer::FFMPEGProducer] Invalid Argument: filename");\r
+\r
+               isRunning_ = false;\r
+\r
+               output_.SetCapacity(GetApplication()->GetSetting<size_t>(TEXT("ffmpeg::buffersize"), FFMPEGProducer::DEFAULT_BUFFER_SIZE));\r
+               \r
+               input_.Load(utils::narrow(filename));\r
+       }\r
+\r
+       ~Implementation() \r
+       {               \r
+               output_.Stop();\r
+               input_.Stop();\r
+\r
+               if(pPipelineThread_ && !pPipelineThread_->timed_join(boost::posix_time::millisec(FFMPEGProducer::THREAD_TIMEOUT_MS)) && isRunning_)\r
+                       LOG << utils::LogLevel::Critical << TEXT("[FFMPEGProducer::~FFMPEGProducer] Thread timed-out!");\r
+       }\r
+               \r
+       bool Initialize(FrameManagerPtr pFrameManager) \r
+       {                       \r
+               if(pFrameManager == nullptr)\r
+                       return false;\r
+               \r
+               input_.SetFactory(pFrameManager);\r
+               \r
+               if(!pPipelineThread_)\r
+                       pPipelineThread_.reset(new boost::thread([this]{ Run(); }));\r
+               \r
+               return true;\r
+       }\r
+               \r
+       FrameBuffer& GetFrameBuffer()\r
+       {\r
+               return output_.GetFrameBuffer();\r
+       }\r
+\r
+       bool GetProducerInfo(MediaProducerInfo* pInfo) \r
+       {\r
+               if(pInfo == nullptr)\r
+                       return false;\r
+               \r
+               pInfo->HaveVideo = input_.VideoCodecContext() != nullptr;\r
+               pInfo->HaveAudio = input_.AudioCodecContext() != nullptr;\r
+               if(pInfo->HaveAudio)\r
+               {\r
+                       pInfo->AudioChannels = input_.AudioCodecContext()->channels;\r
+                       pInfo->AudioSamplesPerSec = input_.AudioCodecContext()->sample_rate;\r
+                       pInfo->BitsPerAudioSample = 16;\r
+               }\r
+\r
+               return true;\r
+       }\r
+\r
+       void Run()\r
+       {                       \r
+               CASPAR_THREAD_GUARD(0, L"[FFMPEGProducer::Run]", [=]\r
+               {\r
+                       CASPAR_SCOPE_EXIT([=]\r
+                       {\r
+                               isRunning_ = false;\r
+                       });\r
+\r
+                       class VideoDecodeAndScaleFilter : public tbb::filter\r
+                       {\r
+                       public:\r
+                               VideoDecodeAndScaleFilter() : tbb::filter(tbb::filter::serial_in_order) {}\r
+                               void* operator()(void* pToken) { return videoScaler(videoDecoder(pToken)); }\r
+                       private:\r
+                               VideoPacketDecoderFilter                        videoDecoder;\r
+                               VideoPacketScalerFilter                         videoScaler;\r
+                       };\r
+\r
+                       VideoDecodeAndScaleFilter                       videoDecoderAndScaler; // Decoder and scaler have to run in same thread\r
+                       VideoPacketDeinterlacerFilter           videoDeinterlacer;\r
+                       AudioPacketDecoderFilter                        audioDecoder;\r
+                       FrameOutputFilter                                       frameOutput;    \r
+\r
+                       isRunning_ = true;\r
+\r
+                       tbb::pipeline pipeline;\r
+                                               \r
+                       pipeline.add_filter(input_);            \r
+                       pipeline.add_filter(audioDecoder);                                      \r
+                       pipeline.add_filter(videoDecoderAndScaler);\r
+                       pipeline.add_filter(frameOutput);\r
+                       pipeline.add_filter(output_);\r
+                                               \r
+                       output_.SetMaster(tbb::this_tbb_thread::get_id());\r
+                       pipeline.run(FFMPEGProducer::MAX_TOKENS);\r
+                       output_.Flush();\r
+\r
+                       pipeline.clear();\r
+               });\r
+               \r
+       }\r
+\r
+       void SetLoop(bool loop)\r
+       {\r
+               input_.SetLoop(loop);\r
+       }       \r
+               \r
+       InputFilter                                                     input_; \r
+       OutputFilter                                            output_;        \r
+       std::unique_ptr<boost::thread>          pPipelineThread_;\r
+       \r
+       FFMPEGProducer*                                         self_;\r
+       tbb::atomic<bool>                                       isRunning_;\r
+};\r
+\r
+FFMPEGProducer::FFMPEGProducer(const tstring& filename) :      pImpl_(new Implementation(filename, this))\r
+{\r
+}\r
+\r
+IMediaController* FFMPEGProducer::QueryController(const tstring& id)\r
+{\r
+       return id == TEXT("FrameController") ? pImpl_.get() : nullptr;\r
+}\r
+\r
+bool FFMPEGProducer::GetProducerInfo(MediaProducerInfo* pInfo)\r
+{\r
+       return pImpl_->GetProducerInfo(pInfo);\r
+}\r
+\r
+void FFMPEGProducer::SetLoop(bool loop)\r
+{\r
+       pImpl_->SetLoop(loop);\r
+}\r
+\r
+}}
\ No newline at end of file
diff --git a/server/producers/ffmpeg/FFMPEGProducer.h b/server/producers/ffmpeg/FFMPEGProducer.h
new file mode 100644 (file)
index 0000000..85f6aac
--- /dev/null
@@ -0,0 +1,69 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _FFMPEG_PRODUCER_H_\r
+#define _FFMPEG_PRODUCER_H_\r
+\r
+#include "../../MediaProducer.h"\r
+#include "../../MediaManager.h"\r
+#include "../../MediaProducerInfo.h"\r
+\r
+#include "../../utils/Noncopyable.hpp"\r
+\r
+extern "C" \r
+{\r
+       #define __STDC_CONSTANT_MACROS\r
+       #define __STDC_LIMIT_MACROS\r
+       #include <libavformat/avformat.h>\r
+       #include <libavcodec/avcodec.h>\r
+       #include <libswscale/swscale.h>\r
+       #include <libavutil/avutil.h>\r
+}\r
+\r
+#include <memory>\r
+\r
+namespace caspar { namespace ffmpeg {\r
+\r
+class FFMPEGProducer : public MediaProducer\r
+{\r
+public:\r
+       FFMPEGProducer(const tstring& filename);\r
+       \r
+       IMediaController* QueryController(const tstring&);\r
+       bool GetProducerInfo(MediaProducerInfo* pInfo);\r
+\r
+       void SetLoop(bool loop);\r
+\r
+       static const size_t MAX_TOKENS = 5;\r
+       static const size_t MIN_BUFFER_SIZE = 2;\r
+       static const size_t DEFAULT_BUFFER_SIZE = 16;\r
+       static const size_t MAX_BUFFER_SIZE = 64;\r
+       static const size_t LOAD_TARGET_BUFFER_SIZE = 8;\r
+       static const size_t THREAD_TIMEOUT_MS = 1000;\r
+\r
+private:       \r
+       struct Implementation;\r
+       std::shared_ptr<Implementation> pImpl_;\r
+};\r
+typedef std::tr1::shared_ptr<FFMPEGProducer> FFMPEGProducerPtr;\r
+\r
+}}\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/producers/ffmpeg/FFmpegManager.cpp b/server/producers/ffmpeg/FFmpegManager.cpp
new file mode 100644 (file)
index 0000000..f27cb62
--- /dev/null
@@ -0,0 +1,82 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "../../stdafx.h"\r
+\r
+#include "FFMPEGManager.h"\r
+#include "FFMPEGProducer.h"\r
+\r
+#include "../../MediaProducerInfo.h"\r
+#include "../../frame/FrameManager.h"\r
+#include "../../frame/FrameMediaController.h"\r
+#include "../../utils/UnhandledException.h"\r
+\r
+#include <boost/thread/once.hpp>\r
+#include <boost/assign.hpp>\r
+\r
+namespace caspar {\r
+namespace ffmpeg {\r
+\r
+using namespace utils;\r
+using namespace boost::assign;\r
+\r
+FFMPEGManager::FFMPEGManager() \r
+{\r
+       static boost::once_flag flag = BOOST_ONCE_INIT;\r
+       boost::call_once(av_register_all, flag);\r
+       \r
+       _extensions += TEXT("mpg"), TEXT("avi"), TEXT("mov"), TEXT("dv"), TEXT("wav"), TEXT("mp3"), TEXT("mp4"), TEXT("f4v"), TEXT("flv");\r
+}\r
+\r
+MediaProducerPtr FFMPEGManager::CreateProducer(const tstring& filename)\r
+{\r
+       CASPAR_TRY\r
+       {\r
+               return std::make_shared<FFMPEGProducer>(filename);\r
+       }\r
+       CASPAR_CATCH_AND_LOG("[FFMPEGManager::CreateProducer]")\r
+\r
+       return nullptr;\r
+}\r
+\r
+bool FFMPEGManager::getFileInfo(FileInfo* pFileInfo)\r
+{\r
+       if(pFileInfo == nullptr)\r
+               return false;\r
+\r
+       auto movie = list_of(TEXT("avi"))(TEXT("mpg"))(TEXT("mov"))(TEXT("dv"))(TEXT("flv"))(TEXT("f4v"))(TEXT("mp4"));\r
+       auto audio = list_of(TEXT("wav"))(TEXT("mp3"));\r
+\r
+       if(std::find(movie.begin(), movie.end(), pFileInfo->filetype) != movie.end())\r
+       {\r
+               pFileInfo->length = 0;  //get real length from file\r
+               pFileInfo->type = TEXT("movie");\r
+               pFileInfo->encoding = TEXT("codec");\r
+       }\r
+       else if(std::find(audio.begin(), audio.end(), pFileInfo->filetype) != audio.end()) \r
+       {\r
+               pFileInfo->length = 0;  //get real length from file\r
+               pFileInfo->type = TEXT("audio");\r
+               pFileInfo->encoding = TEXT("NA");\r
+       }\r
+       return true;\r
+}\r
+\r
+}}
\ No newline at end of file
diff --git a/server/producers/ffmpeg/audio/FFMPEGAudioDecoder.cpp b/server/producers/ffmpeg/audio/FFMPEGAudioDecoder.cpp
new file mode 100644 (file)
index 0000000..6b9dde7
--- /dev/null
@@ -0,0 +1,128 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "../../../stdafx.h"\r
+\r
+#include "FFMPEGAudioDecoder.h"\r
+#include "../FFMPEGException.h"\r
+\r
+#include "../../../utils/image/Image.hpp"\r
+\r
+#include <queue>\r
+\r
+namespace caspar\r
+{\r
+       namespace ffmpeg\r
+       {\r
+               \r
+struct AudioPacketDecoderFilter::Implementation : public FFMPEGFilterImpl<FFMPEGAudioPacket>\r
+{\r
+       Implementation() : discardBytes_(0), currentAudioDataChunkOffset_(0)\r
+       {\r
+               pAudioDecompBuffer_.resize(AudioPacketDecoderFilter::AUDIO_DECOMP_BUFFER_SIZE);\r
+               int alignmentOffset_ = static_cast<unsigned char>(AudioPacketDecoderFilter::ALIGNMENT - (reinterpret_cast<size_t>(&pAudioDecompBuffer_.front()) % AudioPacketDecoderFilter::ALIGNMENT));\r
+               pAlignedAudioDecompAddr_ = &pAudioDecompBuffer_.front() + alignmentOffset_;                             \r
+       }\r
+               \r
+       void* process(FFMPEGAudioPacket* pAudioPacket)\r
+       {                       \r
+               int maxChunkLength = min(pAudioPacket->audioFrameSize, pAudioPacket->sourceAudioFrameSize);\r
+\r
+               int writtenBytes = AudioPacketDecoderFilter::AUDIO_DECOMP_BUFFER_SIZE - AudioPacketDecoderFilter::ALIGNMENT;\r
+               int result = avcodec_decode_audio2(pAudioPacket->codecContext, reinterpret_cast<int16_t*>(pAlignedAudioDecompAddr_), &writtenBytes, pAudioPacket->data, pAudioPacket->size);\r
+\r
+               if(result <= 0)\r
+                       return pAudioPacket;\r
+\r
+               unsigned char* pDecomp = pAlignedAudioDecompAddr_;\r
+\r
+               //if there are bytes to discard, do that first\r
+               while(writtenBytes > 0 && discardBytes_ != 0)\r
+               {\r
+                       int bytesToDiscard = min(writtenBytes, discardBytes_);\r
+                       pDecomp += bytesToDiscard;\r
+\r
+                       discardBytes_ -= bytesToDiscard;\r
+                       writtenBytes -= bytesToDiscard;\r
+               }\r
+\r
+               while(writtenBytes > 0)\r
+               {\r
+                       //if we're starting on a new chunk, allocate it\r
+                       if(pCurrentAudioDataChunk_ == nullptr) \r
+                       {\r
+                               pCurrentAudioDataChunk_ = std::make_shared<audio::AudioDataChunk>(pAudioPacket->audioFrameSize);\r
+                               currentAudioDataChunkOffset_ = 0;\r
+                       }\r
+\r
+                       //either fill what's left of the chunk or copy all writtenBytes that are left\r
+                       int targetLength = min((maxChunkLength - currentAudioDataChunkOffset_), writtenBytes);\r
+                       memcpy(pCurrentAudioDataChunk_->GetDataPtr() + currentAudioDataChunkOffset_, pDecomp, targetLength);\r
+                       writtenBytes -= targetLength;\r
+\r
+                       currentAudioDataChunkOffset_ += targetLength;\r
+                       pDecomp += targetLength;\r
+\r
+                       if(currentAudioDataChunkOffset_ >= maxChunkLength) \r
+                       {\r
+                               if(maxChunkLength < pAudioPacket->audioFrameSize) \r
+                                       memset(pCurrentAudioDataChunk_->GetDataPtr() + maxChunkLength, 0, pAudioPacket->audioFrameSize-maxChunkLength);                                 \r
+                               else if(pAudioPacket->audioFrameSize < pAudioPacket->sourceAudioFrameSize) \r
+                                       discardBytes_ = pAudioPacket->sourceAudioFrameSize-pAudioPacket->audioFrameSize;\r
+\r
+                               pAudioPacket->audioDataChunks.push_back(pCurrentAudioDataChunk_);\r
+                               pCurrentAudioDataChunk_.reset();\r
+                       }\r
+               }\r
+\r
+               return pAudioPacket;\r
+       }\r
+                       \r
+       bool is_valid(FFMPEGAudioPacket* pAudioPacket)\r
+       {\r
+               return pAudioPacket->codecContext != nullptr && pAudioPacket->data != nullptr && pAudioPacket->size > 0;\r
+       }\r
+\r
+       int                                                                     discardBytes_;\r
+               \r
+       std::vector<unsigned char>                      pAudioDecompBuffer_;\r
+       unsigned char*                                          pAlignedAudioDecompAddr_;\r
+\r
+       caspar::audio::AudioDataChunkPtr        pCurrentAudioDataChunk_;\r
+       int                                                                     currentAudioDataChunkOffset_;\r
+};\r
+\r
+AudioPacketDecoderFilter::AudioPacketDecoderFilter()\r
+       : tbb::filter(serial_in_order), pImpl_(new Implementation())\r
+{\r
+}\r
+\r
+void* AudioPacketDecoderFilter::operator()(void* item)\r
+{\r
+       return (*pImpl_)(item);\r
+}\r
+\r
+void AudioPacketDecoderFilter::finalize(void* item)\r
+{\r
+       return pImpl_->finalize(item);\r
+}\r
+\r
+       }\r
+}
\ No newline at end of file
diff --git a/server/producers/ffmpeg/audio/FFMPEGAudioDecoder.h b/server/producers/ffmpeg/audio/FFMPEGAudioDecoder.h
new file mode 100644 (file)
index 0000000..b327142
--- /dev/null
@@ -0,0 +1,85 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _FFMPEG_AUDIODECODER_H_\r
+#define _FFMPEG_AUDIODECODER_H_\r
+\r
+#include "../FFMPEGPacket.h"\r
+\r
+#include "../../../utils/Noncopyable.hpp"\r
+\r
+#include <tbb/pipeline.h>\r
+\r
+#include <memory>\r
+\r
+namespace caspar\r
+{\r
+       namespace ffmpeg\r
+       {\r
+///=================================================================================================\r
+/// <summary>  Decodes audio packets. </summary>\r
+///\r
+/// <remarks>  Rona 2010-06-19. </remarks>\r
+///=================================================================================================\r
+class AudioPacketDecoderFilter : public tbb::filter, private utils::Noncopyable\r
+{\r
+public:\r
+\r
+       ///=================================================================================================\r
+       /// <summary>   Default constructor. </summary>\r
+       ///\r
+       /// <remarks>   Rona 2010-06-19. </remarks>\r
+       ///=================================================================================================\r
+       AudioPacketDecoderFilter();\r
+\r
+       ///=================================================================================================\r
+       /// <summary>   Decodes audio packet. </summary>\r
+       ///\r
+       /// <remarks>   Rona 2010-06-19. </remarks>\r
+       ///\r
+       /// <returns>   The result of the operation. </returns>\r
+       ///=================================================================================================\r
+       void* operator()(void* item);\r
+\r
+       ///=================================================================================================\r
+       /// <summary>   Destroys packet. </summary>\r
+       ///\r
+       /// <remarks>   Rona 2010-06-19. </remarks>\r
+       ///\r
+       /// <param name="item"> [in,out] If non-null, the item. </param>\r
+       ///=================================================================================================\r
+       void finalize(void* item);\r
+       \r
+       /// <summary> The alignment </summary>\r
+       /// <remarks> Four sec of 16 bit stereo 48kHz should be enough </remarks>\r
+       static const int ALIGNMENT = 16 ;\r
+\r
+       /// <summary> Size of the audio decomp buffer </summary>\r
+       static const int AUDIO_DECOMP_BUFFER_SIZE = 4*48000*4+ALIGNMENT;\r
+private:\r
+       struct Implementation;\r
+       std::tr1::shared_ptr<Implementation> pImpl_;\r
+};\r
+typedef std::tr1::shared_ptr<AudioPacketDecoderFilter> AudioPacketDecoderFilterPtr;\r
+\r
+       }\r
+}\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/producers/ffmpeg/ffmpegmanager.h b/server/producers/ffmpeg/ffmpegmanager.h
new file mode 100644 (file)
index 0000000..60dc7de
--- /dev/null
@@ -0,0 +1,41 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+\r
+#include <queue>\r
+\r
+#include "..\..\MediaProducer.h"\r
+#include "..\..\MediaManager.h"\r
+\r
+namespace caspar {\r
+namespace ffmpeg {\r
+\r
+class FFMPEGManager : public IMediaManager\r
+{\r
+public:\r
+       FFMPEGManager();\r
+\r
+       MediaProducerPtr CreateProducer(const tstring& filename);\r
+       bool getFileInfo(FileInfo* pFileInfo);\r
+};\r
+\r
+}      //namespace ffmpeg\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/producers/ffmpeg/video/FFMPEGVideoDecoder.cpp b/server/producers/ffmpeg/video/FFMPEGVideoDecoder.cpp
new file mode 100644 (file)
index 0000000..ba234c1
--- /dev/null
@@ -0,0 +1,78 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "../../../stdafx.h"\r
+\r
+#include "FFMPEGVideoDecoder.h"\r
+#include "../FFMPEGException.h"\r
+\r
+#include "../../../utils/object_pool.h"\r
+#include "../../../utils/image/Image.hpp"\r
+\r
+namespace caspar\r
+{\r
+       namespace ffmpeg\r
+       {\r
+\r
+struct VideoPacketDecoderFilter::Implementation : public FFMPEGFilterImpl<FFMPEGVideoPacket>\r
+{\r
+       void* process(FFMPEGVideoPacket* pVideoPacket)\r
+       {                                                               \r
+               if(pVideoPacket->codec->id == CODEC_ID_RAWVIDEO) \r
+                       utils::image::Shuffle(pVideoPacket->pFrame->GetDataPtr(), pVideoPacket->data, pVideoPacket->size, 3, 2, 1, 0);\r
+               else\r
+               {\r
+                       pVideoPacket->pDecodedFrame = framePool_.construct();\r
+\r
+                       int frameFinished = 0;\r
+                       int result = avcodec_decode_video(pVideoPacket->codecContext, pVideoPacket->pDecodedFrame.get(), &frameFinished, pVideoPacket->data, pVideoPacket->size);\r
+                       if(std::error_code errc = ffmpeg_make_averror_code(result))                                             \r
+                               pVideoPacket->pDecodedFrame.reset();                    \r
+               }\r
+\r
+               return pVideoPacket;            \r
+       }\r
+\r
+       bool is_valid(FFMPEGVideoPacket* pVideoPacket)\r
+       {\r
+               return pVideoPacket->codecContext != nullptr && pVideoPacket->data != nullptr && pVideoPacket->size > 0;\r
+       }\r
+\r
+       utils::object_pool<AVFrame, av_frame_allocator> framePool_; // NOTE: All frames need to be ref released before destruction\r
+};\r
+\r
+VideoPacketDecoderFilter::VideoPacketDecoderFilter()\r
+       : tbb::filter(serial_in_order), pImpl_(new Implementation())\r
+{\r
+}\r
+\r
+\r
+void* VideoPacketDecoderFilter::operator()(void* item)\r
+{\r
+       return (*pImpl_)(item);\r
+}\r
+\r
+void VideoPacketDecoderFilter::finalize(void* item)\r
+{\r
+       pImpl_->finalize(item);\r
+}\r
+\r
+       }\r
+}
\ No newline at end of file
diff --git a/server/producers/ffmpeg/video/FFMPEGVideoDecoder.h b/server/producers/ffmpeg/video/FFMPEGVideoDecoder.h
new file mode 100644 (file)
index 0000000..f33ae15
--- /dev/null
@@ -0,0 +1,80 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _FFMPEG_VIDEODECODER_H_\r
+#define _FFMPEG_VIDEODECODER_H_\r
+\r
+#include "..\FFMPEGPacket.h"\r
+\r
+#include "..\..\..\utils\Noncopyable.hpp"\r
+\r
+#include <tbb/pipeline.h>\r
+\r
+#include <memory>\r
+\r
+namespace caspar\r
+{\r
+       namespace ffmpeg\r
+       {\r
+typedef std::tr1::shared_ptr<AVCodecContext> AVCodecContextPtr;\r
+\r
+///=================================================================================================\r
+/// <summary>  Decodes video packets. </summary>\r
+///\r
+/// <remarks>  Rona 2010-06-19. </remarks>\r
+///=================================================================================================\r
+class VideoPacketDecoderFilter : public tbb::filter, private utils::Noncopyable\r
+{\r
+public:\r
+\r
+       ///=================================================================================================\r
+       /// <summary>   Default constructor. </summary>\r
+       ///\r
+       /// <remarks>   Rona 2010-06-19. </remarks>\r
+       ///=================================================================================================\r
+       VideoPacketDecoderFilter();\r
+\r
+       ///=================================================================================================\r
+       /// <summary>   Decodes video packet. </summary>\r
+       ///\r
+       /// <remarks>   Rona 2010-06-19. </remarks>\r
+       ///\r
+       /// <returns>   The result of the operation. </returns>\r
+       ///=================================================================================================\r
+       void* operator()(void* item);\r
+\r
+       ///=================================================================================================\r
+       /// <summary>   Destroys packet. </summary>\r
+       ///\r
+       /// <remarks>   Rona 2010-06-19. </remarks>\r
+       ///\r
+       /// <param name="item"> [in,out] If non-null, the item. </param>\r
+       ///=================================================================================================\r
+       void finalize(void* item);\r
+\r
+private:\r
+       struct Implementation;\r
+       std::tr1::shared_ptr<Implementation> pImpl_;\r
+};\r
+\r
+       }\r
+}\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/producers/ffmpeg/video/FFMPEGVideoDeinterlacer.cpp b/server/producers/ffmpeg/video/FFMPEGVideoDeinterlacer.cpp
new file mode 100644 (file)
index 0000000..c4a6e9a
--- /dev/null
@@ -0,0 +1,82 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "../../../stdafx.h"\r
+\r
+#include "FFMPEGVideoDeinterlacer.h"\r
+\r
+#include "../FFMPEGPacket.h"\r
+#include "../FFMPEGException.h"\r
+\r
+#include "../../../utils/image/Copy.hpp"\r
+#include "../../../utils/image/Image.hpp"\r
+\r
+#include <tbb/parallel_for.h>\r
+#include <tbb/atomic.h>\r
+#include <tbb/mutex.h>\r
+#include <tbb/concurrent_queue.h>\r
+\r
+#include <functional>\r
+\r
+\r
+using namespace std::tr1::placeholders;\r
+\r
+namespace caspar\r
+{\r
+       namespace ffmpeg\r
+       {\r
+               \r
+struct VideoPacketDeinterlacerFilter::Implementation : public FFMPEGFilterImpl<FFMPEGVideoPacket>\r
+{\r
+       void* process(FFMPEGVideoPacket* pVideoPacket)\r
+       {                               \r
+               std::error_code errc = ffmpeg_make_averror_code(avpicture_deinterlace(reinterpret_cast<AVPicture*>(pVideoPacket->pDecodedFrame.get()), reinterpret_cast<AVPicture*>(pVideoPacket->pDecodedFrame.get()), pVideoPacket->codecContext->pix_fmt, pVideoPacket->codecContext->width, pVideoPacket->codecContext->height));\r
+               if(errc) \r
+               {\r
+                       errc = ffmpeg_make_error_code(ffmpeg_errn::deinterlace_failed);\r
+                       return pVideoPacket; // TODO: Unsure if frame can become corrupted by failed deinterlace?\r
+               }\r
+                               \r
+               return pVideoPacket;    \r
+       }\r
+\r
+       bool is_valid(FFMPEGVideoPacket* pVideoPacket)\r
+       {\r
+               return pVideoPacket->pDecodedFrame != nullptr && pVideoPacket->pDecodedFrame->interlaced_frame;\r
+       }\r
+};\r
+\r
+VideoPacketDeinterlacerFilter::VideoPacketDeinterlacerFilter()\r
+       : tbb::filter(parallel), pImpl_(new Implementation())\r
+{\r
+}\r
+\r
+\r
+void* VideoPacketDeinterlacerFilter::operator()(void* item)\r
+{\r
+       return (*pImpl_)(item);\r
+}\r
+\r
+void VideoPacketDeinterlacerFilter::finalize(void* item)\r
+{\r
+       pImpl_->finalize(item);\r
+}\r
+       }\r
+}
\ No newline at end of file
diff --git a/server/producers/ffmpeg/video/FFMPEGVideoDeinterlacer.h b/server/producers/ffmpeg/video/FFMPEGVideoDeinterlacer.h
new file mode 100644 (file)
index 0000000..541a6c6
--- /dev/null
@@ -0,0 +1,76 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _FFMPEG_VIDEODEINTERLACER_H_\r
+#define _FFMPEG_VIDEODEINTERLACER_H_\r
+\r
+#include "../../../utils/Noncopyable.hpp"\r
+\r
+#include <tbb/pipeline.h>\r
+\r
+#include <memory>\r
+\r
+namespace caspar\r
+{\r
+       namespace ffmpeg\r
+       {\r
+///=================================================================================================\r
+/// <summary>  Deinterlaces video frames. </summary>\r
+///\r
+/// <remarks>  Rona 2010-06-19. This filter must be placed before FFMPEGVideoScaler. </remarks>\r
+///=================================================================================================\r
+class VideoPacketDeinterlacerFilter : public tbb::filter, private utils::Noncopyable\r
+{\r
+public:\r
+\r
+       ///=================================================================================================\r
+       /// <summary>   Default constructor. </summary>\r
+       ///\r
+       /// <remarks>   Rona 2010-06-19. </remarks>\r
+       ///=================================================================================================\r
+       VideoPacketDeinterlacerFilter();\r
+\r
+       ///=================================================================================================\r
+       /// <summary>   Deinterlaces video frame. </summary>\r
+       ///\r
+       /// <remarks>   Rona 2010-06-19. </remarks>\r
+       ///\r
+       /// <returns>   The result of the operation. </returns>\r
+       ///=================================================================================================\r
+       void* operator()(void* item);\r
+\r
+       ///=================================================================================================\r
+       /// <summary>   Destroys packet. </summary>\r
+       ///\r
+       /// <remarks>   Rona 2010-06-19. </remarks>\r
+       ///\r
+       /// <param name="item"> [in,out] If non-null, the item. </param>\r
+       ///=================================================================================================\r
+       void finalize(void* item);\r
+\r
+private:\r
+       struct Implementation;\r
+       std::tr1::shared_ptr<Implementation> pImpl_;\r
+};\r
+\r
+       }\r
+}\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/producers/ffmpeg/video/FFMPEGVideoScaler.cpp b/server/producers/ffmpeg/video/FFMPEGVideoScaler.cpp
new file mode 100644 (file)
index 0000000..90cc769
--- /dev/null
@@ -0,0 +1,151 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "../../../stdafx.h"\r
+\r
+#include "FFMPEGVideoScaler.h"\r
+\r
+#include "../FFMPEGException.h"\r
+\r
+#include "../../../utils/image/Copy.hpp"\r
+#include "../../../utils/image/Image.hpp"\r
+#include "../../../utils/object_pool.h"\r
+\r
+#include <functional>\r
+\r
+#include <tbb/parallel_for.h>\r
+#include <tbb/atomic.h>\r
+#include <tbb/mutex.h>\r
+#include <tbb/concurrent_queue.h>\r
+\r
+extern "C" \r
+{\r
+       #define __STDC_CONSTANT_MACROS\r
+       #define __STDC_LIMIT_MACROS\r
+       #include <libswscale/swscale.h>\r
+}\r
+\r
+using namespace std::tr1::placeholders;\r
+\r
+typedef std::shared_ptr<SwsContext> SwsContextPtr;\r
+\r
+namespace caspar\r
+{\r
+       namespace ffmpeg\r
+       {\r
+\r
+// TODO: Remove and do copy right into frame\r
+struct FillFrame\r
+{\r
+       FillFrame(size_t width, size_t height)\r
+       {\r
+               pFrame.reset(avcodec_alloc_frame(), av_free);           \r
+               if(pFrame == nullptr)\r
+                       throw ffmpeg_error(std::make_error_code(std::generic_errno::not_enough_memory));\r
+\r
+               size_t frameSize = width*height*4;\r
+               pBuffer.reset(allocator_.allocate(frameSize), [=](unsigned char* item){allocator_.deallocate(item, frameSize);});\r
+               avpicture_fill(reinterpret_cast<AVPicture*>(pFrame.get()), pBuffer.get(), PIX_FMT_BGRA, width, height);\r
+       }\r
+       AVFramePtr      pFrame;\r
+       BytePtr         pBuffer;\r
+\r
+       static tbb::cache_aligned_allocator<unsigned char> allocator_;\r
+};\r
+tbb::cache_aligned_allocator<unsigned char> FillFrame::allocator_;\r
+typedef std::shared_ptr<FillFrame> FillFramePtr;\r
+\r
+struct VideoPacketScalerFilter::Implementation : public FFMPEGFilterImpl<FFMPEGVideoPacket>\r
+{\r
+       void* process(FFMPEGVideoPacket* pVideoPacket)\r
+       {                               \r
+               auto pSWSContext = GetSWSContext(pVideoPacket->codecContext, pVideoPacket->frameFormat);\r
+               \r
+               //AVFrame avFrame;      \r
+               //avpicture_fill(reinterpret_cast<AVPicture*>(&avFrame), pVideoPacket->pFrame->GetDataPtr(), PIX_FMT_BGRA, pVideoPacket->frameFormat.width, pVideoPacket->frameFormat.height);\r
+               \r
+               auto pAVFrame = framePool_.construct(pVideoPacket->frameFormat.width, pVideoPacket->frameFormat.height);\r
+               int result = sws_scale(pSWSContext.get(), pVideoPacket->pDecodedFrame->data, pVideoPacket->pDecodedFrame->linesize, 0, codecContext_->height, pAVFrame->pFrame->data, pAVFrame->pFrame->linesize);\r
+               pVideoPacket->pDecodedFrame.reset(); // Free memory\r
+               \r
+               if(pVideoPacket->codec->id == CODEC_ID_DVVIDEO) // Move up one field\r
+               {\r
+                       size_t size = pVideoPacket->frameFormat.width * pVideoPacket->frameFormat.height * 4;\r
+                       size_t linesize = pVideoPacket->frameFormat.width * 4;\r
+                       utils::image::Copy(pVideoPacket->pFrame->GetDataPtr(), pAVFrame->pBuffer.get() + linesize, size - linesize);\r
+                       utils::image::Clear(pVideoPacket->pFrame->GetDataPtr() + size - linesize, linesize);\r
+               }\r
+               else\r
+               {\r
+                        // This copy should be unnecessary. But it seems that when mapping the frame memory to an avframe for scaling there are some artifacts in the picture. \r
+                       utils::image::Copy(pVideoPacket->pFrame->GetDataPtr(), pAVFrame->pBuffer.get(), pVideoPacket->pFrame->GetDataSize());\r
+               }\r
+\r
+               return pVideoPacket;    \r
+       }\r
+\r
+       SwsContextPtr GetSWSContext(AVCodecContext* codecContext, const FrameFormatDescription& frameFormat)\r
+       {\r
+               if(!pSWSContext_ || codecContext_ != codecContext || frameFormat_.width != frameFormat.width || frameFormat_.height != frameFormat.height)\r
+               {\r
+                       frameFormat_ = frameFormat;\r
+                       codecContext_ = codecContext;\r
+                       double param;\r
+                       pSWSContext_.reset(sws_getContext(codecContext_->width, codecContext_->height, codecContext_->pix_fmt, frameFormat_.width, frameFormat_.height, \r
+                                                                                               PIX_FMT_BGRA, SWS_BILINEAR, nullptr, nullptr, &param), sws_freeContext);\r
+                       if(pSWSContext_ == nullptr)\r
+                               throw ffmpeg_error(ffmpeg_make_error_code(ffmpeg_errn::sws_failure));\r
+               }\r
+               return pSWSContext_;\r
+       }\r
+\r
+       bool is_valid(FFMPEGVideoPacket* pVideoPacket)\r
+       {\r
+               return pVideoPacket->codecContext != nullptr &&  pVideoPacket->pDecodedFrame != nullptr;\r
+       }\r
+\r
+private:\r
+       FrameFormatDescription frameFormat_;\r
+       AVCodecContext* codecContext_;\r
+       SwsContextPtr pSWSContext_;\r
+       utils::object_pool<FillFrame> framePool_;\r
+};\r
+\r
+VideoPacketScalerFilter::VideoPacketScalerFilter()\r
+       : tbb::filter(serial_in_order), pImpl_(new Implementation())\r
+{\r
+}\r
+\r
+void* VideoPacketScalerFilter::operator()(void* item)\r
+{\r
+       return (*pImpl_)(item);\r
+}\r
+\r
+void VideoPacketScalerFilter::finalize(void* item)\r
+{\r
+       pImpl_->finalize(item);\r
+}\r
+\r
+       }\r
+}\r
+\r
+\r
+\r
+//     utils::image::Copy(pVideoPacket->pFrame->GetDataPtr(), pVideoPacket->pFrame->GetDataPtr(), size);
\ No newline at end of file
diff --git a/server/producers/ffmpeg/video/FFMPEGVideoScaler.h b/server/producers/ffmpeg/video/FFMPEGVideoScaler.h
new file mode 100644 (file)
index 0000000..6c7f4fa
--- /dev/null
@@ -0,0 +1,82 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _FFMPEG_VIDEOPROCESSOR_H_\r
+#define _FFMPEG_VIDEOPROCESSOR_H_\r
+\r
+#include "FFMPEGVideoDecoder.h"\r
+\r
+#include "../FFMPEGPacket.h"\r
+\r
+#include "../../../utils/Noncopyable.hpp"\r
+\r
+#include <tbb/pipeline.h>\r
+\r
+#include <memory>\r
+\r
+\r
+namespace caspar\r
+{\r
+       namespace ffmpeg\r
+       {\r
+\r
+///=================================================================================================\r
+/// <summary>  Scales video and transform color space to BGRA. </summary>\r
+///\r
+/// <remarks>  Rona 2010-06-19. Must run serially with VideoDecoder. </remarks>\r
+///=================================================================================================\r
+class VideoPacketScalerFilter : public tbb::filter, private utils::Noncopyable\r
+{\r
+public:\r
+\r
+       ///=================================================================================================\r
+       /// <summary>   Default constructor. </summary>\r
+       ///\r
+       /// <remarks>   Rona 2010-06-19. </remarks>\r
+       ///=================================================================================================\r
+       VideoPacketScalerFilter();\r
+\r
+       ///=================================================================================================\r
+       /// <summary>   Scales video and transform color space to BGRA. </summary>\r
+       ///\r
+       /// <remarks>   Rona 2010-06-19. </remarks>\r
+       ///\r
+       /// <returns>   The result of the operation. </returns>\r
+       ///=================================================================================================\r
+       void* operator()(void* item);\r
+\r
+       ///=================================================================================================\r
+       /// <summary>   Destroys packet. </summary>\r
+       ///\r
+       /// <remarks>   Rona 2010-06-19. </remarks>\r
+       ///\r
+       /// <param name="item"> [in,out] If non-null, the item. </param>\r
+       ///=================================================================================================\r
+       void finalize(void* item);\r
+\r
+private:\r
+       struct Implementation;\r
+       std::tr1::shared_ptr<Implementation> pImpl_;\r
+};\r
+\r
+       }\r
+}\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/producers/ffmpeg/video/FFMPEGVideoScaler2.cpp b/server/producers/ffmpeg/video/FFMPEGVideoScaler2.cpp
new file mode 100644 (file)
index 0000000..0720912
--- /dev/null
@@ -0,0 +1,95 @@
+#include "..\..\..\stdafx.h"\r
+\r
+#include "FFMPEGVideoScaler2.h"\r
+#include "..\FFMPEGException.h"\r
+\r
+#include "..\..\..\utils\image\Copy.hpp"\r
+#include "..\..\..\utils\image\Image.hpp"\r
+#include "..\..\..\utils\ObjectPool.h"\r
+\r
+#include <functional>\r
+\r
+#include <tbb/parallel_for.h>\r
+#include <tbb/atomic.h>\r
+#include <tbb/mutex.h>\r
+#include <tbb/concurrent_queue.h>\r
+#include <ffmpeg/swscale.h>\r
+\r
+#include "../../../utils/Types.hpp"\r
+\r
+using namespace std::tr1::placeholders;\r
+\r
+typedef std::shared_ptr<SwsContext> SwsContextPtr;\r
+\r
+namespace caspar\r
+{\r
+       namespace ffmpeg\r
+       {\r
+\r
+void Scale4_Bilinear_REF(void* dest, const void* source, size_t destWidth, size_t destHeight, size_t srcWidth, size_t srcHeight)\r
+{\r
+       const u8* source8 = reinterpret_cast<const u8*>(source);\r
+       u8* dest8 = reinterpret_cast<u8*>(dest);\r
+}\r
+                               \r
+struct VideoPacketScaler2Filter::Implementation\r
+{\r
+       void* operator()(void* item)\r
+       {               \r
+               if(item == nullptr)\r
+                       return nullptr;\r
+\r
+               FFMPEGPacket* pPacket = static_cast<FFMPEGPacket*>(item);\r
+\r
+               if(pPacket->type != FFMPEGVideoPacket::packet_type)\r
+                       return item;\r
+\r
+               FFMPEGVideoPacket* pVideoPacket = static_cast<FFMPEGVideoPacket*>(pPacket); \r
+\r
+               if(!is_valid(pVideoPacket)) \r
+                       return pVideoPacket;\r
+\r
+               return Scale(pVideoPacket);\r
+       }\r
+\r
+       void* Scale(FFMPEGVideoPacket* pVideoPacket)\r
+       {               \r
+               return pVideoPacket;            \r
+       }\r
+\r
+       void finalize(void* item)\r
+       {\r
+               delete static_cast<FFMPEGPacket*>(item);\r
+       }       \r
+       \r
+       bool is_valid(FFMPEGVideoPacket* pVideoPacket)\r
+       {\r
+               return pVideoPacket->pDecodedFrame != nullptr && \r
+                          pVideoPacket->pFrame == nullptr &&\r
+                          pVideoPacket->codecContext != nullptr && \r
+                          pVideoPacket->codec != nullptr && \r
+                          Supports(pVideoPacket->codecContext, pVideoPacket->frameFormat);\r
+       }\r
+\r
+private:\r
+       FrameFormatDescription frameFormat_;\r
+       AVCodecContext* codecContext_;\r
+};\r
+\r
+VideoPacketScaler2Filter::VideoPacketScaler2Filter()\r
+       : tbb::filter(parallel), pImpl_(new Implementation())\r
+{\r
+}\r
+\r
+void* VideoPacketScaler2Filter::operator()(void* item)\r
+{\r
+       return (*pImpl_)(item);\r
+}\r
+\r
+void VideoPacketScaler2Filter::finalize(void* item)\r
+{\r
+       pImpl_->finalize(item);\r
+}\r
+\r
+       }\r
+}
\ No newline at end of file
diff --git a/server/producers/ffmpeg/video/FFMPEGVideoScaler2.h b/server/producers/ffmpeg/video/FFMPEGVideoScaler2.h
new file mode 100644 (file)
index 0000000..4874347
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef _FFMPEG_VIDEO_SCALER2_H_\r
+#define _FFMPEG_VIDEO_SCALER2_H_\r
+\r
+#include "..\FFMPEGPacket.h"\r
+#include "FFMPEGVideoDecoder.h"\r
+\r
+#include <memory>\r
+\r
+#include <tbb/pipeline.h>\r
+\r
+#include "..\..\..\frame\Frame.h"\r
+#include "..\..\..\utils\Noncopyable.hpp"\r
+\r
+namespace caspar\r
+{\r
+       namespace ffmpeg\r
+       {\r
+\r
+class VideoPacketScaler2Filter : public tbb::filter, private utils::Noncopyable\r
+{\r
+public:\r
+\r
+       VideoPacketScaler2Filter();\r
+\r
+       void* operator()(void* item);\r
+       void finalize(void* item);\r
+\r
+       static bool Supports(AVCodecContext* codecContext, const FrameFormatDescription& frameFormat)\r
+       {\r
+               switch(codecContext->pix_fmt)\r
+               {\r
+               //case PIX_FMT_RGB24:\r
+               //      return true;\r
+               default:\r
+                       return false;\r
+               }               \r
+       }\r
+\r
+private:\r
+       struct Implementation;\r
+       std::tr1::shared_ptr<Implementation> pImpl_;\r
+};\r
+\r
+       }\r
+}\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/producers/flash/CTManager.cpp b/server/producers/flash/CTManager.cpp
new file mode 100644 (file)
index 0000000..860a9fe
--- /dev/null
@@ -0,0 +1,74 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\..\stdafx.h"\r
+\r
+#include "..\..\frame\FrameManager.h"\r
+#include "..\..\frame\FrameMediaController.h"\r
+#include "..\..\utils\FileInputStream.h"\r
+#include "..\..\fileinfo.h"\r
+#include "CTManager.h"\r
+#include "FlashProducer.h"\r
+#include "..\..\cg\FlashCGProxy.h"\r
+\r
+namespace caspar {\r
+\r
+using namespace caspar::utils;\r
+using namespace caspar::CG;\r
+\r
+//////////////////////////////\r
+//  CTManager definition\r
+//\r
+CTManager::CTManager()\r
+{\r
+       _extensions.push_back(TEXT("ct"));\r
+}\r
+\r
+CTManager::~CTManager()\r
+{}\r
+\r
+MediaProducerPtr CTManager::CreateProducer(const tstring& filename) {\r
+       tstring fixedFilename = filename;\r
+       tstring::size_type pos = 0;\r
+       while((pos = fixedFilename.find(TEXT('\\'), pos)) != tstring::npos) {\r
+               fixedFilename[pos] = TEXT('/');\r
+       }\r
+       MediaProducerPtr result;\r
+       FlashCGProxyPtr pCGProxy(FlashCGProxy::Create());\r
+       if(pCGProxy) {\r
+               pCGProxy->Add(0, filename, 1);\r
+               result = pCGProxy->GetFlashProducer();\r
+       }\r
+\r
+       return result;\r
+}\r
+\r
+bool CTManager::getFileInfo(FileInfo* pFileInfo)\r
+{\r
+       if(pFileInfo != 0) {\r
+               pFileInfo->length = 1;\r
+               pFileInfo->type = TEXT("movie");\r
+               pFileInfo->encoding = TEXT("ct");\r
+               return true;\r
+       }\r
+       return false;\r
+}\r
+\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/producers/flash/CTManager.h b/server/producers/flash/CTManager.h
new file mode 100644 (file)
index 0000000..993aace
--- /dev/null
@@ -0,0 +1,40 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+\r
+#include "..\..\frame\Frame.h"\r
+#include "..\..\MediaManager.h"\r
+\r
+namespace caspar {\r
+\r
+class FileInfo;\r
+\r
+class CTManager : public IMediaManager\r
+{\r
+public:\r
+       CTManager();\r
+       virtual ~CTManager();\r
+\r
+       virtual MediaProducerPtr CreateProducer(const tstring& filename);\r
+       virtual bool getFileInfo(FileInfo* pFileInfo);\r
+};\r
+\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/producers/flash/Flash9e.IDL b/server/producers/flash/Flash9e.IDL
new file mode 100644 (file)
index 0000000..c85a3bb
--- /dev/null
@@ -0,0 +1,367 @@
+// Generated .IDL file (by the OLE/COM Object Viewer)\r
+// \r
+// typelib filename: Flash9e.ocx\r
+\r
+[\r
+  uuid(D27CDB6B-AE6D-11CF-96B8-444553540000),\r
+  version(1.0),\r
+  helpstring("Shockwave Flash"),\r
+  custom(DE77BA64-517C-11D1-A2DA-0000F8773CE9, 100663662),\r
+  custom(DE77BA63-517C-11D1-A2DA-0000F8773CE9, 1180654890)\r
+\r
+]\r
+library ShockwaveFlashObjects\r
+{\r
+    // TLib :     // TLib : OLE Automation : {00020430-0000-0000-C000-000000000046}\r
+    importlib("stdole2.tlb");\r
+\r
+    // Forward declare all types defined in this typelib\r
+    interface IShockwaveFlash;\r
+    dispinterface _IShockwaveFlashEvents;\r
+    interface IFlashFactory;\r
+    interface IFlashObjectInterface;\r
+    interface IDispatchEx;\r
+    interface IServiceProvider;\r
+\r
+    [\r
+      odl,\r
+      uuid(D27CDB6C-AE6D-11CF-96B8-444553540000),\r
+      helpstring("Shockwave Flash"),\r
+      dual,\r
+      oleautomation\r
+    ]\r
+    interface IShockwaveFlash : IDispatch {\r
+        [id(0xfffffdf3), propget, helpstring("property ReadyState")]\r
+        HRESULT ReadyState([out, retval] long* pVal);\r
+        [id(0x0000007c), propget, helpstring("property TotalFrames")]\r
+        HRESULT TotalFrames([out, retval] long* pVal);\r
+        [id(0x0000007d), propget, helpstring("property Playing")]\r
+        HRESULT Playing([out, retval] VARIANT_BOOL* pVal);\r
+        [id(0x0000007d), propput, helpstring("property Playing")]\r
+        HRESULT Playing([in] VARIANT_BOOL pVal);\r
+        [id(0x00000069), propget, helpstring("property Quality")]\r
+        HRESULT Quality([out, retval] int* pVal);\r
+        [id(0x00000069), propput, helpstring("property Quality")]\r
+        HRESULT Quality([in] int pVal);\r
+        [id(0x00000078), propget, helpstring("property ScaleMode")]\r
+        HRESULT ScaleMode([out, retval] int* pVal);\r
+        [id(0x00000078), propput, helpstring("property ScaleMode")]\r
+        HRESULT ScaleMode([in] int pVal);\r
+        [id(0x00000079), propget, helpstring("property AlignMode")]\r
+        HRESULT AlignMode([out, retval] int* pVal);\r
+        [id(0x00000079), propput, helpstring("property AlignMode")]\r
+        HRESULT AlignMode([in] int pVal);\r
+        [id(0x0000007b), propget, helpstring("property BackgroundColor")]\r
+        HRESULT BackgroundColor([out, retval] long* pVal);\r
+        [id(0x0000007b), propput, helpstring("property BackgroundColor")]\r
+        HRESULT BackgroundColor([in] long pVal);\r
+        [id(0x0000006a), propget, helpstring("property Loop")]\r
+        HRESULT Loop([out, retval] VARIANT_BOOL* pVal);\r
+        [id(0x0000006a), propput, helpstring("property Loop")]\r
+        HRESULT Loop([in] VARIANT_BOOL pVal);\r
+        [id(0x00000066), propget, helpstring("property Movie")]\r
+        HRESULT Movie([out, retval] BSTR* pVal);\r
+        [id(0x00000066), propput, helpstring("property Movie")]\r
+        HRESULT Movie([in] BSTR pVal);\r
+        [id(0x0000006b), propget, helpstring("property FrameNum")]\r
+        HRESULT FrameNum([out, retval] long* pVal);\r
+        [id(0x0000006b), propput, helpstring("property FrameNum")]\r
+        HRESULT FrameNum([in] long pVal);\r
+        [id(0x0000006d), helpstring("method SetZoomRect")]\r
+        HRESULT SetZoomRect(\r
+                        [in] long left, \r
+                        [in] long top, \r
+                        [in] long right, \r
+                        [in] long bottom);\r
+        [id(0x00000076), helpstring("method Zoom")]\r
+        HRESULT Zoom([in] int factor);\r
+        [id(0x00000077), helpstring("method Pan")]\r
+        HRESULT Pan(\r
+                        [in] long x, \r
+                        [in] long y, \r
+                        [in] int mode);\r
+        [id(0x00000070), helpstring("method Play")]\r
+        HRESULT Play();\r
+        [id(0x00000071), helpstring("method Stop")]\r
+        HRESULT Stop();\r
+        [id(0x00000072), helpstring("method Back")]\r
+        HRESULT Back();\r
+        [id(0x00000073), helpstring("method Forward")]\r
+        HRESULT Forward();\r
+        [id(0x00000074), helpstring("method Rewind")]\r
+        HRESULT Rewind();\r
+        [id(0x0000007e), helpstring("method StopPlay")]\r
+        HRESULT StopPlay();\r
+        [id(0x0000007f), helpstring("method GotoFrame")]\r
+        HRESULT GotoFrame([in] long FrameNum);\r
+        [id(0x00000080), helpstring("method CurrentFrame")]\r
+        HRESULT CurrentFrame([out, retval] long* FrameNum);\r
+        [id(0x00000081), helpstring("method IsPlaying")]\r
+        HRESULT IsPlaying([out, retval] VARIANT_BOOL* Playing);\r
+        [id(0x00000082), helpstring("method PercentLoaded")]\r
+        HRESULT PercentLoaded([out, retval] long* percent);\r
+        [id(0x00000083), helpstring("method FrameLoaded")]\r
+        HRESULT FrameLoaded(\r
+                        [in] long FrameNum, \r
+                        [out, retval] VARIANT_BOOL* loaded);\r
+        [id(0x00000084), helpstring("method FlashVersion")]\r
+        HRESULT FlashVersion([out, retval] long* version);\r
+        [id(0x00000085), propget, helpstring("property WMode")]\r
+        HRESULT WMode([out, retval] BSTR* pVal);\r
+        [id(0x00000085), propput, helpstring("property WMode")]\r
+        HRESULT WMode([in] BSTR pVal);\r
+        [id(0x00000086), propget, helpstring("property SAlign")]\r
+        HRESULT SAlign([out, retval] BSTR* pVal);\r
+        [id(0x00000086), propput, helpstring("property SAlign")]\r
+        HRESULT SAlign([in] BSTR pVal);\r
+        [id(0x00000087), propget, helpstring("property Menu")]\r
+        HRESULT Menu([out, retval] VARIANT_BOOL* pVal);\r
+        [id(0x00000087), propput, helpstring("property Menu")]\r
+        HRESULT Menu([in] VARIANT_BOOL pVal);\r
+        [id(0x00000088), propget, helpstring("property Base")]\r
+        HRESULT Base([out, retval] BSTR* pVal);\r
+        [id(0x00000088), propput, helpstring("property Base")]\r
+        HRESULT Base([in] BSTR pVal);\r
+        [id(0x00000089), propget, helpstring("property Scale")]\r
+        HRESULT Scale([out, retval] BSTR* pVal);\r
+        [id(0x00000089), propput, helpstring("property Scale")]\r
+        HRESULT Scale([in] BSTR pVal);\r
+        [id(0x0000008a), propget, helpstring("property DeviceFont")]\r
+        HRESULT DeviceFont([out, retval] VARIANT_BOOL* pVal);\r
+        [id(0x0000008a), propput, helpstring("property DeviceFont")]\r
+        HRESULT DeviceFont([in] VARIANT_BOOL pVal);\r
+        [id(0x0000008b), propget, helpstring("property EmbedMovie")]\r
+        HRESULT EmbedMovie([out, retval] VARIANT_BOOL* pVal);\r
+        [id(0x0000008b), propput, helpstring("property EmbedMovie")]\r
+        HRESULT EmbedMovie([in] VARIANT_BOOL pVal);\r
+        [id(0x0000008c), propget, helpstring("property BGColor")]\r
+        HRESULT BGColor([out, retval] BSTR* pVal);\r
+        [id(0x0000008c), propput, helpstring("property BGColor")]\r
+        HRESULT BGColor([in] BSTR pVal);\r
+        [id(0x0000008d), propget, helpstring("property Quality2")]\r
+        HRESULT Quality2([out, retval] BSTR* pVal);\r
+        [id(0x0000008d), propput, helpstring("property Quality2")]\r
+        HRESULT Quality2([in] BSTR pVal);\r
+        [id(0x0000008e), helpstring("method LoadMovie")]\r
+        HRESULT LoadMovie(\r
+                        [in] int layer, \r
+                        [in] BSTR url);\r
+        [id(0x0000008f), helpstring("method TGotoFrame")]\r
+        HRESULT TGotoFrame(\r
+                        [in] BSTR target, \r
+                        [in] long FrameNum);\r
+        [id(0x00000090), helpstring("method TGotoLabel")]\r
+        HRESULT TGotoLabel(\r
+                        [in] BSTR target, \r
+                        [in] BSTR label);\r
+        [id(0x00000091), helpstring("method TCurrentFrame")]\r
+        HRESULT TCurrentFrame(\r
+                        [in] BSTR target, \r
+                        [out, retval] long* FrameNum);\r
+        [id(0x00000092), helpstring("method TCurrentLabel")]\r
+        HRESULT TCurrentLabel(\r
+                        [in] BSTR target, \r
+                        [out, retval] BSTR* pVal);\r
+        [id(0x00000093), helpstring("method TPlay")]\r
+        HRESULT TPlay([in] BSTR target);\r
+        [id(0x00000094), helpstring("method TStopPlay")]\r
+        HRESULT TStopPlay([in] BSTR target);\r
+        [id(0x00000097), helpstring("method SetVariable")]\r
+        HRESULT SetVariable(\r
+                        [in] BSTR name, \r
+                        [in] BSTR value);\r
+        [id(0x00000098), helpstring("method GetVariable")]\r
+        HRESULT GetVariable(\r
+                        [in] BSTR name, \r
+                        [out, retval] BSTR* pVal);\r
+        [id(0x00000099), helpstring("method TSetProperty")]\r
+        HRESULT TSetProperty(\r
+                        [in] BSTR target, \r
+                        [in] int property, \r
+                        [in] BSTR value);\r
+        [id(0x0000009a), helpstring("method TGetProperty")]\r
+        HRESULT TGetProperty(\r
+                        [in] BSTR target, \r
+                        [in] int property, \r
+                        [out, retval] BSTR* pVal);\r
+        [id(0x0000009b), helpstring("method TCallFrame")]\r
+        HRESULT TCallFrame(\r
+                        [in] BSTR target, \r
+                        [in] int FrameNum);\r
+        [id(0x0000009c), helpstring("method TCallLabel")]\r
+        HRESULT TCallLabel(\r
+                        [in] BSTR target, \r
+                        [in] BSTR label);\r
+        [id(0x0000009d), helpstring("method TSetPropertyNum")]\r
+        HRESULT TSetPropertyNum(\r
+                        [in] BSTR target, \r
+                        [in] int property, \r
+                        [in] double value);\r
+        [id(0x0000009e), helpstring("method TGetPropertyNum")]\r
+        HRESULT TGetPropertyNum(\r
+                        [in] BSTR target, \r
+                        [in] int property, \r
+                        [out, retval] double* pVal);\r
+        [id(0x000000ac), helpstring("method TGetPropertyAsNumber")]\r
+        HRESULT TGetPropertyAsNumber(\r
+                        [in] BSTR target, \r
+                        [in] int property, \r
+                        [out, retval] double* pVal);\r
+        [id(0x0000009f), propget, helpstring("property SWRemote")]\r
+        HRESULT SWRemote([out, retval] BSTR* pVal);\r
+        [id(0x0000009f), propput, helpstring("property SWRemote")]\r
+        HRESULT SWRemote([in] BSTR pVal);\r
+        [id(0x000000aa), propget, helpstring("property FlashVars")]\r
+        HRESULT FlashVars([out, retval] BSTR* pVal);\r
+        [id(0x000000aa), propput, helpstring("property FlashVars")]\r
+        HRESULT FlashVars([in] BSTR pVal);\r
+        [id(0x000000ab), propget, helpstring("property AllowScriptAccess")]\r
+        HRESULT AllowScriptAccess([out, retval] BSTR* pVal);\r
+        [id(0x000000ab), propput, helpstring("property AllowScriptAccess")]\r
+        HRESULT AllowScriptAccess([in] BSTR pVal);\r
+        [id(0x000000be), propget, helpstring("property MovieData")]\r
+        HRESULT MovieData([out, retval] BSTR* pVal);\r
+        [id(0x000000be), propput, helpstring("property MovieData")]\r
+        HRESULT MovieData([in] BSTR pVal);\r
+        [id(0x000000bf), propget, helpstring("property inline-data")]\r
+        HRESULT InlineData([out, retval] IUnknown** ppIUnknown);\r
+        [id(0x000000bf), propput, helpstring("property inline-data")]\r
+        HRESULT InlineData([in] IUnknown* ppIUnknown);\r
+        [id(0x000000c0), propget, helpstring("property SeamlessTabbing")]\r
+        HRESULT SeamlessTabbing([out, retval] VARIANT_BOOL* pVal);\r
+        [id(0x000000c0), propput, helpstring("property SeamlessTabbing")]\r
+        HRESULT SeamlessTabbing([in] VARIANT_BOOL pVal);\r
+        [id(0x000000c1), helpstring("method EnforceLocalSecurity")]\r
+        HRESULT EnforceLocalSecurity();\r
+        [id(0x000000c2), propget, helpstring("property Profile")]\r
+        HRESULT Profile([out, retval] VARIANT_BOOL* pVal);\r
+        [id(0x000000c2), propput, helpstring("property Profile")]\r
+        HRESULT Profile([in] VARIANT_BOOL pVal);\r
+        [id(0x000000c3), propget, helpstring("property ProfileAddress")]\r
+        HRESULT ProfileAddress([out, retval] BSTR* pVal);\r
+        [id(0x000000c3), propput, helpstring("property ProfileAddress")]\r
+        HRESULT ProfileAddress([in] BSTR pVal);\r
+        [id(0x000000c4), propget, helpstring("property ProfilePort")]\r
+        HRESULT ProfilePort([out, retval] long* pVal);\r
+        [id(0x000000c4), propput, helpstring("property ProfilePort")]\r
+        HRESULT ProfilePort([in] long pVal);\r
+        [id(0x000000c6), helpstring("method Call")]\r
+        HRESULT CallFunction(\r
+                        [in] BSTR request, \r
+                        [out, retval] BSTR* response);\r
+        [id(0x000000c7), helpstring("method SetReturnValue")]\r
+        HRESULT SetReturnValue([in] BSTR returnValue);\r
+        [id(0x000000c8), helpstring("method DisableLocalSecurity")]\r
+        HRESULT DisableLocalSecurity();\r
+        [id(0x000000c9), propget, helpstring("property AllowNetworking")]\r
+        HRESULT AllowNetworking([out, retval] BSTR* pVal);\r
+        [id(0x000000c9), propput, helpstring("property AllowNetworking")]\r
+        HRESULT AllowNetworking([in] BSTR pVal);\r
+        [id(0x000000ca), propget, helpstring("property AllowFullScreen")]\r
+        HRESULT AllowFullScreen([out, retval] BSTR* pVal);\r
+        [id(0x000000ca), propput, helpstring("property AllowFullScreen")]\r
+        HRESULT AllowFullScreen([in] BSTR pVal);\r
+    };\r
+\r
+    [\r
+      uuid(D27CDB6D-AE6D-11CF-96B8-444553540000),\r
+      helpstring("Event interface for Shockwave Flash"),\r
+         hidden\r
+    ]\r
+    dispinterface _IShockwaveFlashEvents {\r
+        properties:\r
+        methods:\r
+            [id(0xfffffd9f)]\r
+            void OnReadyStateChange(long newState);\r
+            [id(0x000007a6)]\r
+            void OnProgress(long percentDone);\r
+            [id(0x00000096)]\r
+            void FSCommand(\r
+                            [in] BSTR command, \r
+                            [in] BSTR args);\r
+            [id(0x000000c5)]\r
+            void FlashCall([in] BSTR request);\r
+    };\r
+\r
+    [\r
+      uuid(D27CDB6E-AE6D-11CF-96B8-444553540000),\r
+      helpstring("Shockwave Flash")\r
+    ]\r
+    coclass ShockwaveFlash {\r
+        [default] interface IShockwaveFlash;\r
+        [default, source] dispinterface _IShockwaveFlashEvents;\r
+    };\r
+\r
+    [\r
+      odl,\r
+      uuid(D27CDB70-AE6D-11CF-96B8-444553540000),\r
+      helpstring("IFlashFactory Interface")\r
+    ]\r
+    interface IFlashFactory : IUnknown {\r
+    };\r
+\r
+    [\r
+      odl,\r
+      uuid(D27CDB72-AE6D-11CF-96B8-444553540000),\r
+      helpstring("IFlashObjectInterface Interface")\r
+    ]\r
+    interface IFlashObjectInterface : IDispatchEx {\r
+    };\r
+\r
+    [\r
+      odl,\r
+      uuid(A6EF9860-C720-11D0-9337-00A0C90DCAA9)\r
+    ]\r
+    interface IDispatchEx : IDispatch {\r
+        HRESULT _stdcall GetDispID(\r
+                        [in] BSTR bstrName, \r
+                        [in] unsigned long grfdex, \r
+                        [out] long* pid);\r
+        HRESULT _stdcall RemoteInvokeEx(\r
+                        [in] long id, \r
+                        [in] unsigned long lcid, \r
+                        [in] unsigned long dwFlags, \r
+                        [in] DISPPARAMS* pdp, \r
+                        [out] VARIANT* pvarRes, \r
+                        [out] EXCEPINFO* pei, \r
+                        [in] IServiceProvider* pspCaller, \r
+                        [in] unsigned int cvarRefArg, \r
+                        [in] unsigned int* rgiRefArg, \r
+                        [in, out] VARIANT* rgvarRefArg);\r
+        HRESULT _stdcall DeleteMemberByName(\r
+                        [in] BSTR bstrName, \r
+                        [in] unsigned long grfdex);\r
+        HRESULT _stdcall DeleteMemberByDispID([in] long id);\r
+        HRESULT _stdcall GetMemberProperties(\r
+                        [in] long id, \r
+                        [in] unsigned long grfdexFetch, \r
+                        [out] unsigned long* pgrfdex);\r
+        HRESULT _stdcall GetMemberName(\r
+                        [in] long id, \r
+                        [out] BSTR* pbstrName);\r
+        HRESULT _stdcall GetNextDispID(\r
+                        [in] unsigned long grfdex, \r
+                        [in] long id, \r
+                        [out] long* pid);\r
+        HRESULT _stdcall GetNameSpaceParent([out] IUnknown** ppunk);\r
+    };\r
+\r
+    [\r
+      odl,\r
+      uuid(6D5140C1-7436-11CE-8034-00AA006009FA)\r
+    ]\r
+    interface IServiceProvider : IUnknown {\r
+        HRESULT _stdcall RemoteQueryService(\r
+                        [in] GUID* guidService, \r
+                        [in] GUID* riid, \r
+                        [out] IUnknown** ppvObject);\r
+    };\r
+\r
+    [\r
+      uuid(D27CDB71-AE6D-11CF-96B8-444553540000),\r
+      helpstring("IFlashObjectInterface Interface")\r
+    ]\r
+    coclass FlashObjectInterface {\r
+        [default] interface IFlashObjectInterface;\r
+    };\r
+};\r
diff --git a/server/producers/flash/Flash9e_i.c b/server/producers/flash/Flash9e_i.c
new file mode 100644 (file)
index 0000000..3cc610e
--- /dev/null
@@ -0,0 +1,103 @@
+\r
+\r
+/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */\r
+\r
+/* link this file in with the server and any clients */\r
+\r
+\r
+ /* File created by MIDL compiler version 6.00.0366 */\r
+/* at Tue Mar 18 13:05:00 2008\r
+ */\r
+/* Compiler settings for .\flash\Flash9e.IDL:\r
+    Oicf, W4, Zp8, env=Win32 (32b run)\r
+    protocol : dce , ms_ext, c_ext, robust\r
+    error checks: allocation ref bounds_check enum stub_data \r
+    VC __declspec() decoration level: \r
+         __declspec(uuid()), __declspec(selectany), __declspec(novtable)\r
+         DECLSPEC_UUID(), MIDL_INTERFACE()\r
+*/\r
+//@@MIDL_FILE_HEADING(  )\r
+\r
+#pragma warning( disable: 4049 )  /* more than 64k source lines */\r
+\r
+\r
+#ifdef __cplusplus\r
+extern "C"{\r
+#endif \r
+\r
+\r
+#include <rpc.h>\r
+#include <rpcndr.h>\r
+\r
+#ifdef _MIDL_USE_GUIDDEF_\r
+\r
+#ifndef INITGUID\r
+#define INITGUID\r
+#include <guiddef.h>\r
+#undef INITGUID\r
+#else\r
+#include <guiddef.h>\r
+#endif\r
+\r
+#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \\r
+        DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8)\r
+\r
+#else // !_MIDL_USE_GUIDDEF_\r
+\r
+#ifndef __IID_DEFINED__\r
+#define __IID_DEFINED__\r
+\r
+typedef struct _IID\r
+{\r
+    unsigned long x;\r
+    unsigned short s1;\r
+    unsigned short s2;\r
+    unsigned char  c[8];\r
+} IID;\r
+\r
+#endif // __IID_DEFINED__\r
+\r
+#ifndef CLSID_DEFINED\r
+#define CLSID_DEFINED\r
+typedef IID CLSID;\r
+#endif // CLSID_DEFINED\r
+\r
+#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \\r
+        const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}\r
+\r
+#endif !_MIDL_USE_GUIDDEF_\r
+\r
+MIDL_DEFINE_GUID(IID, LIBID_ShockwaveFlashObjects,0xD27CDB6B,0xAE6D,0x11CF,0x96,0xB8,0x44,0x45,0x53,0x54,0x00,0x00);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IShockwaveFlash,0xD27CDB6C,0xAE6D,0x11CF,0x96,0xB8,0x44,0x45,0x53,0x54,0x00,0x00);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, DIID__IShockwaveFlashEvents,0xD27CDB6D,0xAE6D,0x11CF,0x96,0xB8,0x44,0x45,0x53,0x54,0x00,0x00);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IFlashFactory,0xD27CDB70,0xAE6D,0x11CF,0x96,0xB8,0x44,0x45,0x53,0x54,0x00,0x00);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IDispatchEx,0xA6EF9860,0xC720,0x11D0,0x93,0x37,0x00,0xA0,0xC9,0x0D,0xCA,0xA9);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IFlashObjectInterface,0xD27CDB72,0xAE6D,0x11CF,0x96,0xB8,0x44,0x45,0x53,0x54,0x00,0x00);\r
+\r
+\r
+MIDL_DEFINE_GUID(IID, IID_IServiceProvider,0x6D5140C1,0x7436,0x11CE,0x80,0x34,0x00,0xAA,0x00,0x60,0x09,0xFA);\r
+\r
+\r
+MIDL_DEFINE_GUID(CLSID, CLSID_ShockwaveFlash,0xD27CDB6E,0xAE6D,0x11CF,0x96,0xB8,0x44,0x45,0x53,0x54,0x00,0x00);\r
+\r
+\r
+MIDL_DEFINE_GUID(CLSID, CLSID_FlashObjectInterface,0xD27CDB71,0xAE6D,0x11CF,0x96,0xB8,0x44,0x45,0x53,0x54,0x00,0x00);\r
+\r
+#undef MIDL_DEFINE_GUID\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+\r
+\r
diff --git a/server/producers/flash/FlashAxContainer.cpp b/server/producers/flash/FlashAxContainer.cpp
new file mode 100644 (file)
index 0000000..9f619e2
--- /dev/null
@@ -0,0 +1,835 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\..\stdafx.h"\r
+\r
+#include "FlashAxContainer.h"\r
+#include "..\..\application.h"\r
+#include "..\..\window.h"\r
+#include "..\..\monitor.h"\r
+#include "flashproducer.h"\r
+#include "TimerHelper.h"\r
+\r
+using namespace ATL;\r
+\r
+namespace caspar {\r
+namespace flash {\r
+\r
+CComBSTR FlashAxContainer::flashGUID_(_T("{D27CDB6E-AE6D-11CF-96B8-444553540000}"));\r
+\r
+_ATL_FUNC_INFO fnInfoFlashCallEvent = { CC_STDCALL, VT_EMPTY, 1, { VT_BSTR } };\r
+_ATL_FUNC_INFO fnInfoReadyStateChangeEvent = { CC_STDCALL, VT_EMPTY, 1, { VT_I4 } };\r
+\r
+FlashAxContainer::FlashAxContainer() : pFlashProducer_(0), bInPlaceActive_(FALSE), pTimerHelper(0), bInvalidRect_(false), bReadyToRender_(false), bHasNewTiming_(false)\r
+{\r
+}\r
+FlashAxContainer::~FlashAxContainer()\r
+{\r
+//     ReleaseAll();\r
+\r
+       if(pTimerHelper != 0)\r
+               delete pTimerHelper;\r
+}\r
+\r
+\r
+///////////////////\r
+// IObjectWithSite\r
+///////////////////\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::SetSite(IUnknown* pUnkSite)\r
+{\r
+       ATLTRACE(_T("IObjectWithSite::SetSite\n"));\r
+       HRESULT hr = IObjectWithSiteImpl<FlashAxContainer>::SetSite(pUnkSite);\r
+\r
+       if (SUCCEEDED(hr) && m_spUnkSite)\r
+       {\r
+               // Look for "outer" IServiceProvider\r
+               hr = m_spUnkSite->QueryInterface(__uuidof(IServiceProvider), (void**)&m_spServices);\r
+               ATLASSERT( !hr && _T("No ServiceProvider!") );\r
+       }\r
+\r
+       if (pUnkSite == NULL)\r
+               m_spServices.Release();\r
+\r
+       return hr;\r
+}\r
+\r
+///////////////////\r
+// IOleClientSite\r
+///////////////////\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::SaveObject()\r
+{\r
+       ATLTRACENOTIMPL(_T("IOleClientSite::SaveObject"));\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker** ppmk)\r
+{\r
+/*     if(*ppmk != NULL) {\r
+               if(m_spMyMoniker == NULL) {\r
+                       ATL::CComObject<MyMoniker>* pMoniker = NULL;\r
+                       HRESULT hr = ATL::CComObject<MyMoniker>::CreateInstance(&pMoniker);\r
+                       if(SUCCEEDED(hr))\r
+                               m_spMyMoniker = pMoniker;\r
+               }\r
+\r
+               if(m_spMyMoniker != NULL) {\r
+                       *ppmk = m_spMyMoniker;\r
+                       (*ppmk)->AddRef();\r
+                       return S_OK;\r
+               }\r
+       }\r
+*/     if(ppmk != NULL)\r
+               *ppmk = NULL;\r
+       return E_FAIL;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::GetContainer(IOleContainer** ppContainer)\r
+{\r
+       ATLTRACE(_T("IOleClientSite::GetContainer\n"));\r
+       (*ppContainer) = NULL;\r
+       return E_NOINTERFACE;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::ShowObject()\r
+{\r
+       ATLTRACE(_T("IOleClientSite::ShowObject\n"));\r
+       return S_OK;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::OnShowWindow(BOOL fShow)\r
+{\r
+       ATLTRACE(_T("IOleClientSite::OnShowWindow"));\r
+       return S_OK;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::RequestNewObjectLayout()\r
+{\r
+       ATLTRACE(_T("IOleClientSite::RequestNewObjectLayout"));\r
+       return S_OK;\r
+}\r
+\r
+///////////////////\r
+// IOleInPlaceSite\r
+///////////////////\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::GetWindow(HWND* pHwnd)\r
+{\r
+       ATLTRACE(_T("IOleInPlaceSite::GetWindow\n"));\r
+       (*pHwnd) = NULL;//GetApplication()->GetMainWindow()->getHwnd();\r
+       return E_FAIL;\r
+}\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::ContextSensitiveHelp(BOOL fEnterMode)\r
+{\r
+       ATLTRACE(_T("IOleInPlaceSite::ContextSensitiveHelp"));\r
+       return S_OK;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::CanInPlaceActivate()\r
+{\r
+       ATLTRACE(_T("IOleInPlaceSite::CanInPlaceActivate\n"));\r
+       return S_OK;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::OnInPlaceActivate()\r
+{\r
+       ATLTRACE(_T("IOleInPlaceSite::OnInPlaceActivate"));\r
+       return S_OK;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::OnUIActivate()\r
+{\r
+       ATLTRACE(_T("IOleInPlaceSite::OnUIActivate\n"));\r
+       bUIActive_ = TRUE;\r
+       return S_OK;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::GetWindowContext(IOleInPlaceFrame** ppFrame, IOleInPlaceUIWindow** ppDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO pFrameInfo)\r
+{\r
+       ATLTRACE(_T("IOleInPlaceSite::GetWindowContext\n"));\r
+       if (ppFrame != NULL)\r
+               *ppFrame = NULL;\r
+       if (ppDoc != NULL)\r
+               *ppDoc = NULL;\r
+\r
+       if (ppFrame == NULL || ppDoc == NULL || lprcPosRect == NULL || lprcClipRect == NULL)\r
+               return E_POINTER;\r
+\r
+       pFrameInfo->fMDIApp = FALSE;\r
+       pFrameInfo->haccel = NULL;\r
+       pFrameInfo->cAccelEntries = 0;\r
+       pFrameInfo->hwndFrame = NULL;\r
+\r
+       lprcPosRect->top = m_rcPos.top;\r
+       lprcPosRect->left = m_rcPos.left;\r
+       lprcPosRect->right = m_rcPos.right;\r
+       lprcPosRect->bottom = m_rcPos.bottom;\r
+\r
+       lprcClipRect->top = m_rcPos.top;\r
+       lprcClipRect->left = m_rcPos.left;\r
+       lprcClipRect->right = m_rcPos.right;\r
+       lprcClipRect->bottom = m_rcPos.bottom;\r
+\r
+       return S_OK;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::Scroll(SIZE scrollExtant)\r
+{\r
+       ATLTRACE(_T("IOleInPlaceSite::Scroll"));\r
+       return S_OK;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::OnUIDeactivate(BOOL fUndoable)\r
+{\r
+       ATLTRACE(_T("IOleInPlaceSite::OnUIDeactivate\n"));\r
+       bUIActive_ = FALSE;\r
+       return S_OK;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::OnInPlaceDeactivate()\r
+{\r
+       ATLTRACE(_T("IOleInPlaceSite::OnInPlaceDeactivate\n"));\r
+       bInPlaceActive_ = FALSE;\r
+       m_spInPlaceObjectWindowless.Release();\r
+       return S_OK;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::DiscardUndoState()\r
+{\r
+       ATLTRACE(_T("IOleInPlaceSite::DiscardUndoState"));\r
+       return S_OK;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::DeactivateAndUndo()\r
+{\r
+       ATLTRACE(_T("IOleInPlaceSite::DeactivateAndUndo"));\r
+       return S_OK;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::OnPosRectChange(LPCRECT lprcPosRect)\r
+{\r
+       ATLTRACE(_T("IOleInPlaceSite::OnPosRectChange"));\r
+       return S_OK;\r
+}\r
+\r
+\r
+/////////////////////\r
+// IOleInPlaceSiteEx\r
+/////////////////////\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::OnInPlaceActivateEx(BOOL* pfNoRedraw, DWORD dwFlags)\r
+{\r
+       // should only be called once the first time control is inplace-activated\r
+       ATLTRACE(_T("IOleInPlaceSiteEx::OnInPlaceActivateEx\n"));\r
+       ATLASSERT(bInPlaceActive_ == FALSE);\r
+       ATLASSERT(m_spInPlaceObjectWindowless == NULL);\r
+\r
+       bInPlaceActive_ = TRUE;\r
+       OleLockRunning(m_spOleObject, TRUE, FALSE);\r
+       HRESULT hr = E_FAIL;\r
+       if (dwFlags & ACTIVATE_WINDOWLESS)\r
+       {\r
+               hr = m_spOleObject->QueryInterface(__uuidof(IOleInPlaceObjectWindowless), (void**) &m_spInPlaceObjectWindowless);\r
+\r
+               if (m_spInPlaceObjectWindowless != NULL)\r
+                       m_spInPlaceObjectWindowless->SetObjectRects(&m_rcPos, &m_rcPos);\r
+       }\r
+\r
+       return (m_spInPlaceObjectWindowless != NULL) ? S_OK : E_FAIL;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::OnInPlaceDeactivateEx(BOOL fNoRedraw)\r
+{\r
+       ATLTRACE(_T("IOleInPlaceSiteEx::OnInPlaceDeactivateEx\n"));\r
+       bInPlaceActive_ = FALSE;\r
+       m_spInPlaceObjectWindowless.Release();\r
+       return S_OK;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::RequestUIActivate()\r
+{\r
+       ATLTRACE(_T("IOleInPlaceSiteEx::RequestUIActivate\n"));\r
+       return S_OK;\r
+}\r
+\r
+\r
+/////////////////////////////\r
+// IOleInPlaceSiteWindowless\r
+/////////////////////////////\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::CanWindowlessActivate()\r
+{\r
+       ATLTRACE(_T("IOleInPlaceSiteWindowless::CanWindowlessActivate\n"));\r
+       return S_OK;\r
+//     return S_FALSE;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::GetCapture()\r
+{\r
+       ATLTRACE(_T("IOleInPlaceSiteWindowless::GetCapture\n"));\r
+       return bCapture_ ? S_OK : S_FALSE;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::SetCapture(BOOL fCapture)\r
+{\r
+       ATLTRACE(_T("IOleInPlaceSiteWindowless::SetCapture\n"));\r
+       bCapture_ = fCapture;\r
+       return S_OK;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::GetFocus()\r
+{\r
+       ATLTRACE(_T("IOleInPlaceSiteWindowless::GetFocus\n"));\r
+       return bHaveFocus_ ? S_OK : S_FALSE;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::SetFocus(BOOL fGotFocus)\r
+{\r
+       ATLTRACE(_T("IOleInPlaceSiteWindowless::SetFocus\n"));\r
+       bHaveFocus_ = fGotFocus;\r
+       return S_OK;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::GetDC(LPCRECT pRect, DWORD grfFlags, HDC* phDC)\r
+{\r
+       ATLTRACE(_T("IOleInPlaceSiteWindowless::GetDC"));\r
+       return S_OK;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::ReleaseDC(HDC hDC)\r
+{\r
+       ATLTRACE(_T("IOleInPlaceSiteWindowless::ReleaseDC"));\r
+       return S_OK;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::InvalidateRect(LPCRECT pRect, BOOL fErase)\r
+{\r
+//     ATLTRACE(_T("IOleInPlaceSiteWindowless::InvalidateRect\n"));\r
+       \r
+       bInvalidRect_ = true;\r
+\r
+/*     //Keep a list of dirty rectangles in order to be able to redraw only them\r
+       if(pRect != NULL) {\r
+               bDirtyRects_.push_back(DirtyRect(*pRect, fErase != 0));\r
+       }\r
+       else {\r
+               bDirtyRects_.push_back(DirtyRect(true));\r
+       }\r
+*/     return S_OK;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::InvalidateRgn(HRGN hRGN, BOOL fErase)\r
+{\r
+       ATLTRACE(_T("IOleInPlaceSiteWindowless::InvalidateRng\n"));\r
+       return S_OK;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::ScrollRect(INT dx, INT dy, LPCRECT pRectScroll, LPCRECT pRectClip)\r
+{\r
+       ATLTRACE(_T("IOleInPlaceSiteWindowless::ScrollRect"));\r
+       return S_OK;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::AdjustRect(LPRECT prc)\r
+{\r
+       ATLTRACE(_T("IOleInPlaceSiteWindowless::AdjustRect"));\r
+       return S_OK;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::OnDefWindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT* plResult)\r
+{\r
+       ATLTRACE(_T("IOleInPlaceSiteWindowless::OnDefWindowMessage"));\r
+       return S_OK;\r
+}\r
+\r
+///////////////////\r
+// IOleControlSite\r
+///////////////////\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::OnControlInfoChanged()\r
+{\r
+       ATLTRACE(_T("IOleControlSite::OnControlInfoChanged"));\r
+       return S_OK;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::LockInPlaceActive(BOOL fLock)\r
+{\r
+       ATLTRACE(_T("IOleControlSite::LockInPlaceActive"));\r
+       return S_OK;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::GetExtendedControl(IDispatch** ppDisp)\r
+{\r
+       ATLTRACE(_T("IOleControlSite::GetExtendedControl"));\r
+\r
+       if (ppDisp == NULL)\r
+               return E_POINTER;\r
+       return m_spOleObject.QueryInterface(ppDisp);\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::TransformCoords(POINTL* pPtlHimetric, POINTF* pPtfContainer, DWORD dwFlags)\r
+{\r
+       ATLTRACE(_T("IOleControlSite::TransformCoords"));\r
+       return S_OK;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::TranslateAccelerator(LPMSG lpMsg, DWORD grfModifiers)\r
+{\r
+       ATLTRACE(_T("IOleControlSite::TranslateAccelerator"));\r
+       return S_FALSE;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::OnFocus(BOOL fGotFocus)\r
+{\r
+       bHaveFocus_ = fGotFocus;\r
+       return S_OK;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::ShowPropertyFrame()\r
+{\r
+       ATLTRACE(_T("IOleControlSite::ShowPropertyFrame"));\r
+       return S_OK;\r
+}\r
+\r
+\r
+///////////////////\r
+// IAdviseSink\r
+///////////////////\r
+void STDMETHODCALLTYPE FlashAxContainer::OnDataChange(FORMATETC* pFormatetc, STGMEDIUM* pStgmed)\r
+{\r
+       ATLTRACE(_T("IAdviseSink::OnDataChange\n"));\r
+}\r
+\r
+void STDMETHODCALLTYPE FlashAxContainer::OnViewChange(DWORD dwAspect, LONG lindex)\r
+{\r
+       ATLTRACE(_T("IAdviseSink::OnViewChange\n"));\r
+}\r
+\r
+void STDMETHODCALLTYPE FlashAxContainer::OnRename(IMoniker* pmk)\r
+{\r
+       ATLTRACE(_T("IAdviseSink::OnRename\n"));\r
+}\r
+\r
+void STDMETHODCALLTYPE FlashAxContainer::OnSave()\r
+{\r
+       ATLTRACE(_T("IAdviseSink::OnSave\n"));\r
+}\r
+\r
+void STDMETHODCALLTYPE FlashAxContainer::OnClose()\r
+{\r
+       ATLTRACE(_T("IAdviseSink::OnClose\n"));\r
+}\r
+\r
+\r
+///////////////////\r
+// IServiceProvider\r
+///////////////////\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::QueryService( REFGUID rsid, REFIID riid, void** ppvObj) \r
+{\r
+//     ATLTRACE(_T("IServiceProvider::QueryService\n"));\r
+       //the flashcontrol asks for an interface {618F8AD4-8B7A-11D0-8FCC-00C04FD9189D}, this is IID for a DirectDraw3 object\r
+\r
+       ATLASSERT(ppvObj != NULL);\r
+       if (ppvObj == NULL)\r
+               return E_POINTER;\r
+       *ppvObj = NULL;\r
+\r
+       //TODO: The fullscreen-consumer requires that ths does NOT return an ITimerService\r
+       HRESULT hr = QueryInterface(riid, ppvObj);//E_NOINTERFACE;\r
+\r
+       return hr;\r
+}\r
+\r
+\r
+///////////////////\r
+// ITimerService\r
+///////////////////\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::CreateTimer(ITimer *pReferenceTimer, ITimer **ppNewTimer)\r
+{\r
+       ATLTRACE(_T("ITimerService::CreateTimer\n"));\r
+       if(pTimerHelper != 0)\r
+       {\r
+               delete pTimerHelper;\r
+               pTimerHelper = 0;\r
+       }\r
+       pTimerHelper = new TimerHelper();\r
+       return QueryInterface(__uuidof(ITimer), (void**) ppNewTimer);\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::GetNamedTimer(REFGUID rguidName, ITimer **ppTimer)\r
+{\r
+       ATLTRACE(_T("ITimerService::GetNamedTimer"));\r
+       if(ppTimer == NULL)\r
+               return E_POINTER;\r
+       else\r
+               *ppTimer = NULL;\r
+\r
+       return E_FAIL;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::SetNamedTimerReference(REFGUID rguidName, ITimer *pReferenceTimer)\r
+{\r
+       ATLTRACE(_T("ITimerService::SetNamedTimerReference"));\r
+       return S_OK;\r
+}\r
+\r
+///////////\r
+// ITimer\r
+///////////\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::Advise(VARIANT vtimeMin, VARIANT vtimeMax, VARIANT vtimeInterval, DWORD dwFlags, ITimerSink *pTimerSink, DWORD *pdwCookie)\r
+{\r
+       ATLTRACE(_T("Timer::Advise\n"));\r
+       if(pdwCookie == 0)\r
+               return E_POINTER;\r
+\r
+       if(pTimerHelper != 0)\r
+       {\r
+               pTimerHelper->Setup(vtimeMin.ulVal, vtimeInterval.ulVal, pTimerSink);\r
+               *pdwCookie = pTimerHelper->ID;\r
+               bHasNewTiming_ = true;\r
+\r
+               return S_OK;\r
+       }\r
+       else\r
+               return E_OUTOFMEMORY;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::Unadvise(/* [in] */ DWORD dwCookie)\r
+{\r
+       ATLTRACE(_T("Timer::Unadvice\n"));\r
+       if(pTimerHelper != 0)\r
+       {\r
+               pTimerHelper->pTimerSink = 0;\r
+               return S_OK;\r
+       }\r
+       else\r
+               return E_FAIL;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::Freeze(/* [in] */ BOOL fFreeze)\r
+{\r
+       ATLTRACE(_T("Timer::Freeze\n"));\r
+       return S_OK;\r
+}\r
+\r
+HRESULT STDMETHODCALLTYPE FlashAxContainer::GetTime(/* [out] */ VARIANT *pvtime)\r
+{\r
+       ATLTRACE(_T("Timer::GetTime\n"));\r
+       if(pvtime == 0)\r
+               return E_POINTER;\r
+\r
+//     return E_NOTIMPL;\r
+       pvtime->lVal = 0;\r
+       return S_OK;\r
+}\r
+\r
+int FlashAxContainer::GetFPS() {\r
+       if(pTimerHelper != 0 && pTimerHelper->interval > 0)\r
+               return (1000 / pTimerHelper->interval);\r
+       \r
+       return 0;\r
+}\r
+\r
+bool FlashAxContainer::IsReadyToRender() const {\r
+       return bReadyToRender_;\r
+}\r
+\r
+void FlashAxContainer::EnterFullscreen()\r
+{\r
+       if(m_spInPlaceObjectWindowless != 0)\r
+       {\r
+               HRESULT result;\r
+               m_spInPlaceObjectWindowless->OnWindowMessage(WM_LBUTTONDOWN, 0, MAKELPARAM(1, 1), &result);\r
+               m_spInPlaceObjectWindowless->OnWindowMessage(WM_LBUTTONUP, 0, MAKELPARAM(1, 1), &result);\r
+       }\r
+}\r
+\r
+void STDMETHODCALLTYPE FlashAxContainer::OnFlashCall(BSTR request)\r
+{\r
+       tstring str(request);\r
+       if(str.find(TEXT("DisplayedTemplate")) != tstring::npos)\r
+       {\r
+               ATLTRACE(_T("ShockwaveFlash::DisplayedTemplate\n"));\r
+               bReadyToRender_ = true;\r
+       }\r
+       else if(str.find(TEXT("OnCommand")) != tstring::npos) {\r
+               //this is how templatehost 1.8 reports that a command has been received\r
+               LOG << utils::LogLevel::Verbose << TEXT("TEMPLATEHOST: ") << str;\r
+               bCallSuccessful_ = true;\r
+       }\r
+       else if(str.find(TEXT("Activity")) != tstring::npos)\r
+       {\r
+               LOG << utils::LogLevel::Verbose << TEXT("TEMPLATEHOST: ") << str;\r
+\r
+               //this is how templatehost 1.7 reports that a command has been received\r
+               if(str.find(TEXT("Command recieved")) != tstring::npos)\r
+                       bCallSuccessful_ = true;\r
+\r
+               /*if(pFlashProducer_ != 0 && pFlashProducer_->pMonitor_) {\r
+                       tstring::size_type pos = str.find(TEXT('@'));\r
+                       if(pos != tstring::npos)\r
+                               pFlashProducer_->pMonitor_->Inform(str.substr(pos, str.find(TEXT('<'), pos)-pos));\r
+               }*/\r
+       }\r
+       else if(str.find(TEXT("OnNotify")) != tstring::npos)\r
+       {\r
+               LOG << utils::LogLevel::Verbose << TEXT("TEMPLATEHOST: ") << str;\r
+\r
+               //if(pFlashProducer_ != 0 && pFlashProducer_->pMonitor_) {\r
+               //      tstring::size_type pos = str.find(TEXT('@'));\r
+               //      if(pos != tstring::npos)\r
+               //              pFlashProducer_->pMonitor_->Inform(str.substr(pos, str.find(TEXT('<'), pos)-pos));\r
+               //}\r
+       }\r
+       else if(str.find(TEXT("IsEmpty")) != tstring::npos)\r
+       {\r
+               ATLTRACE(_T("ShockwaveFlash::IsEmpty\n"));\r
+               bIsEmpty_ = true;\r
+               if(pFlashProducer_ != 0 && pFlashProducer_->emptyCallback)\r
+                       pFlashProducer_->emptyCallback();\r
+       }\r
+       else if(str.find(TEXT("OnError")) != tstring::npos)\r
+       {\r
+               LOG << "FLASHERROR: " << str;\r
+       }\r
+\r
+       CComPtr<IShockwaveFlash> spFlash;\r
+       HRESULT hr = m_spOleObject->QueryInterface(__uuidof(IShockwaveFlash), (void**) &spFlash);\r
+       if(hr == S_OK && spFlash)\r
+       {\r
+               hr = spFlash->SetReturnValue(TEXT("<null/>"));\r
+       }\r
+}\r
+\r
+void STDMETHODCALLTYPE FlashAxContainer::OnReadyStateChange(long newState)\r
+{\r
+       if(newState == 4)\r
+       {\r
+               bReadyToRender_ = true;\r
+       }\r
+       else\r
+               bReadyToRender_ = false;\r
+}\r
+\r
+void FlashAxContainer::DestroyAxControl()\r
+{\r
+       GetControllingUnknown()->AddRef();\r
+\r
+       if ((!m_spViewObject) == false)\r
+               m_spViewObject->SetAdvise(DVASPECT_CONTENT, 0, NULL);\r
+\r
+       if ((!m_spOleObject) == false)\r
+       {\r
+               DispEventUnadvise(m_spOleObject, &DIID__IShockwaveFlashEvents);\r
+               m_spOleObject->Unadvise(m_dwOleObject);\r
+               m_spOleObject->Close(OLECLOSE_NOSAVE);\r
+               m_spOleObject->SetClientSite(NULL);\r
+       }\r
+\r
+       if ((!m_spUnknown) == false)\r
+       {\r
+               CComPtr<IObjectWithSite> spSite;\r
+               m_spUnknown->QueryInterface(__uuidof(IObjectWithSite), (void**)&spSite);\r
+               if (spSite != NULL)\r
+                       spSite->SetSite(NULL);\r
+       }\r
+\r
+       if ((!m_spViewObject) == false)\r
+               m_spViewObject.Release();\r
+\r
+       if ((!m_spInPlaceObjectWindowless) == false)\r
+               m_spInPlaceObjectWindowless.Release();\r
+\r
+       if ((!m_spOleObject) == false)\r
+               m_spOleObject.Release();\r
+\r
+       if ((!m_spUnknown) == false)\r
+               m_spUnknown.Release();\r
+}\r
+\r
+bool FlashAxContainer::CheckForFlashSupport()\r
+{\r
+       CLSID clsid;\r
+       return SUCCEEDED(CLSIDFromString((LPOLESTR)flashGUID_, &clsid));\r
+}\r
+\r
+HRESULT FlashAxContainer::CreateAxControl()\r
+{\r
+       CLSID clsid;\r
+       HRESULT hr = CLSIDFromString((LPOLESTR)flashGUID_, &clsid); \r
+       if(SUCCEEDED(hr))\r
+               hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, __uuidof(IUnknown), (void**)&m_spUnknown);\r
+\r
+//Start ActivateAx\r
+       if(SUCCEEDED(hr))\r
+       {\r
+               m_spUnknown->QueryInterface(__uuidof(IOleObject), (void**)&m_spOleObject);\r
+               if(m_spOleObject)\r
+               {\r
+                       m_spOleObject->GetMiscStatus(DVASPECT_CONTENT, &m_dwMiscStatus);\r
+                       if (m_dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)\r
+                       {\r
+                               CComQIPtr<IOleClientSite> spClientSite(GetControllingUnknown());\r
+                               m_spOleObject->SetClientSite(spClientSite);\r
+                       }\r
+\r
+                       //Initialize control\r
+                       CComQIPtr<IPersistStreamInit> spPSI(m_spOleObject);\r
+                       if (spPSI)\r
+                               hr = spPSI->InitNew();\r
+\r
+                       if (FAILED(hr)) // If the initialization of the control failed...\r
+                       {\r
+                               // Clean up and return\r
+                               if (m_dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)\r
+                                       m_spOleObject->SetClientSite(NULL);\r
+\r
+                               m_dwMiscStatus = 0;\r
+                               m_spOleObject.Release();\r
+                               m_spUnknown.Release();\r
+\r
+                               return hr;\r
+                       }\r
+                       //end Initialize object\r
+\r
+                       if (0 == (m_dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST))\r
+                       {\r
+                               CComQIPtr<IOleClientSite> spClientSite(GetControllingUnknown());\r
+                               m_spOleObject->SetClientSite(spClientSite);\r
+                       }\r
+\r
+                       CComPtr<IShockwaveFlash> spFlash;\r
+                       HRESULT hResultQuality;\r
+                       HRESULT hr2 = m_spOleObject->QueryInterface(__uuidof(IShockwaveFlash), (void**) &spFlash);\r
+                       if(hr2 == S_OK && spFlash)\r
+                       {\r
+                               spFlash->put_WMode(TEXT("Transparent"));\r
+                               //spFlash->put_WMode(TEXT("GPU"));\r
+                               hResultQuality = spFlash->put_Quality2(TEXT("Best"));\r
+                       }\r
+                       if(SUCCEEDED(DispEventAdvise(spFlash, &DIID__IShockwaveFlashEvents)))\r
+                       {\r
+                       }\r
+\r
+                       HRESULT hrView = m_spOleObject->QueryInterface(__uuidof(IViewObjectEx), (void**) &m_spViewObject);\r
+\r
+                       CComQIPtr<IAdviseSink> spAdviseSink(GetControllingUnknown());\r
+                       m_spOleObject->Advise(spAdviseSink, &m_dwOleObject);\r
+                       if (m_spViewObject)\r
+                               m_spViewObject->SetAdvise(DVASPECT_CONTENT, 0, spAdviseSink);\r
+\r
+                       if ((m_dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME) == 0)\r
+                       {\r
+                               //Initialize window to some dummy size\r
+                               m_rcPos.top = 0;\r
+                               m_rcPos.left = 0;\r
+                               m_rcPos.right = 720;\r
+                               m_rcPos.bottom = 576;\r
+\r
+                               m_pxSize.cx = m_rcPos.right - m_rcPos.left;\r
+                               m_pxSize.cy = m_rcPos.bottom - m_rcPos.top;\r
+                               AtlPixelToHiMetric(&m_pxSize, &m_hmSize);\r
+                               m_spOleObject->SetExtent(DVASPECT_CONTENT, &m_hmSize);\r
+                               m_spOleObject->GetExtent(DVASPECT_CONTENT, &m_hmSize);\r
+                               AtlHiMetricToPixel(&m_hmSize, &m_pxSize);\r
+                               m_rcPos.right = m_rcPos.left + m_pxSize.cx;\r
+                               m_rcPos.bottom = m_rcPos.top + m_pxSize.cy;\r
+\r
+                               CComQIPtr<IOleClientSite> spClientSite(GetControllingUnknown());\r
+                               hr = m_spOleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, spClientSite, 0, NULL, &m_rcPos);\r
+                       }\r
+               }\r
+               CComPtr<IObjectWithSite> spSite;\r
+               m_spUnknown->QueryInterface(__uuidof(IObjectWithSite), (void**)&spSite);\r
+               if (spSite != NULL)\r
+                       spSite->SetSite(GetControllingUnknown());\r
+       }\r
+//End ActivateAx\r
+\r
+//     hr = E_FAIL;\r
+       if (FAILED(hr) || m_spUnknown == NULL)\r
+       {\r
+               return E_FAIL;\r
+               // We don't have a control or something failed so release\r
+//             ReleaseAll();\r
+       }\r
+\r
+       return S_OK;\r
+}\r
+\r
+void FlashAxContainer::SetFormat(const caspar::FrameFormatDescription& fmtDesc) {\r
+       if(m_spInPlaceObjectWindowless != 0)\r
+       {\r
+               m_rcPos.top = 0;\r
+               m_rcPos.left = 0;\r
+               m_rcPos.right = fmtDesc.width;\r
+               m_rcPos.bottom = fmtDesc.height;\r
+\r
+               m_pxSize.cx = m_rcPos.right - m_rcPos.left;\r
+               m_pxSize.cy = m_rcPos.bottom - m_rcPos.top;\r
+               AtlPixelToHiMetric(&m_pxSize, &m_hmSize);\r
+               m_spOleObject->SetExtent(DVASPECT_CONTENT, &m_hmSize);\r
+               m_spOleObject->GetExtent(DVASPECT_CONTENT, &m_hmSize);\r
+               AtlHiMetricToPixel(&m_hmSize, &m_pxSize);\r
+               m_rcPos.right = m_rcPos.left + m_pxSize.cx;\r
+               m_rcPos.bottom = m_rcPos.top + m_pxSize.cy;\r
+\r
+               m_spInPlaceObjectWindowless->SetObjectRects(&m_rcPos, &m_rcPos);\r
+               bInvalidRect_ = true;\r
+       }\r
+}\r
+\r
+HRESULT FlashAxContainer::QueryControl(REFIID iid, void** ppUnk)\r
+{\r
+       ATLASSERT(ppUnk != NULL);\r
+       if (ppUnk == NULL)\r
+               return E_POINTER;\r
+       HRESULT hr;\r
+       hr = m_spOleObject->QueryInterface(iid, ppUnk);\r
+       return hr;\r
+}\r
+\r
+bool FlashAxContainer::DrawControl(HDC targetDC)\r
+{\r
+//     ATLTRACE(_T("FlashAxContainer::DrawControl\n"));\r
+       DVASPECTINFO aspectInfo = {sizeof(DVASPECTINFO), DVASPECTINFOFLAG_CANOPTIMIZE};\r
+       HRESULT hr = S_OK;\r
+\r
+       hr = m_spViewObject->Draw(DVASPECT_CONTENT, -1, &aspectInfo, NULL, NULL, targetDC, NULL, NULL, NULL, NULL); \r
+\r
+/*     const caspar::FrameFormatDescription& fmtDesc = caspar::FrameFormatDescription::FormatDescriptions[format_];\r
+\r
+       //Trying to redraw just the dirty rectangles. Doesn't seem to work when the movie uses "filters", such as glow, dropshadow etc.\r
+       std::vector<flash::DirtyRect>::iterator it = bDirtyRects_.begin();\r
+       std::vector<flash::DirtyRect>::iterator end = bDirtyRects_.end();\r
+       for(; it != end; ++it) {\r
+               flash::DirtyRect& dirtyRect = (*it);\r
+               if(dirtyRect.bWhole || dirtyRect.rect.right >= fmtDesc.width || dirtyRect.rect.bottom >= fmtDesc.height) {\r
+                       m_spInPlaceObjectWindowless->SetObjectRects(&m_rcPos, &m_rcPos);\r
+                       hr = m_spViewObject->Draw(DVASPECT_OPAQUE, -1, NULL, NULL, NULL, targetDC, NULL, NULL, NULL, NULL); \r
+                       break;\r
+               }\r
+               else {\r
+                       m_spInPlaceObjectWindowless->SetObjectRects(&m_rcPos, &(dirtyRect.rect));\r
+                       hr = m_spViewObject->Draw(DVASPECT_OPAQUE, -1, NULL, NULL, NULL, targetDC, NULL, NULL, NULL, NULL); \r
+               }\r
+       }\r
+       bDirtyRects_.clear();\r
+*/\r
+\r
+       return (hr == S_OK);\r
+}\r
+\r
+}      //namespace flash\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/producers/flash/FlashAxContainer.h b/server/producers/flash/FlashAxContainer.h
new file mode 100644 (file)
index 0000000..9a956ab
--- /dev/null
@@ -0,0 +1,283 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _FLASHAXCONTAINER_H__\r
+#define _FLASHAXCONTAINER_H__\r
+\r
+#pragma once\r
+\r
+#include <atlbase.h>\r
+#include <atlcom.h>\r
+#include <atlhost.h>\r
+\r
+\r
+#include <ocmm.h>\r
+#include "..\..\frame\Frame.h"\r
+#include <vector>\r
+\r
+#include "axflash.h"\r
+//#import "progid:ShockwaveFlash.ShockwaveFlash.9" no_namespace, named_guids\r
+\r
+namespace caspar {\r
+\r
+class FlashProducer;\r
+\r
+namespace flash {\r
+\r
+class TimerHelper;\r
+struct DirtyRect {\r
+       DirtyRect(LONG l, LONG t, LONG r, LONG b, bool e) : bErase(e), bWhole(false) { \r
+               rect.left = l;\r
+               rect.top = t;\r
+               rect.right = r;\r
+               rect.bottom = b; \r
+       }\r
+       DirtyRect(const RECT& rc, bool e) : bErase(e), bWhole(false)  {\r
+               rect.left = rc.left;\r
+               rect.top = rc.top;\r
+               rect.right = rc.right;\r
+               rect.bottom = rc.bottom; \r
+       }\r
+       explicit DirtyRect(bool b) : bWhole(b) {}\r
+\r
+       RECT    rect;\r
+       bool    bErase;\r
+       bool    bWhole;\r
+};\r
+\r
+extern _ATL_FUNC_INFO fnInfoFlashCallEvent;\r
+extern _ATL_FUNC_INFO fnInfoReadyStateChangeEvent;\r
+\r
+class ATL_NO_VTABLE FlashAxContainer : \r
+               public ATL::CComCoClass<FlashAxContainer , &CLSID_NULL>,\r
+               public ATL::CComObjectRootEx<ATL::CComMultiThreadModel>,\r
+               public IOleClientSite,\r
+               public IOleContainer,\r
+               public IOleControlSite,\r
+               public IOleInPlaceSiteWindowless,\r
+               public IObjectWithSiteImpl<FlashAxContainer>,\r
+               public IServiceProvider,\r
+               public IAdviseSink,\r
+               public ITimerService,\r
+               public ITimer,\r
+               public IDispatchImpl<IDispatch>,\r
+               public IDispEventSimpleImpl<0, FlashAxContainer, &DIID__IShockwaveFlashEvents>\r
+{\r
+\r
+public:\r
+\r
+       FlashAxContainer();\r
+       virtual ~FlashAxContainer();\r
+\r
+       DECLARE_NO_REGISTRY()\r
+       DECLARE_POLY_AGGREGATABLE(FlashAxContainer)\r
+       DECLARE_GET_CONTROLLING_UNKNOWN()\r
+\r
+       BEGIN_COM_MAP(FlashAxContainer)\r
+               COM_INTERFACE_ENTRY(IDispatch)\r
+               COM_INTERFACE_ENTRY(IOleClientSite)\r
+               COM_INTERFACE_ENTRY(IObjectWithSite)\r
+               COM_INTERFACE_ENTRY(IOleControlSite)\r
+               COM_INTERFACE_ENTRY(IOleContainer)\r
+\r
+               COM_INTERFACE_ENTRY(IOleInPlaceSiteWindowless)\r
+               COM_INTERFACE_ENTRY(IOleInPlaceSiteEx)\r
+               COM_INTERFACE_ENTRY(IOleInPlaceSite)\r
+               COM_INTERFACE_ENTRY(IOleWindow)\r
+\r
+               COM_INTERFACE_ENTRY(IServiceProvider)\r
+\r
+               COM_INTERFACE_ENTRY(IAdviseSink)\r
+\r
+               COM_INTERFACE_ENTRY(ITimerService)\r
+\r
+               COM_INTERFACE_ENTRY(ITimer)\r
+       END_COM_MAP()\r
+\r
+       BEGIN_SINK_MAP(FlashAxContainer)\r
+               SINK_ENTRY_INFO(0, DIID__IShockwaveFlashEvents, 0xc5, OnFlashCall, &fnInfoFlashCallEvent)\r
+               SINK_ENTRY_INFO(0, DIID__IShockwaveFlashEvents, 0xfffffd9f, OnReadyStateChange, &fnInfoReadyStateChangeEvent)\r
+       END_SINK_MAP()\r
+\r
+       void STDMETHODCALLTYPE OnFlashCall(BSTR request);\r
+       void STDMETHODCALLTYPE OnReadyStateChange(long newState);\r
+\r
+// IObjectWithSite\r
+       STDMETHOD(SetSite)(IUnknown* pUnkSite);\r
+\r
+// IOleClientSite\r
+       STDMETHOD(SaveObject)();\r
+       STDMETHOD(GetMoniker)(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker** ppmk);\r
+       STDMETHOD(GetContainer)(IOleContainer** ppContainer);\r
+       STDMETHOD(ShowObject)();\r
+       STDMETHOD(OnShowWindow)(BOOL fShow);\r
+       STDMETHOD(RequestNewObjectLayout)();\r
+\r
+// IOleInPlaceSite\r
+       STDMETHOD(GetWindow)(HWND* pHwnd);\r
+       STDMETHOD(ContextSensitiveHelp)(BOOL fEnterMode);\r
+       STDMETHOD(CanInPlaceActivate)();\r
+       STDMETHOD(OnInPlaceActivate)();\r
+       STDMETHOD(OnInPlaceDeactivate)();\r
+       STDMETHOD(OnUIActivate)();\r
+       STDMETHOD(OnUIDeactivate)(BOOL fUndoable);\r
+       STDMETHOD(GetWindowContext)(IOleInPlaceFrame** ppFrame, IOleInPlaceUIWindow** ppDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO pFrameInfo);\r
+       STDMETHOD(Scroll)(SIZE scrollExtant);\r
+       STDMETHOD(DiscardUndoState)();\r
+       STDMETHOD(DeactivateAndUndo)();\r
+       STDMETHOD(OnPosRectChange)(LPCRECT lprcPosRect);\r
+\r
+// IOleInPlaceSiteEx\r
+       STDMETHOD(OnInPlaceActivateEx)(BOOL* pfNoRedraw, DWORD dwFlags);\r
+       STDMETHOD(OnInPlaceDeactivateEx)(BOOL fNoRedraw);\r
+       STDMETHOD(RequestUIActivate)();\r
+\r
+// IOleInPlaceSiteWindowless\r
+       STDMETHOD(CanWindowlessActivate)();\r
+       STDMETHOD(GetCapture)();\r
+       STDMETHOD(SetCapture)(BOOL fCapture);\r
+       STDMETHOD(GetFocus)();\r
+       STDMETHOD(SetFocus)(BOOL fGotFocus);\r
+       STDMETHOD(GetDC)(LPCRECT pRect, DWORD grfFlags, HDC* phDC);\r
+       STDMETHOD(ReleaseDC)(HDC hDC);\r
+       STDMETHOD(InvalidateRect)(LPCRECT pRect, BOOL fErase);\r
+       STDMETHOD(InvalidateRgn)(HRGN hRGN, BOOL fErase);\r
+       STDMETHOD(ScrollRect)(INT dx, INT dy, LPCRECT pRectScroll, LPCRECT pRectClip);\r
+       STDMETHOD(AdjustRect)(LPRECT prc);\r
+       STDMETHOD(OnDefWindowMessage)(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT* plResult);\r
+\r
+// IOleControlSite\r
+       STDMETHOD(OnControlInfoChanged)();\r
+       STDMETHOD(LockInPlaceActive)(BOOL fLock);\r
+       STDMETHOD(GetExtendedControl)(IDispatch** ppDisp);\r
+       STDMETHOD(TransformCoords)(POINTL* pPtlHimetric, POINTF* pPtfContainer, DWORD dwFlags);\r
+       STDMETHOD(TranslateAccelerator)(LPMSG lpMsg, DWORD grfModifiers);\r
+       STDMETHOD(OnFocus)(BOOL fGotFocus);\r
+       STDMETHOD(ShowPropertyFrame)();\r
+\r
+// IAdviseSink\r
+       STDMETHOD_(void, OnDataChange)(FORMATETC* pFormatetc, STGMEDIUM* pStgmed);\r
+       STDMETHOD_(void, OnViewChange)(DWORD dwAspect, LONG lindex);\r
+       STDMETHOD_(void, OnRename)(IMoniker* pmk);\r
+       STDMETHOD_(void, OnSave)();\r
+       STDMETHOD_(void, OnClose)();\r
+\r
+// IServiceProvider\r
+       STDMETHOD(QueryService)( REFGUID rsid, REFIID riid, void** ppvObj);\r
+\r
+// IOleContainer\r
+       STDMETHOD(ParseDisplayName)(IBindCtx*, LPOLESTR, ULONG*, IMoniker**)\r
+       {\r
+               ATLTRACENOTIMPL(_T("IOleContainer::ParseDisplayName"));\r
+       }\r
+       STDMETHOD(EnumObjects)(DWORD, IEnumUnknown** ppenum)\r
+       {\r
+               if (ppenum == NULL)\r
+                       return E_POINTER;\r
+               *ppenum = NULL;\r
+               typedef CComObject<CComEnum<IEnumUnknown, &__uuidof(IEnumUnknown), IUnknown*, _CopyInterface<IUnknown> > > enumunk;\r
+               enumunk* p = NULL;\r
+               ATLTRY(p = new enumunk);\r
+               if(p == NULL)\r
+                       return E_OUTOFMEMORY;\r
+               IUnknown* pTemp = m_spUnknown;\r
+               // There is always only one object.\r
+               HRESULT hRes = p->Init(reinterpret_cast<IUnknown**>(&pTemp), reinterpret_cast<IUnknown**>(&pTemp + 1), GetControllingUnknown(), AtlFlagCopy);\r
+               if (SUCCEEDED(hRes))\r
+                       hRes = p->QueryInterface(__uuidof(IEnumUnknown), (void**)ppenum);\r
+               if (FAILED(hRes))\r
+                       delete p;\r
+               return hRes;\r
+       }\r
+       STDMETHOD(LockContainer)(BOOL)\r
+       {\r
+               ATLTRACENOTIMPL(_T("IOleContainer::LockContainer"));\r
+       }\r
+\r
+//ITimerService\r
+       STDMETHOD(CreateTimer)(ITimer *pReferenceTimer, ITimer **ppNewTimer);\r
+       STDMETHOD(GetNamedTimer)(REFGUID rguidName, ITimer **ppTimer);\r
+       STDMETHOD(SetNamedTimerReference)(REFGUID rguidName, ITimer *pReferenceTimer);\r
+\r
+//ITimer\r
+       STDMETHOD(Advise)(VARIANT vtimeMin, VARIANT vtimeMax, VARIANT vtimeInterval, DWORD dwFlags, ITimerSink *pTimerSink, DWORD *pdwCookie);\r
+       STDMETHOD(Unadvise)(DWORD dwCookie);\r
+       STDMETHOD(Freeze)(BOOL fFreeze);\r
+       STDMETHOD(GetTime)(VARIANT *pvtime);\r
+       int GetFPS();\r
+\r
+       HRESULT CreateAxControl();\r
+       void DestroyAxControl();\r
+       HRESULT QueryControl(REFIID iid, void** ppUnk);\r
+\r
+       template <class Q>\r
+       HRESULT QueryControl(Q** ppUnk)\r
+       {\r
+               return QueryControl(__uuidof(Q), (void**)ppUnk);\r
+       }\r
+\r
+//     static ATL::CComObject<FlashAxContainer>* CreateInstance();\r
+\r
+       bool DrawControl(HDC targetDC);\r
+\r
+       TimerHelper* pTimerHelper;\r
+       volatile bool bInvalidRect_;\r
+       volatile bool bCallSuccessful_;\r
+       volatile bool bReadyToRender_;\r
+       volatile bool bIsEmpty_;\r
+       volatile bool bHasNewTiming_;\r
+       FlashProducer* pFlashProducer_;\r
+       std::vector<DirtyRect> bDirtyRects_;\r
+\r
+       void SetFormat(const caspar::FrameFormatDescription&);\r
+       bool IsReadyToRender() const;\r
+       void EnterFullscreen();\r
+\r
+       static bool CheckForFlashSupport();\r
+\r
+       ATL::CComPtr<IOleInPlaceObjectWindowless> m_spInPlaceObjectWindowless;\r
+\r
+private:\r
+       static CComBSTR flashGUID_;\r
+\r
+//     state\r
+       bool            bUIActive_;\r
+       bool            bInPlaceActive_;\r
+       unsigned long           bHaveFocus_ : 1;\r
+       unsigned long           bCapture_ : 1;\r
+\r
+       DWORD m_dwOleObject;\r
+       DWORD m_dwMiscStatus;\r
+       SIZEL m_hmSize;\r
+       SIZEL m_pxSize;\r
+       RECT m_rcPos;\r
+\r
+       ATL::CComPtr<IUnknown> m_spUnknown;\r
+       ATL::CComPtr<IOleObject> m_spServices;\r
+       ATL::CComPtr<IOleObject> m_spOleObject;\r
+       ATL::CComPtr<IViewObjectEx> m_spViewObject;\r
+\r
+//     ATL::CComPtr<ATL::CComObject<MyMoniker> > m_spMyMoniker;\r
+};\r
+\r
+}      //namespace flash\r
+}      //namespace caspar\r
+\r
+#endif //_FLASHAXCONTAINER_H__
\ No newline at end of file
diff --git a/server/producers/flash/FlashCommand.cpp b/server/producers/flash/FlashCommand.cpp
new file mode 100644 (file)
index 0000000..35a959c
--- /dev/null
@@ -0,0 +1,87 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\..\stdafx.h"\r
+\r
+#include "FlashCommand.h"\r
+#include "FlashManager.h"\r
+#include "FlashProducer.h"\r
+\r
+namespace caspar\r
+{\r
+\r
+//////////////////////\r
+// FlashCommand\r
+FlashCommand::FlashCommand(FlashProducer* pHost) : pHost_(pHost), eventDone_(FALSE, FALSE) \r
+{}\r
+\r
+FlashCommand::~FlashCommand() {\r
+}\r
+\r
+void FlashCommand::Execute()\r
+{\r
+       if(pHost_ != 0)\r
+               result = DoExecute();\r
+\r
+       eventDone_.Set();\r
+}\r
+\r
+void FlashCommand::Cancel() {\r
+       eventDone_.Set();\r
+}\r
+\r
+bool FlashCommand::Wait(DWORD timeout)\r
+{\r
+       if(!pHost_->worker_.IsRunning())\r
+               return false;\r
+\r
+       HRESULT result = WaitForSingleObject(eventDone_, timeout);\r
+       return (result == WAIT_OBJECT_0);\r
+}\r
+\r
+/////////////////////////\r
+//  GenericFlashCommand\r
+GenericFlashCommand::GenericFlashCommand(caspar::FlashProducer *pHost, caspar::FlashMemberFnPtr pFunction) : FlashCommand(pHost), pFunction_(pFunction) {\r
+}\r
+GenericFlashCommand::GenericFlashCommand(caspar::FlashProducer *pHost, caspar::FlashMemberFnPtr pFunction, const tstring &parameter) : FlashCommand(pHost), pFunction_(pFunction), parameter_(parameter) {\r
+}\r
+GenericFlashCommand::~GenericFlashCommand() {\r
+}\r
+\r
+bool GenericFlashCommand::DoExecute() {\r
+       if(pFunction_ != 0)\r
+               return (GetHost()->*pFunction_)(parameter_);\r
+       \r
+       return false;\r
+}\r
+\r
+////////////////////////////\r
+//  InitializeFlashCommand\r
+InitializeFlashCommand::InitializeFlashCommand(FlashProducer *pHost, FrameManagerPtr pFrameManager) : FlashCommand(pHost), pFrameManager_(pFrameManager) {\r
+}\r
+\r
+InitializeFlashCommand::~InitializeFlashCommand() {\r
+}\r
+\r
+bool InitializeFlashCommand::DoExecute() {\r
+       return GetHost()->DoInitialize(pFrameManager_);\r
+}\r
+\r
+}
\ No newline at end of file
diff --git a/server/producers/flash/FlashCommand.h b/server/producers/flash/FlashCommand.h
new file mode 100644 (file)
index 0000000..2844ae5
--- /dev/null
@@ -0,0 +1,91 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _FLASHCOMMAND_H_\r
+#define _FLASHCOMMAND_H_\r
+\r
+#include "..\..\utils\Event.h"\r
+\r
+namespace caspar\r
+{\r
+\r
+class FlashProducer;\r
+typedef bool (FlashProducer::*FlashMemberFnPtr)(const tstring&);\r
+\r
+class FrameManager;\r
+typedef std::tr1::shared_ptr<FrameManager> FrameManagerPtr;\r
+\r
+class FlashCommand\r
+{\r
+protected:\r
+       explicit FlashCommand(FlashProducer* pHost);\r
+       virtual bool DoExecute() = 0;\r
+\r
+       FlashProducer* GetHost() {\r
+               return pHost_;\r
+       }\r
+\r
+public:\r
+       virtual ~FlashCommand();\r
+\r
+       void Execute();\r
+       void Cancel();\r
+       bool Wait(DWORD timeout);\r
+\r
+       bool GetResult() {\r
+               return result;\r
+       }\r
+\r
+private:\r
+       bool result;\r
+\r
+       utils::Event    eventDone_;\r
+       FlashProducer* pHost_;\r
+};\r
+\r
+class GenericFlashCommand : public FlashCommand \r
+{\r
+public:\r
+       GenericFlashCommand(FlashProducer* pHost, FlashMemberFnPtr pFunction);\r
+       GenericFlashCommand(FlashProducer* pHost, FlashMemberFnPtr pFunction, const tstring& parameter);\r
+       virtual ~GenericFlashCommand();\r
+\r
+private:\r
+       typedef std::tr1::shared_ptr<FlashCommand> FlashCommandPtr;\r
+\r
+       virtual bool DoExecute();\r
+       FlashMemberFnPtr pFunction_;\r
+       tstring parameter_;\r
+};\r
+\r
+class InitializeFlashCommand : public FlashCommand\r
+{\r
+public:\r
+       InitializeFlashCommand(FlashProducer* pHost, FrameManagerPtr pFrameManager);\r
+       virtual ~InitializeFlashCommand();\r
+\r
+private:\r
+       virtual bool DoExecute();\r
+       FrameManagerPtr pFrameManager_;\r
+};\r
+\r
+}\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/producers/flash/FlashCommandQueue.cpp b/server/producers/flash/FlashCommandQueue.cpp
new file mode 100644 (file)
index 0000000..254ecb0
--- /dev/null
@@ -0,0 +1,80 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\..\stdafx.h"\r
+\r
+#include "FlashCommandQueue.h"\r
+#include "FlashCommand.h"\r
+#include "FlashManager.h"\r
+#include <algorithm>\r
+\r
+namespace caspar {\r
+namespace flash {\r
+\r
+FlashCommandQueue::FlashCommandQueue() : newCommandEvent_(TRUE, FALSE) {\r
+}\r
+\r
+FlashCommandQueue::~FlashCommandQueue() {\r
+}\r
+\r
+void CancelCommand(FlashCommandPtr& pCommand) {\r
+       if(pCommand != 0)\r
+               pCommand->Cancel();\r
+}\r
+\r
+void FlashCommandQueue::Clear()\r
+{\r
+       Lock lock(*this);\r
+\r
+       std::for_each (commands_.begin(), commands_.end(), CancelCommand);\r
+       commands_.clear();\r
+\r
+       newCommandEvent_.Reset();\r
+}\r
+\r
+void FlashCommandQueue::Push(FlashCommandPtr pNewCommand)\r
+{\r
+       {\r
+               Lock lock(*this);\r
+               commands_.push_back(pNewCommand);\r
+       }\r
+\r
+       newCommandEvent_.Set();\r
+}\r
+\r
+FlashCommandPtr FlashCommandQueue::Pop()\r
+{\r
+       Lock lock(*this);\r
+\r
+       FlashCommandPtr result;\r
+       if(commands_.size() > 0)\r
+       {\r
+               result = commands_.front();\r
+               commands_.pop_front();\r
+\r
+               if(commands_.size() == 0)\r
+                       newCommandEvent_.Reset();\r
+       }\r
+       \r
+       return result;\r
+}\r
+\r
+}      //namespace flash\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/producers/flash/FlashCommandQueue.h b/server/producers/flash/FlashCommandQueue.h
new file mode 100644 (file)
index 0000000..14bed0f
--- /dev/null
@@ -0,0 +1,70 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _FLASHCOMMANDQUEUE_H__\r
+#define _FLASHCOMMANDQUEUE_H__\r
+\r
+#pragma once\r
+\r
+#include <list>\r
+#include <string>\r
+#include "..\..\utils\Lockable.h"\r
+#include "..\..\utils\event.h"\r
+\r
+namespace caspar {\r
+\r
+class FlashCommand;\r
+typedef std::tr1::shared_ptr<FlashCommand> FlashCommandPtr;\r
+\r
+namespace flash {\r
+\r
+//LoadCommand - creates axControl and loads it with the swf\r
+//StartCommand - Creates the buffers, DC and BITMAP and starts generating frames\r
+//ParamCommand - Sends a parameter to the swf\r
+\r
+\r
+class FlashCommandQueue : private utils::LockableObject\r
+{\r
+       FlashCommandQueue(const FlashCommandQueue&);\r
+       FlashCommandQueue& operator=(const FlashCommandQueue&);\r
+public:\r
+       FlashCommandQueue();\r
+       ~FlashCommandQueue();\r
+\r
+       void Push(FlashCommandPtr pCommand);\r
+       FlashCommandPtr Pop();\r
+\r
+       void Clear();\r
+\r
+       HANDLE GetWaitHandle() {\r
+               return newCommandEvent_;\r
+       }\r
+\r
+private:\r
+       utils::Event newCommandEvent_;\r
+\r
+       //Needs synro-protection\r
+       std::list<FlashCommandPtr>      commands_;\r
+};\r
+\r
+}      //namespace flash\r
+}      //namespace caspar\r
+\r
+#endif //_FLASHCOMMANDQUEUE_H__
\ No newline at end of file
diff --git a/server/producers/flash/FlashManager.cpp b/server/producers/flash/FlashManager.cpp
new file mode 100644 (file)
index 0000000..db28432
--- /dev/null
@@ -0,0 +1,76 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\..\stdafx.h"\r
+\r
+#include "FlashManager.h"\r
+#include "..\..\frame\FrameManager.h"\r
+#include "..\..\Application.h"\r
+#include "..\..\utils\image\Image.hpp"\r
+#include "TimerHelper.h"\r
+\r
+#include <math.h>\r
+#include <intrin.h>\r
+#pragma intrinsic(__movsd, __stosd)\r
+\r
+#include <objbase.h>\r
+#include <guiddef.h>\r
+#include <algorithm>\r
+\r
+#include "FlashProducer.h"\r
+\r
+namespace caspar {\r
+\r
+using namespace utils;\r
+\r
+\r
+FlashManager::FlashManager()\r
+{\r
+       _extensions.push_back(TEXT("swf"));\r
+\r
+       //Check that flash is installed\r
+       ATL::CComBSTR flashGUID(_T("{D27CDB6E-AE6D-11CF-96B8-444553540000}"));\r
+       CLSID clsid;\r
+       if(!SUCCEEDED(CLSIDFromString((LPOLESTR)flashGUID, &clsid))) {\r
+               throw std::exception("No Flash activex player installed");\r
+       }\r
+}\r
+\r
+FlashManager::~FlashManager() {\r
+}\r
+\r
+MediaProducerPtr FlashManager::CreateProducer(const tstring& filename)\r
+{\r
+       return FlashProducer::Create(filename);\r
+}\r
+\r
+bool FlashManager::getFileInfo(FileInfo* pFileInfo)\r
+{\r
+       if(pFileInfo->filetype == TEXT("swf"))\r
+       {\r
+               pFileInfo->length = 0;  //get real length from file\r
+               pFileInfo->type = TEXT("movie");\r
+               pFileInfo->encoding = TEXT("swf");\r
+       }\r
+       return true;\r
+}\r
+\r
+\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/producers/flash/FlashManager.h b/server/producers/flash/FlashManager.h
new file mode 100644 (file)
index 0000000..e7cbde2
--- /dev/null
@@ -0,0 +1,43 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _FLASHMEDIAMANAGER_H__\r
+#define _FLASHMEDIAMANAGER_H__\r
+\r
+#include "..\..\MediaManager.h"\r
+\r
+namespace caspar {\r
+\r
+class FlashManager : public IMediaManager\r
+{\r
+public:\r
+       FlashManager();\r
+       virtual ~FlashManager();\r
+\r
+       virtual MediaProducerPtr CreateProducer(const tstring& filename);\r
+       virtual bool getFileInfo(FileInfo* pFileInfo);\r
+};\r
+\r
+\r
+\r
+\r
+}      //namespace caspar\r
+\r
+#endif // _FLASHMEDIAMANAGER_H__\r
diff --git a/server/producers/flash/FlashProducer.cpp b/server/producers/flash/FlashProducer.cpp
new file mode 100644 (file)
index 0000000..801d8cf
--- /dev/null
@@ -0,0 +1,434 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\..\stdafx.h"\r
+\r
+#include "..\..\Application.h"\r
+#include "TimerHelper.h"\r
+#include "FlashProducer.h"\r
+#include "..\..\utils\Logger.h"\r
+#include "..\..\utils\LogLevel.h"\r
+#include "..\..\utils\image\Image.hpp"\r
+#include "..\..\application.h"\r
+#include "..\..\frame\BitmapFrameManagerAdapter.h"\r
+\r
+namespace caspar {\r
+\r
+using namespace utils;\r
+\r
+//////////////////////////////////////////////////////////////////////\r
+// FlashProducer\r
+//////////////////////////////////////////////////////////////////////\r
+FlashProducer::FlashProducer() : pFlashAxContainer_(0), bRunning_(false), frameBuffer_(2), pFnRenderer_(std::tr1::bind(&FlashProducer::WriteFrame, this)), pMonitor_(0), timerCount_(0)\r
+{\r
+}\r
+\r
+FlashProducer::~FlashProducer() \r
+{\r
+       worker_.Stop();\r
+}\r
+\r
+FlashProducerPtr FlashProducer::Create(const tstring& filename, Monitor* pMonitor)\r
+{\r
+       FlashProducerPtr result;\r
+\r
+       if(filename.length() > 0) {\r
+               result.reset(new FlashProducer());\r
+               result->pMonitor_ = pMonitor;\r
+\r
+               if(!(result->Create() && result->Load(filename)))\r
+                       result.reset();\r
+       }\r
+\r
+       return result;\r
+}\r
+\r
+IMediaController* FlashProducer::QueryController(const tstring& id) \r
+{      \r
+       return id == TEXT("FrameController") ? this : 0;\r
+}\r
+\r
+void FlashProducer::Stop() \r
+{\r
+       worker_.Stop(false);\r
+}\r
+\r
+void FlashProducer::Run(HANDLE stopEvent)\r
+{\r
+//#ifdef DEBUG\r
+//     srand(timeGetTime());\r
+//     int frameIndex = 0;\r
+//     int crashIndex = 200+rand()%200;\r
+//#endif\r
+\r
+       ::OleInitialize(NULL);\r
+       LOG << LogLevel::Verbose << TEXT("Flash readAhead thread started");\r
+\r
+       HANDLE waitHandles[3] = { stopEvent, commandQueue_.GetWaitHandle(), frameBuffer_.GetWriteWaitHandle() };\r
+       DWORD waitHandlesCount = sizeof(waitHandles) / sizeof(HANDLE) - 1;\r
+\r
+       bool bQuit = false;\r
+       while(!bQuit) \r
+       {\r
+               DWORD realWaitHandleCount = waitHandlesCount;\r
+               if(bRunning_)\r
+                       ++realWaitHandleCount;\r
+\r
+               HRESULT waitResult = MsgWaitForMultipleObjects(realWaitHandleCount, waitHandles, FALSE, 1000, QS_ALLINPUT);\r
+               switch(waitResult)\r
+               {\r
+               case (WAIT_OBJECT_0+0): //stop\r
+               case WAIT_FAILED:               //wait failiure\r
+                       bQuit = true;\r
+                       continue;\r
+\r
+               case (WAIT_OBJECT_0+1): //command\r
+                       {\r
+                               FlashCommandPtr pFlashCommand = commandQueue_.Pop();\r
+                               if(pFlashCommand != 0) {\r
+                                       pFlashCommand->Execute();\r
+                                       pFlashCommand.reset();\r
+                               }\r
+                       }\r
+                       continue;\r
+\r
+               case (WAIT_TIMEOUT):    //nothing has happened...\r
+                       continue;\r
+               }\r
+\r
+               //render next frame\r
+               if(bRunning_ && waitResult==(WAIT_OBJECT_0+2)) \r
+               {\r
+                       if(pFlashAxContainer_->bHasNewTiming_) \r
+                       {\r
+                               pFlashAxContainer_->bHasNewTiming_ = false;\r
+                               const caspar::FrameFormatDescription& fmtDesc = pFrameManager_->GetFrameFormatDescription();\r
+\r
+                               //render frames if we're playing on a channel with a progressive format OR if the FPS of the flash is half that of the channel\r
+                               int flashFPS = pFlashAxContainer_->GetFPS();\r
+                               bool bFrames = (fmtDesc.mode == Progressive || ((flashFPS - fmtDesc.fps/2) == 0));\r
+                               pFnRenderer_ = std::tr1::bind(bFrames ? &FlashProducer::WriteFrame : &FlashProducer::WriteFields, this);\r
+                       }\r
+                       \r
+                       if(pFlashAxContainer_->IsReadyToRender())\r
+                               this->pFnRenderer_();\r
+//#ifdef DEBUG\r
+//                     ++frameIndex;\r
+//                     if(frameIndex >= crashIndex)\r
+//                     {\r
+//                             //Go down in a ball of fire!\r
+//                             int* pCrash = 0;\r
+//                             *pCrash = 42;\r
+//                     }\r
+//#endif\r
+               }\r
+               \r
+               static int logCount = 0;\r
+               //take care of input (windowmessages)\r
+               if(waitResult == (WAIT_OBJECT_0 + realWaitHandleCount)) \r
+               {\r
+                       MSG msg;\r
+                       while(PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE)) \r
+                       {\r
+                               if(msg.message != WM_TIMER)\r
+                               {\r
+                                       if(logCount < 1000)\r
+                                       {\r
+                                               LOG << TEXT("[FlashProducer] ####### Received MSG message: ") << msg.message << TEXT(" lParam: ") << msg.lParam << TEXT(" wParam: ") << msg.wParam;\r
+                                               ++logCount;\r
+                                       }\r
+                                       TranslateMessage(&msg);\r
+                                       DispatchMessage(&msg);\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+\r
+       if(pFlashAxContainer_) \r
+       {\r
+               pFlashAxContainer_->DestroyAxControl();\r
+\r
+               pFlashAxContainer_->Release();\r
+               pFlashAxContainer_ = 0;\r
+       }\r
+\r
+       commandQueue_.Clear();\r
+\r
+       FramePtr pNullFrame;\r
+       frameBuffer_.push_back(pNullFrame);\r
+       LOG << LogLevel::Verbose << TEXT("Flash readAhead thread ended");\r
+       ::OleUninitialize();\r
+}\r
+\r
+bool FlashProducer::OnUnhandledException(const std::exception& ex) throw() \r
+{\r
+       try \r
+       {\r
+               FramePtr pNullFrame;\r
+               frameBuffer_.push_back(pNullFrame);\r
+\r
+               LOG << LogLevel::Critical << TEXT("UNHANDLED EXCEPTION in flash readahead-thread. Message: ") << ex.what();\r
+\r
+               if(pFlashAxContainer_) {\r
+                       pFlashAxContainer_->DestroyAxControl();\r
+\r
+                       pFlashAxContainer_->Release();\r
+                       pFlashAxContainer_ = 0;\r
+               }\r
+\r
+               commandQueue_.Clear();\r
+               ::OleUninitialize();\r
+       }\r
+       catch(...)\r
+       {\r
+               try \r
+               {\r
+                       pFlashAxContainer_ = 0;\r
+               } \r
+               catch(...){}\r
+       }\r
+\r
+       return false;\r
+}\r
+\r
+void FlashProducer::SetEmptyAlert(EmptyCallback callback) \r
+{\r
+       emptyCallback = callback;\r
+}\r
+\r
+bool FlashProducer::IsEmpty() const \r
+{\r
+       return (pFlashAxContainer_ != 0) ? pFlashAxContainer_->bIsEmpty_ : true;\r
+}\r
+\r
+void FlashProducer::WriteFields()\r
+{              \r
+       const caspar::FrameFormatDescription& fmtDesc = pFrameManager_->GetFrameFormatDescription();\r
+       \r
+       FramePtr pNextFrame1 = RenderFrame();\r
+       FramePtr pNextFrame2 = RenderFrame();\r
+\r
+       if(pNextFrame1 != pNextFrame2)\r
+               utils::image::CopyField(pNextFrame1->GetDataPtr(), pNextFrame2->GetDataPtr(), 1, fmtDesc.width, fmtDesc.height); // TODO: at this point we should spawn work as a task to allow rendering of next frame while copying\r
+\r
+       frameBuffer_.push_back(pNextFrame1);\r
+}\r
+\r
+void FlashProducer::WriteFrame()\r
+{\r
+       frameBuffer_.push_back(RenderFrame()); // Consumer always expects frameFramePtr pResultFrame = pFrameManager_->CreateFrame();\r
+}\r
+\r
+FramePtr FlashProducer::RenderFrame()\r
+{      \r
+       if(pFlashAxContainer_->pTimerHelper)\r
+       {\r
+               DWORD time = pFlashAxContainer_->pTimerHelper->Invoke(); // Tick flash\r
+               if(time - timerCount_ >= 400)\r
+               {\r
+                       timerCount_ = time;\r
+                       HRESULT hr;\r
+                       pFlashAxContainer_->m_spInPlaceObjectWindowless->OnWindowMessage(WM_TIMER, 3, 0, &hr);\r
+               }\r
+       }\r
+\r
+       if(pFlashAxContainer_->bInvalidRect_ || pCurrentFrame_ == NULL)\r
+       {               \r
+               FramePtr pNewFrame = pFrameManager_->CreateFrame();\r
+\r
+               image::Clear(pNewFrame->GetDataPtr(), pFrameManager_->GetFrameFormatDescription().size);\r
+               pFlashAxContainer_->DrawControl(reinterpret_cast<HDC>(pNewFrame->GetMetadata())); // error handling?    \r
+\r
+               pFlashAxContainer_->bInvalidRect_ = false;      \r
+               \r
+               pCurrentFrame_ = pNewFrame;                     \r
+       }       \r
+       assert(pCurrentFrame_);\r
+       return pCurrentFrame_;\r
+}\r
+\r
+bool FlashProducer::Create() \r
+{\r
+       //Create worker-thread\r
+       worker_.Start(this);\r
+\r
+       //dispatch DoCreate-command\r
+       FlashCommandPtr pCreateCommand(new GenericFlashCommand(this, &caspar::FlashProducer::DoCreate));\r
+\r
+       commandQueue_.Push(pCreateCommand);\r
+       if(pCreateCommand->Wait(INFINITE))\r
+               return pCreateCommand->GetResult();     \r
+\r
+       return false;\r
+}\r
+\r
+bool FlashProducer::Load(const tstring& filename) \r
+{\r
+       if(worker_.IsRunning()) \r
+       {\r
+               //dispatch DoLoad-command\r
+               FlashCommandPtr pLoadCommand(new GenericFlashCommand(this, &caspar::FlashProducer::DoLoad, filename));\r
+\r
+               commandQueue_.Push(pLoadCommand);\r
+               if(pLoadCommand->Wait(INFINITE))\r
+                       return pLoadCommand->GetResult();               \r
+       }\r
+       return false;\r
+}\r
+\r
+bool FlashProducer::Initialize(FrameManagerPtr pFrameManager) \r
+{\r
+       if(worker_.IsRunning() && pFrameManager != 0) \r
+       {\r
+               //dispatch Initialize-command\r
+               FlashCommandPtr pInitializeCommand(new InitializeFlashCommand(this, pFrameManager));\r
+               commandQueue_.Push(pInitializeCommand);\r
+               if(pInitializeCommand->Wait(INFINITE)) \r
+                       return pInitializeCommand->GetResult();         \r
+       }\r
+       return false;   \r
+}\r
+\r
+bool FlashProducer::Param(const tstring &param) \r
+{\r
+       if(worker_.IsRunning()) \r
+       {\r
+               //dispatch DoParam-command\r
+               FlashCommandPtr pParamCommand(new GenericFlashCommand(this, &caspar::FlashProducer::DoParam, param));\r
+               commandQueue_.Push(pParamCommand);\r
+               return true;\r
+       }\r
+       return false;\r
+}\r
+\r
+//This is always run from the worker thread\r
+//This is called when the MediaProducer is created\r
+bool FlashProducer::DoCreate(const tstring&) \r
+{\r
+       HRESULT hr = CComObject<caspar::flash::FlashAxContainer>::CreateInstance(&pFlashAxContainer_);\r
+       if(pFlashAxContainer_) \r
+       {\r
+               pFlashAxContainer_->pFlashProducer_ = this;\r
+               HRESULT hr = pFlashAxContainer_->CreateAxControl();\r
+               if(FAILED(hr))\r
+                       return false;\r
+\r
+               CComPtr<IShockwaveFlash> spFlash;\r
+               pFlashAxContainer_->QueryControl(&spFlash);\r
+               if(spFlash)             \r
+                       spFlash->put_Playing(TRUE);             \r
+               else\r
+                       return false;\r
+       }\r
+       else\r
+               return false;\r
+\r
+       return true;\r
+}\r
+\r
+//This is always run from the worker thread\r
+//This is called when the MediaProducer is created\r
+bool FlashProducer::DoLoad(const tstring &filename) \r
+{\r
+       filename_ = filename;\r
+       if(filename_.length() == 0)\r
+               return false;\r
+\r
+       CComPtr<IShockwaveFlash> spFlash;\r
+       pFlashAxContainer_->QueryControl(&spFlash);\r
+       if(!spFlash)\r
+               return false;\r
+\r
+       spFlash->put_AllowFullScreen(CComBSTR(TEXT("true")));\r
+       HRESULT hrLoad = spFlash->put_Movie(CComBSTR(filename_.c_str()));\r
+       spFlash->put_ScaleMode(2);      //Exact fit. Scale without respect to the aspect ratio\r
+       return SUCCEEDED(hrLoad);\r
+}\r
+\r
+//This is always run from the worker thread\r
+//This is called frÃ¥n FrameMediaController::Initialize\r
+bool FlashProducer::DoInitialize(FrameManagerPtr pFrameManager)\r
+{\r
+       int oldWidth = 0, oldHeight = 0;\r
+       if(pFrameManager_ != 0) \r
+       {\r
+               const caspar::FrameFormatDescription& oldFmtDesc = pFrameManager_->GetFrameFormatDescription();\r
+               oldWidth = oldFmtDesc.width;\r
+               oldHeight = oldFmtDesc.height;\r
+       }\r
+\r
+       pFrameManager_ = pFrameManager->HasFeature("BITMAP_FRAME") ? pFrameManager : FrameManagerPtr(new BitmapFrameManagerAdapter(pFrameManager, GetApplication()->GetMainWindow()->getHwnd()));\r
+       const caspar::FrameFormatDescription& fmtDesc = pFrameManager_->GetFrameFormatDescription();\r
+       \r
+       pCurrentFrame_ = FramePtr();\r
+\r
+       if(fmtDesc.width != oldWidth || fmtDesc.height != oldHeight)    \r
+               pFlashAxContainer_->SetFormat(fmtDesc);         \r
+\r
+       bRunning_ = true;\r
+       return true;\r
+}\r
+\r
+//This is always run from the worker thread\r
+//this can get called at any time after the producer is loaded\r
+bool FlashProducer::DoParam(const tstring& param) \r
+{\r
+       HRESULT hr;\r
+       CComPtr<IShockwaveFlash> spFlash;\r
+       pFlashAxContainer_->bIsEmpty_ = false;\r
+       pFlashAxContainer_->bCallSuccessful_ = false;\r
+       pFlashAxContainer_->QueryControl(&spFlash);\r
+       CComBSTR request(param.c_str());\r
+       //ATLTRACE(_T("ShockwaveFlash::CallFuntion\n"));\r
+\r
+       if(spFlash)\r
+       {\r
+               int retries = 0;\r
+               bool bSuccess = false;\r
+\r
+               while(!bSuccess && retries < 5)\r
+               {\r
+                       CComBSTR result;\r
+                       //LOG << LogLevel::Debug << TEXT("Calling ExternalInterface: ") << param;\r
+                       hr = spFlash->CallFunction(request, &result);\r
+                       bSuccess = (hr == S_OK);\r
+\r
+                       if(hr != S_OK) \r
+                       {\r
+                               //LOG << LogLevel::Debug << TEXT("Flashproducer: ExternalInterface-call failed. (HRESULT = ") << hr << TEXT(")");\r
+                               if(pFlashAxContainer_->bCallSuccessful_)\r
+                               {\r
+                                       bSuccess = true;\r
+                               }\r
+                               else \r
+                               {\r
+                                       ++retries;\r
+                                       LOG << LogLevel::Debug << TEXT("Retrying. Count = ") << retries;\r
+                               }\r
+                       }\r
+               }\r
+\r
+               return (hr == S_OK);\r
+       }\r
+\r
+       return false;\r
+}\r
+\r
+}
\ No newline at end of file
diff --git a/server/producers/flash/FlashProducer.h b/server/producers/flash/FlashProducer.h
new file mode 100644 (file)
index 0000000..dc4f7de
--- /dev/null
@@ -0,0 +1,121 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _FLASHPRODUCER_H_\r
+#define _FLASHPRODUCER_H_\r
+\r
+//std include\r
+#include <vector>\r
+#include <string>\r
+#include <functional>\r
+\r
+#include "..\..\MediaProducer.h"\r
+#include "..\..\frame\FrameMediaController.h"\r
+#include "FlashAxContainer.h"\r
+#include "FlashCommandQueue.h"\r
+#include "..\..\frame\BitmapFrame.h"\r
+#include "FlashCommand.h"\r
+\r
+#include "..\..\utils\thread.h"\r
+#include "..\..\frame\buffers\MotionFrameBuffer.h"\r
+\r
+namespace caspar\r
+{\r
+\r
+class Monitor;\r
+\r
+class FlashProducer;\r
+typedef std::tr1::shared_ptr<FlashProducer> FlashProducerPtr;\r
+\r
+typedef std::tr1::function<void()> EmptyCallback;\r
+\r
+class FlashProducer : public MediaProducer, FrameMediaController, utils::IRunnable\r
+{\r
+       FlashProducer(const FlashProducer&);\r
+\r
+public:\r
+       static FlashProducerPtr Create(const tstring& filename, Monitor* pMonitor=0);\r
+\r
+       FlashProducer();\r
+       virtual ~FlashProducer();\r
+\r
+       //MediaProducer\r
+       virtual IMediaController* QueryController(const tstring& id);\r
+       virtual bool Param(const tstring& param);\r
+\r
+       //FrameMediaController\r
+       virtual bool Initialize(FrameManagerPtr pFrameManager);\r
+       virtual FrameBuffer& GetFrameBuffer() {\r
+               return frameBuffer_;\r
+       }\r
+\r
+       bool IsEmpty() const;\r
+\r
+       void Stop();\r
+       void SetEmptyAlert(EmptyCallback callback);\r
+\r
+       bool Create();\r
+       bool Load(const tstring& filename);\r
+\r
+private:\r
+\r
+       friend class FlashCommand;\r
+       friend class InitializeFlashCommand;\r
+       friend class flash::FlashAxContainer;\r
+       friend class FullscreenControllerFlashCommand;\r
+\r
+       bool DoCreate(const tstring&);\r
+       bool DoLoad(const tstring &);\r
+       bool DoInitialize(FrameManagerPtr pFrameManager);\r
+       bool DoParam(const tstring&);\r
+\r
+       virtual void Run(HANDLE stopEvent);\r
+       virtual bool OnUnhandledException(const std::exception& ex) throw();\r
+\r
+       EmptyCallback emptyCallback;\r
+\r
+       MotionFrameBuffer frameBuffer_;\r
+\r
+       DWORD timerCount_;\r
+\r
+       utils::Thread worker_;\r
+\r
+       tstring filename_;\r
+       bool bRunning_;\r
+       CComObject<caspar::flash::FlashAxContainer>* pFlashAxContainer_;\r
+       caspar::flash::FlashCommandQueue commandQueue_;\r
+\r
+       FramePtr pCurrentFrame_;\r
+\r
+       FramePtr RenderFrame();\r
+       void WriteFields(void);\r
+       void WriteFrame(void);\r
+       std::tr1::function<void()> pFnRenderer_;\r
+       \r
+       FrameManagerPtr pFrameManager_;\r
+       Monitor* pMonitor_;\r
+       //void CopyFieldToFrameBuffer(FramePtr frame1, FramePtr frame2, size_t fieldIndex, size_t width, size_t height);\r
+};\r
+\r
+typedef bool (FlashProducer::*FlashMemberFnPtr)(const tstring&);\r
+\r
+}\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/producers/flash/TimerHelper.h b/server/producers/flash/TimerHelper.h
new file mode 100644 (file)
index 0000000..a0de2b1
--- /dev/null
@@ -0,0 +1,77 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _TIMER_HELPER_H__\r
+#define _TIMER_HELPER_H__\r
+\r
+#include "FlashAxContainer.h"\r
+\r
+namespace caspar {\r
+namespace flash {\r
+\r
+       class TimerHelper\r
+       {\r
+               TimerHelper(const TimerHelper&);\r
+               const TimerHelper& operator=(const TimerHelper&);\r
+\r
+       public:\r
+               TimerHelper()\r
+               {}\r
+               TimerHelper(DWORD first, DWORD interv, ITimerSink* pTS) : firstTime(first), interval(interv), currentTime(first), pTimerSink(pTS)\r
+               {\r
+                       ID = first;\r
+               }\r
+               ~TimerHelper()\r
+               {\r
+               }\r
+               void Setup(DWORD first, DWORD interv, ITimerSink* pTS)\r
+               {\r
+                       firstTime = first;\r
+                       interval = interv;\r
+                       currentTime = first;\r
+                       pTimerSink = pTS;\r
+                       ID = first;\r
+               }\r
+\r
+               DWORD Invoke()\r
+               {\r
+                       if(pTimerSink != 0)\r
+                       {\r
+                               VARIANT value;\r
+                               value.vt = VT_UI4;\r
+                               value.ulVal = currentTime;\r
+\r
+                               pTimerSink->OnTimer(value);\r
+                               currentTime += interval;\r
+                       }\r
+                       return currentTime;\r
+               }\r
+\r
+               DWORD firstTime;\r
+               DWORD interval;\r
+               DWORD currentTime;\r
+               ATL::CComPtr<ITimerSink> pTimerSink;\r
+               DWORD ID;\r
+       };\r
+\r
+}      //namespace flash\r
+}      //namespace caspar\r
+\r
+#endif //_TIMER_HELPER_H__
\ No newline at end of file
diff --git a/server/producers/flash/axflash.h b/server/producers/flash/axflash.h
new file mode 100644 (file)
index 0000000..4685f3a
--- /dev/null
@@ -0,0 +1,3156 @@
+\r
+\r
+/* this ALWAYS GENERATED file contains the definitions for the interfaces */\r
+\r
+\r
+ /* File created by MIDL compiler version 6.00.0366 */\r
+/* at Tue Mar 18 13:05:00 2008\r
+ */\r
+/* Compiler settings for .\flash\Flash9e.IDL:\r
+    Oicf, W4, Zp8, env=Win32 (32b run)\r
+    protocol : dce , ms_ext, c_ext, robust\r
+    error checks: allocation ref bounds_check enum stub_data \r
+    VC __declspec() decoration level: \r
+         __declspec(uuid()), __declspec(selectany), __declspec(novtable)\r
+         DECLSPEC_UUID(), MIDL_INTERFACE()\r
+*/\r
+//@@MIDL_FILE_HEADING(  )\r
+\r
+#pragma warning( disable: 4049 )  /* more than 64k source lines */\r
+\r
+\r
+/* verify that the <rpcndr.h> version is high enough to compile this file*/\r
+#ifndef __REQUIRED_RPCNDR_H_VERSION__\r
+#define __REQUIRED_RPCNDR_H_VERSION__ 475\r
+#endif\r
+\r
+#include "rpc.h"\r
+#include "rpcndr.h"\r
+#include <dispex.h>\r
+\r
+#ifndef __RPCNDR_H_VERSION__\r
+#error this stub requires an updated version of <rpcndr.h>\r
+#endif // __RPCNDR_H_VERSION__\r
+\r
+\r
+#ifndef __axflash_h__\r
+#define __axflash_h__\r
+\r
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)\r
+#pragma once\r
+#endif\r
+\r
+/* Forward Declarations */ \r
+\r
+#ifndef __IShockwaveFlash_FWD_DEFINED__\r
+#define __IShockwaveFlash_FWD_DEFINED__\r
+typedef interface IShockwaveFlash IShockwaveFlash;\r
+#endif         /* __IShockwaveFlash_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef ___IShockwaveFlashEvents_FWD_DEFINED__\r
+#define ___IShockwaveFlashEvents_FWD_DEFINED__\r
+typedef interface _IShockwaveFlashEvents _IShockwaveFlashEvents;\r
+#endif         /* ___IShockwaveFlashEvents_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IFlashFactory_FWD_DEFINED__\r
+#define __IFlashFactory_FWD_DEFINED__\r
+typedef interface IFlashFactory IFlashFactory;\r
+#endif         /* __IFlashFactory_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IDispatchEx_FWD_DEFINED__\r
+#define __IDispatchEx_FWD_DEFINED__\r
+typedef interface IDispatchEx IDispatchEx;\r
+#endif         /* __IDispatchEx_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IFlashObjectInterface_FWD_DEFINED__\r
+#define __IFlashObjectInterface_FWD_DEFINED__\r
+typedef interface IFlashObjectInterface IFlashObjectInterface;\r
+#endif         /* __IFlashObjectInterface_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __IServiceProvider_FWD_DEFINED__\r
+#define __IServiceProvider_FWD_DEFINED__\r
+typedef interface IServiceProvider IServiceProvider;\r
+#endif         /* __IServiceProvider_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __ShockwaveFlash_FWD_DEFINED__\r
+#define __ShockwaveFlash_FWD_DEFINED__\r
+\r
+#ifdef __cplusplus\r
+typedef class ShockwaveFlash ShockwaveFlash;\r
+#else\r
+typedef struct ShockwaveFlash ShockwaveFlash;\r
+#endif /* __cplusplus */\r
+\r
+#endif         /* __ShockwaveFlash_FWD_DEFINED__ */\r
+\r
+\r
+#ifndef __FlashObjectInterface_FWD_DEFINED__\r
+#define __FlashObjectInterface_FWD_DEFINED__\r
+\r
+#ifdef __cplusplus\r
+typedef class FlashObjectInterface FlashObjectInterface;\r
+#else\r
+typedef struct FlashObjectInterface FlashObjectInterface;\r
+#endif /* __cplusplus */\r
+\r
+#endif         /* __FlashObjectInterface_FWD_DEFINED__ */\r
+\r
+\r
+#ifdef __cplusplus\r
+extern "C"{\r
+#endif \r
+\r
+void * __RPC_USER MIDL_user_allocate(size_t);\r
+void __RPC_USER MIDL_user_free( void * ); \r
+\r
+\r
+#ifndef __ShockwaveFlashObjects_LIBRARY_DEFINED__\r
+#define __ShockwaveFlashObjects_LIBRARY_DEFINED__\r
+\r
+/* library ShockwaveFlashObjects */\r
+/* [custom][custom][helpstring][version][uuid] */ \r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+EXTERN_C const IID LIBID_ShockwaveFlashObjects;\r
+\r
+#ifndef __IShockwaveFlash_INTERFACE_DEFINED__\r
+#define __IShockwaveFlash_INTERFACE_DEFINED__\r
+\r
+/* interface IShockwaveFlash */\r
+/* [object][oleautomation][dual][helpstring][uuid] */ \r
+\r
+\r
+EXTERN_C const IID IID_IShockwaveFlash;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("D27CDB6C-AE6D-11CF-96B8-444553540000")\r
+    IShockwaveFlash : public IDispatch\r
+    {\r
+    public:\r
+        virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_ReadyState( \r
+            /* [retval][out] */ long *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_TotalFrames( \r
+            /* [retval][out] */ long *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_Playing( \r
+            /* [retval][out] */ VARIANT_BOOL *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_Playing( \r
+            /* [in] */ VARIANT_BOOL pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_Quality( \r
+            /* [retval][out] */ int *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_Quality( \r
+            /* [in] */ int pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_ScaleMode( \r
+            /* [retval][out] */ int *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_ScaleMode( \r
+            /* [in] */ int pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_AlignMode( \r
+            /* [retval][out] */ int *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_AlignMode( \r
+            /* [in] */ int pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_BackgroundColor( \r
+            /* [retval][out] */ long *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_BackgroundColor( \r
+            /* [in] */ long pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_Loop( \r
+            /* [retval][out] */ VARIANT_BOOL *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_Loop( \r
+            /* [in] */ VARIANT_BOOL pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_Movie( \r
+            /* [retval][out] */ BSTR *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_Movie( \r
+            /* [in] */ BSTR pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_FrameNum( \r
+            /* [retval][out] */ long *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_FrameNum( \r
+            /* [in] */ long pVal) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE SetZoomRect( \r
+            /* [in] */ long left,\r
+            /* [in] */ long top,\r
+            /* [in] */ long right,\r
+            /* [in] */ long bottom) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Zoom( \r
+            /* [in] */ int factor) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Pan( \r
+            /* [in] */ long x,\r
+            /* [in] */ long y,\r
+            /* [in] */ int mode) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Play( void) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Stop( void) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Back( void) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Forward( void) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Rewind( void) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE StopPlay( void) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE GotoFrame( \r
+            /* [in] */ long FrameNum) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE CurrentFrame( \r
+            /* [retval][out] */ long *FrameNum) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IsPlaying( \r
+            /* [retval][out] */ VARIANT_BOOL *Playing) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE PercentLoaded( \r
+            /* [retval][out] */ long *percent) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE FrameLoaded( \r
+            /* [in] */ long FrameNum,\r
+            /* [retval][out] */ VARIANT_BOOL *loaded) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE FlashVersion( \r
+            /* [retval][out] */ long *version) = 0;\r
+        \r
+        virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_WMode( \r
+            /* [retval][out] */ BSTR *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_WMode( \r
+            /* [in] */ BSTR pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_SAlign( \r
+            /* [retval][out] */ BSTR *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_SAlign( \r
+            /* [in] */ BSTR pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_Menu( \r
+            /* [retval][out] */ VARIANT_BOOL *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_Menu( \r
+            /* [in] */ VARIANT_BOOL pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_Base( \r
+            /* [retval][out] */ BSTR *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_Base( \r
+            /* [in] */ BSTR pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_Scale( \r
+            /* [retval][out] */ BSTR *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_Scale( \r
+            /* [in] */ BSTR pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_DeviceFont( \r
+            /* [retval][out] */ VARIANT_BOOL *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_DeviceFont( \r
+            /* [in] */ VARIANT_BOOL pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_EmbedMovie( \r
+            /* [retval][out] */ VARIANT_BOOL *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_EmbedMovie( \r
+            /* [in] */ VARIANT_BOOL pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_BGColor( \r
+            /* [retval][out] */ BSTR *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_BGColor( \r
+            /* [in] */ BSTR pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_Quality2( \r
+            /* [retval][out] */ BSTR *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_Quality2( \r
+            /* [in] */ BSTR pVal) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE LoadMovie( \r
+            /* [in] */ int layer,\r
+            /* [in] */ BSTR url) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE TGotoFrame( \r
+            /* [in] */ BSTR target,\r
+            /* [in] */ long FrameNum) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE TGotoLabel( \r
+            /* [in] */ BSTR target,\r
+            /* [in] */ BSTR label) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE TCurrentFrame( \r
+            /* [in] */ BSTR target,\r
+            /* [retval][out] */ long *FrameNum) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE TCurrentLabel( \r
+            /* [in] */ BSTR target,\r
+            /* [retval][out] */ BSTR *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE TPlay( \r
+            /* [in] */ BSTR target) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE TStopPlay( \r
+            /* [in] */ BSTR target) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE SetVariable( \r
+            /* [in] */ BSTR name,\r
+            /* [in] */ BSTR value) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE GetVariable( \r
+            /* [in] */ BSTR name,\r
+            /* [retval][out] */ BSTR *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE TSetProperty( \r
+            /* [in] */ BSTR target,\r
+            /* [in] */ int property,\r
+            /* [in] */ BSTR value) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE TGetProperty( \r
+            /* [in] */ BSTR target,\r
+            /* [in] */ int property,\r
+            /* [retval][out] */ BSTR *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE TCallFrame( \r
+            /* [in] */ BSTR target,\r
+            /* [in] */ int FrameNum) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE TCallLabel( \r
+            /* [in] */ BSTR target,\r
+            /* [in] */ BSTR label) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE TSetPropertyNum( \r
+            /* [in] */ BSTR target,\r
+            /* [in] */ int property,\r
+            /* [in] */ double value) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE TGetPropertyNum( \r
+            /* [in] */ BSTR target,\r
+            /* [in] */ int property,\r
+            /* [retval][out] */ double *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE TGetPropertyAsNumber( \r
+            /* [in] */ BSTR target,\r
+            /* [in] */ int property,\r
+            /* [retval][out] */ double *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_SWRemote( \r
+            /* [retval][out] */ BSTR *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_SWRemote( \r
+            /* [in] */ BSTR pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_FlashVars( \r
+            /* [retval][out] */ BSTR *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_FlashVars( \r
+            /* [in] */ BSTR pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_AllowScriptAccess( \r
+            /* [retval][out] */ BSTR *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_AllowScriptAccess( \r
+            /* [in] */ BSTR pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_MovieData( \r
+            /* [retval][out] */ BSTR *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_MovieData( \r
+            /* [in] */ BSTR pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_InlineData( \r
+            /* [retval][out] */ IUnknown **ppIUnknown) = 0;\r
+        \r
+        virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_InlineData( \r
+            /* [in] */ IUnknown *ppIUnknown) = 0;\r
+        \r
+        virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_SeamlessTabbing( \r
+            /* [retval][out] */ VARIANT_BOOL *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_SeamlessTabbing( \r
+            /* [in] */ VARIANT_BOOL pVal) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE EnforceLocalSecurity( void) = 0;\r
+        \r
+        virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_Profile( \r
+            /* [retval][out] */ VARIANT_BOOL *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_Profile( \r
+            /* [in] */ VARIANT_BOOL pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_ProfileAddress( \r
+            /* [retval][out] */ BSTR *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_ProfileAddress( \r
+            /* [in] */ BSTR pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_ProfilePort( \r
+            /* [retval][out] */ long *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_ProfilePort( \r
+            /* [in] */ long pVal) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE CallFunction( \r
+            /* [in] */ BSTR request,\r
+            /* [retval][out] */ BSTR *response) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE SetReturnValue( \r
+            /* [in] */ BSTR returnValue) = 0;\r
+        \r
+        virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE DisableLocalSecurity( void) = 0;\r
+        \r
+        virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_AllowNetworking( \r
+            /* [retval][out] */ BSTR *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_AllowNetworking( \r
+            /* [in] */ BSTR pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_AllowFullScreen( \r
+            /* [retval][out] */ BSTR *pVal) = 0;\r
+        \r
+        virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_AllowFullScreen( \r
+            /* [in] */ BSTR pVal) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IShockwaveFlashVtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IShockwaveFlash * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IShockwaveFlash * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( \r
+            IShockwaveFlash * This,\r
+            /* [out] */ UINT *pctinfo);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ UINT iTInfo,\r
+            /* [in] */ LCID lcid,\r
+            /* [out] */ ITypeInfo **ppTInfo);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [size_is][in] */ LPOLESTR *rgszNames,\r
+            /* [in] */ UINT cNames,\r
+            /* [in] */ LCID lcid,\r
+            /* [size_is][out] */ DISPID *rgDispId);\r
+        \r
+        /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ DISPID dispIdMember,\r
+            /* [in] */ REFIID riid,\r
+            /* [in] */ LCID lcid,\r
+            /* [in] */ WORD wFlags,\r
+            /* [out][in] */ DISPPARAMS *pDispParams,\r
+            /* [out] */ VARIANT *pVarResult,\r
+            /* [out] */ EXCEPINFO *pExcepInfo,\r
+            /* [out] */ UINT *puArgErr);\r
+        \r
+        /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ReadyState )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ long *pVal);\r
+        \r
+        /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_TotalFrames )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ long *pVal);\r
+        \r
+        /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Playing )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ VARIANT_BOOL *pVal);\r
+        \r
+        /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Playing )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ VARIANT_BOOL pVal);\r
+        \r
+        /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Quality )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ int *pVal);\r
+        \r
+        /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Quality )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ int pVal);\r
+        \r
+        /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ScaleMode )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ int *pVal);\r
+        \r
+        /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ScaleMode )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ int pVal);\r
+        \r
+        /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AlignMode )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ int *pVal);\r
+        \r
+        /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_AlignMode )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ int pVal);\r
+        \r
+        /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BackgroundColor )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ long *pVal);\r
+        \r
+        /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BackgroundColor )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ long pVal);\r
+        \r
+        /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Loop )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ VARIANT_BOOL *pVal);\r
+        \r
+        /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Loop )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ VARIANT_BOOL pVal);\r
+        \r
+        /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Movie )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ BSTR *pVal);\r
+        \r
+        /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Movie )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR pVal);\r
+        \r
+        /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_FrameNum )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ long *pVal);\r
+        \r
+        /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_FrameNum )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ long pVal);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *SetZoomRect )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ long left,\r
+            /* [in] */ long top,\r
+            /* [in] */ long right,\r
+            /* [in] */ long bottom);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Zoom )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ int factor);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Pan )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ long x,\r
+            /* [in] */ long y,\r
+            /* [in] */ int mode);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Play )( \r
+            IShockwaveFlash * This);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Stop )( \r
+            IShockwaveFlash * This);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Back )( \r
+            IShockwaveFlash * This);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Forward )( \r
+            IShockwaveFlash * This);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Rewind )( \r
+            IShockwaveFlash * This);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *StopPlay )( \r
+            IShockwaveFlash * This);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *GotoFrame )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ long FrameNum);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *CurrentFrame )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ long *FrameNum);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *IsPlaying )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ VARIANT_BOOL *Playing);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *PercentLoaded )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ long *percent);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *FrameLoaded )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ long FrameNum,\r
+            /* [retval][out] */ VARIANT_BOOL *loaded);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *FlashVersion )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ long *version);\r
+        \r
+        /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_WMode )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ BSTR *pVal);\r
+        \r
+        /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_WMode )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR pVal);\r
+        \r
+        /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SAlign )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ BSTR *pVal);\r
+        \r
+        /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_SAlign )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR pVal);\r
+        \r
+        /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Menu )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ VARIANT_BOOL *pVal);\r
+        \r
+        /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Menu )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ VARIANT_BOOL pVal);\r
+        \r
+        /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Base )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ BSTR *pVal);\r
+        \r
+        /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Base )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR pVal);\r
+        \r
+        /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Scale )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ BSTR *pVal);\r
+        \r
+        /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Scale )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR pVal);\r
+        \r
+        /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DeviceFont )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ VARIANT_BOOL *pVal);\r
+        \r
+        /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DeviceFont )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ VARIANT_BOOL pVal);\r
+        \r
+        /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EmbedMovie )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ VARIANT_BOOL *pVal);\r
+        \r
+        /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EmbedMovie )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ VARIANT_BOOL pVal);\r
+        \r
+        /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BGColor )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ BSTR *pVal);\r
+        \r
+        /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BGColor )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR pVal);\r
+        \r
+        /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Quality2 )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ BSTR *pVal);\r
+        \r
+        /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Quality2 )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR pVal);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *LoadMovie )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ int layer,\r
+            /* [in] */ BSTR url);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *TGotoFrame )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR target,\r
+            /* [in] */ long FrameNum);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *TGotoLabel )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR target,\r
+            /* [in] */ BSTR label);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *TCurrentFrame )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR target,\r
+            /* [retval][out] */ long *FrameNum);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *TCurrentLabel )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR target,\r
+            /* [retval][out] */ BSTR *pVal);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *TPlay )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR target);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *TStopPlay )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR target);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *SetVariable )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR name,\r
+            /* [in] */ BSTR value);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *GetVariable )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR name,\r
+            /* [retval][out] */ BSTR *pVal);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *TSetProperty )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR target,\r
+            /* [in] */ int property,\r
+            /* [in] */ BSTR value);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *TGetProperty )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR target,\r
+            /* [in] */ int property,\r
+            /* [retval][out] */ BSTR *pVal);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *TCallFrame )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR target,\r
+            /* [in] */ int FrameNum);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *TCallLabel )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR target,\r
+            /* [in] */ BSTR label);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *TSetPropertyNum )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR target,\r
+            /* [in] */ int property,\r
+            /* [in] */ double value);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *TGetPropertyNum )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR target,\r
+            /* [in] */ int property,\r
+            /* [retval][out] */ double *pVal);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *TGetPropertyAsNumber )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR target,\r
+            /* [in] */ int property,\r
+            /* [retval][out] */ double *pVal);\r
+        \r
+        /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SWRemote )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ BSTR *pVal);\r
+        \r
+        /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_SWRemote )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR pVal);\r
+        \r
+        /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_FlashVars )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ BSTR *pVal);\r
+        \r
+        /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_FlashVars )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR pVal);\r
+        \r
+        /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AllowScriptAccess )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ BSTR *pVal);\r
+        \r
+        /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_AllowScriptAccess )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR pVal);\r
+        \r
+        /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_MovieData )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ BSTR *pVal);\r
+        \r
+        /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_MovieData )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR pVal);\r
+        \r
+        /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_InlineData )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ IUnknown **ppIUnknown);\r
+        \r
+        /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_InlineData )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ IUnknown *ppIUnknown);\r
+        \r
+        /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SeamlessTabbing )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ VARIANT_BOOL *pVal);\r
+        \r
+        /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_SeamlessTabbing )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ VARIANT_BOOL pVal);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *EnforceLocalSecurity )( \r
+            IShockwaveFlash * This);\r
+        \r
+        /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Profile )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ VARIANT_BOOL *pVal);\r
+        \r
+        /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Profile )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ VARIANT_BOOL pVal);\r
+        \r
+        /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ProfileAddress )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ BSTR *pVal);\r
+        \r
+        /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ProfileAddress )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR pVal);\r
+        \r
+        /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ProfilePort )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ long *pVal);\r
+        \r
+        /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ProfilePort )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ long pVal);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *CallFunction )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR request,\r
+            /* [retval][out] */ BSTR *response);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *SetReturnValue )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR returnValue);\r
+        \r
+        /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *DisableLocalSecurity )( \r
+            IShockwaveFlash * This);\r
+        \r
+        /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AllowNetworking )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ BSTR *pVal);\r
+        \r
+        /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_AllowNetworking )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR pVal);\r
+        \r
+        /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AllowFullScreen )( \r
+            IShockwaveFlash * This,\r
+            /* [retval][out] */ BSTR *pVal);\r
+        \r
+        /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_AllowFullScreen )( \r
+            IShockwaveFlash * This,\r
+            /* [in] */ BSTR pVal);\r
+        \r
+        END_INTERFACE\r
+    } IShockwaveFlashVtbl;\r
+\r
+    interface IShockwaveFlash\r
+    {\r
+        CONST_VTBL struct IShockwaveFlashVtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IShockwaveFlash_QueryInterface(This,riid,ppvObject)    \\r
+    (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)\r
+\r
+#define IShockwaveFlash_AddRef(This)   \\r
+    (This)->lpVtbl -> AddRef(This)\r
+\r
+#define IShockwaveFlash_Release(This)  \\r
+    (This)->lpVtbl -> Release(This)\r
+\r
+\r
+#define IShockwaveFlash_GetTypeInfoCount(This,pctinfo) \\r
+    (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)\r
+\r
+#define IShockwaveFlash_GetTypeInfo(This,iTInfo,lcid,ppTInfo)  \\r
+    (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)\r
+\r
+#define IShockwaveFlash_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)        \\r
+    (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)\r
+\r
+#define IShockwaveFlash_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)  \\r
+    (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)\r
+\r
+\r
+#define IShockwaveFlash_get_ReadyState(This,pVal)      \\r
+    (This)->lpVtbl -> get_ReadyState(This,pVal)\r
+\r
+#define IShockwaveFlash_get_TotalFrames(This,pVal)     \\r
+    (This)->lpVtbl -> get_TotalFrames(This,pVal)\r
+\r
+#define IShockwaveFlash_get_Playing(This,pVal) \\r
+    (This)->lpVtbl -> get_Playing(This,pVal)\r
+\r
+#define IShockwaveFlash_put_Playing(This,pVal) \\r
+    (This)->lpVtbl -> put_Playing(This,pVal)\r
+\r
+#define IShockwaveFlash_get_Quality(This,pVal) \\r
+    (This)->lpVtbl -> get_Quality(This,pVal)\r
+\r
+#define IShockwaveFlash_put_Quality(This,pVal) \\r
+    (This)->lpVtbl -> put_Quality(This,pVal)\r
+\r
+#define IShockwaveFlash_get_ScaleMode(This,pVal)       \\r
+    (This)->lpVtbl -> get_ScaleMode(This,pVal)\r
+\r
+#define IShockwaveFlash_put_ScaleMode(This,pVal)       \\r
+    (This)->lpVtbl -> put_ScaleMode(This,pVal)\r
+\r
+#define IShockwaveFlash_get_AlignMode(This,pVal)       \\r
+    (This)->lpVtbl -> get_AlignMode(This,pVal)\r
+\r
+#define IShockwaveFlash_put_AlignMode(This,pVal)       \\r
+    (This)->lpVtbl -> put_AlignMode(This,pVal)\r
+\r
+#define IShockwaveFlash_get_BackgroundColor(This,pVal) \\r
+    (This)->lpVtbl -> get_BackgroundColor(This,pVal)\r
+\r
+#define IShockwaveFlash_put_BackgroundColor(This,pVal) \\r
+    (This)->lpVtbl -> put_BackgroundColor(This,pVal)\r
+\r
+#define IShockwaveFlash_get_Loop(This,pVal)    \\r
+    (This)->lpVtbl -> get_Loop(This,pVal)\r
+\r
+#define IShockwaveFlash_put_Loop(This,pVal)    \\r
+    (This)->lpVtbl -> put_Loop(This,pVal)\r
+\r
+#define IShockwaveFlash_get_Movie(This,pVal)   \\r
+    (This)->lpVtbl -> get_Movie(This,pVal)\r
+\r
+#define IShockwaveFlash_put_Movie(This,pVal)   \\r
+    (This)->lpVtbl -> put_Movie(This,pVal)\r
+\r
+#define IShockwaveFlash_get_FrameNum(This,pVal)        \\r
+    (This)->lpVtbl -> get_FrameNum(This,pVal)\r
+\r
+#define IShockwaveFlash_put_FrameNum(This,pVal)        \\r
+    (This)->lpVtbl -> put_FrameNum(This,pVal)\r
+\r
+#define IShockwaveFlash_SetZoomRect(This,left,top,right,bottom)        \\r
+    (This)->lpVtbl -> SetZoomRect(This,left,top,right,bottom)\r
+\r
+#define IShockwaveFlash_Zoom(This,factor)      \\r
+    (This)->lpVtbl -> Zoom(This,factor)\r
+\r
+#define IShockwaveFlash_Pan(This,x,y,mode)     \\r
+    (This)->lpVtbl -> Pan(This,x,y,mode)\r
+\r
+#define IShockwaveFlash_Play(This)     \\r
+    (This)->lpVtbl -> Play(This)\r
+\r
+#define IShockwaveFlash_Stop(This)     \\r
+    (This)->lpVtbl -> Stop(This)\r
+\r
+#define IShockwaveFlash_Back(This)     \\r
+    (This)->lpVtbl -> Back(This)\r
+\r
+#define IShockwaveFlash_Forward(This)  \\r
+    (This)->lpVtbl -> Forward(This)\r
+\r
+#define IShockwaveFlash_Rewind(This)   \\r
+    (This)->lpVtbl -> Rewind(This)\r
+\r
+#define IShockwaveFlash_StopPlay(This) \\r
+    (This)->lpVtbl -> StopPlay(This)\r
+\r
+#define IShockwaveFlash_GotoFrame(This,FrameNum)       \\r
+    (This)->lpVtbl -> GotoFrame(This,FrameNum)\r
+\r
+#define IShockwaveFlash_CurrentFrame(This,FrameNum)    \\r
+    (This)->lpVtbl -> CurrentFrame(This,FrameNum)\r
+\r
+#define IShockwaveFlash_IsPlaying(This,Playing)        \\r
+    (This)->lpVtbl -> IsPlaying(This,Playing)\r
+\r
+#define IShockwaveFlash_PercentLoaded(This,percent)    \\r
+    (This)->lpVtbl -> PercentLoaded(This,percent)\r
+\r
+#define IShockwaveFlash_FrameLoaded(This,FrameNum,loaded)      \\r
+    (This)->lpVtbl -> FrameLoaded(This,FrameNum,loaded)\r
+\r
+#define IShockwaveFlash_FlashVersion(This,version)     \\r
+    (This)->lpVtbl -> FlashVersion(This,version)\r
+\r
+#define IShockwaveFlash_get_WMode(This,pVal)   \\r
+    (This)->lpVtbl -> get_WMode(This,pVal)\r
+\r
+#define IShockwaveFlash_put_WMode(This,pVal)   \\r
+    (This)->lpVtbl -> put_WMode(This,pVal)\r
+\r
+#define IShockwaveFlash_get_SAlign(This,pVal)  \\r
+    (This)->lpVtbl -> get_SAlign(This,pVal)\r
+\r
+#define IShockwaveFlash_put_SAlign(This,pVal)  \\r
+    (This)->lpVtbl -> put_SAlign(This,pVal)\r
+\r
+#define IShockwaveFlash_get_Menu(This,pVal)    \\r
+    (This)->lpVtbl -> get_Menu(This,pVal)\r
+\r
+#define IShockwaveFlash_put_Menu(This,pVal)    \\r
+    (This)->lpVtbl -> put_Menu(This,pVal)\r
+\r
+#define IShockwaveFlash_get_Base(This,pVal)    \\r
+    (This)->lpVtbl -> get_Base(This,pVal)\r
+\r
+#define IShockwaveFlash_put_Base(This,pVal)    \\r
+    (This)->lpVtbl -> put_Base(This,pVal)\r
+\r
+#define IShockwaveFlash_get_Scale(This,pVal)   \\r
+    (This)->lpVtbl -> get_Scale(This,pVal)\r
+\r
+#define IShockwaveFlash_put_Scale(This,pVal)   \\r
+    (This)->lpVtbl -> put_Scale(This,pVal)\r
+\r
+#define IShockwaveFlash_get_DeviceFont(This,pVal)      \\r
+    (This)->lpVtbl -> get_DeviceFont(This,pVal)\r
+\r
+#define IShockwaveFlash_put_DeviceFont(This,pVal)      \\r
+    (This)->lpVtbl -> put_DeviceFont(This,pVal)\r
+\r
+#define IShockwaveFlash_get_EmbedMovie(This,pVal)      \\r
+    (This)->lpVtbl -> get_EmbedMovie(This,pVal)\r
+\r
+#define IShockwaveFlash_put_EmbedMovie(This,pVal)      \\r
+    (This)->lpVtbl -> put_EmbedMovie(This,pVal)\r
+\r
+#define IShockwaveFlash_get_BGColor(This,pVal) \\r
+    (This)->lpVtbl -> get_BGColor(This,pVal)\r
+\r
+#define IShockwaveFlash_put_BGColor(This,pVal) \\r
+    (This)->lpVtbl -> put_BGColor(This,pVal)\r
+\r
+#define IShockwaveFlash_get_Quality2(This,pVal)        \\r
+    (This)->lpVtbl -> get_Quality2(This,pVal)\r
+\r
+#define IShockwaveFlash_put_Quality2(This,pVal)        \\r
+    (This)->lpVtbl -> put_Quality2(This,pVal)\r
+\r
+#define IShockwaveFlash_LoadMovie(This,layer,url)      \\r
+    (This)->lpVtbl -> LoadMovie(This,layer,url)\r
+\r
+#define IShockwaveFlash_TGotoFrame(This,target,FrameNum)       \\r
+    (This)->lpVtbl -> TGotoFrame(This,target,FrameNum)\r
+\r
+#define IShockwaveFlash_TGotoLabel(This,target,label)  \\r
+    (This)->lpVtbl -> TGotoLabel(This,target,label)\r
+\r
+#define IShockwaveFlash_TCurrentFrame(This,target,FrameNum)    \\r
+    (This)->lpVtbl -> TCurrentFrame(This,target,FrameNum)\r
+\r
+#define IShockwaveFlash_TCurrentLabel(This,target,pVal)        \\r
+    (This)->lpVtbl -> TCurrentLabel(This,target,pVal)\r
+\r
+#define IShockwaveFlash_TPlay(This,target)     \\r
+    (This)->lpVtbl -> TPlay(This,target)\r
+\r
+#define IShockwaveFlash_TStopPlay(This,target) \\r
+    (This)->lpVtbl -> TStopPlay(This,target)\r
+\r
+#define IShockwaveFlash_SetVariable(This,name,value)   \\r
+    (This)->lpVtbl -> SetVariable(This,name,value)\r
+\r
+#define IShockwaveFlash_GetVariable(This,name,pVal)    \\r
+    (This)->lpVtbl -> GetVariable(This,name,pVal)\r
+\r
+#define IShockwaveFlash_TSetProperty(This,target,property,value)       \\r
+    (This)->lpVtbl -> TSetProperty(This,target,property,value)\r
+\r
+#define IShockwaveFlash_TGetProperty(This,target,property,pVal)        \\r
+    (This)->lpVtbl -> TGetProperty(This,target,property,pVal)\r
+\r
+#define IShockwaveFlash_TCallFrame(This,target,FrameNum)       \\r
+    (This)->lpVtbl -> TCallFrame(This,target,FrameNum)\r
+\r
+#define IShockwaveFlash_TCallLabel(This,target,label)  \\r
+    (This)->lpVtbl -> TCallLabel(This,target,label)\r
+\r
+#define IShockwaveFlash_TSetPropertyNum(This,target,property,value)    \\r
+    (This)->lpVtbl -> TSetPropertyNum(This,target,property,value)\r
+\r
+#define IShockwaveFlash_TGetPropertyNum(This,target,property,pVal)     \\r
+    (This)->lpVtbl -> TGetPropertyNum(This,target,property,pVal)\r
+\r
+#define IShockwaveFlash_TGetPropertyAsNumber(This,target,property,pVal)        \\r
+    (This)->lpVtbl -> TGetPropertyAsNumber(This,target,property,pVal)\r
+\r
+#define IShockwaveFlash_get_SWRemote(This,pVal)        \\r
+    (This)->lpVtbl -> get_SWRemote(This,pVal)\r
+\r
+#define IShockwaveFlash_put_SWRemote(This,pVal)        \\r
+    (This)->lpVtbl -> put_SWRemote(This,pVal)\r
+\r
+#define IShockwaveFlash_get_FlashVars(This,pVal)       \\r
+    (This)->lpVtbl -> get_FlashVars(This,pVal)\r
+\r
+#define IShockwaveFlash_put_FlashVars(This,pVal)       \\r
+    (This)->lpVtbl -> put_FlashVars(This,pVal)\r
+\r
+#define IShockwaveFlash_get_AllowScriptAccess(This,pVal)       \\r
+    (This)->lpVtbl -> get_AllowScriptAccess(This,pVal)\r
+\r
+#define IShockwaveFlash_put_AllowScriptAccess(This,pVal)       \\r
+    (This)->lpVtbl -> put_AllowScriptAccess(This,pVal)\r
+\r
+#define IShockwaveFlash_get_MovieData(This,pVal)       \\r
+    (This)->lpVtbl -> get_MovieData(This,pVal)\r
+\r
+#define IShockwaveFlash_put_MovieData(This,pVal)       \\r
+    (This)->lpVtbl -> put_MovieData(This,pVal)\r
+\r
+#define IShockwaveFlash_get_InlineData(This,ppIUnknown)        \\r
+    (This)->lpVtbl -> get_InlineData(This,ppIUnknown)\r
+\r
+#define IShockwaveFlash_put_InlineData(This,ppIUnknown)        \\r
+    (This)->lpVtbl -> put_InlineData(This,ppIUnknown)\r
+\r
+#define IShockwaveFlash_get_SeamlessTabbing(This,pVal) \\r
+    (This)->lpVtbl -> get_SeamlessTabbing(This,pVal)\r
+\r
+#define IShockwaveFlash_put_SeamlessTabbing(This,pVal) \\r
+    (This)->lpVtbl -> put_SeamlessTabbing(This,pVal)\r
+\r
+#define IShockwaveFlash_EnforceLocalSecurity(This)     \\r
+    (This)->lpVtbl -> EnforceLocalSecurity(This)\r
+\r
+#define IShockwaveFlash_get_Profile(This,pVal) \\r
+    (This)->lpVtbl -> get_Profile(This,pVal)\r
+\r
+#define IShockwaveFlash_put_Profile(This,pVal) \\r
+    (This)->lpVtbl -> put_Profile(This,pVal)\r
+\r
+#define IShockwaveFlash_get_ProfileAddress(This,pVal)  \\r
+    (This)->lpVtbl -> get_ProfileAddress(This,pVal)\r
+\r
+#define IShockwaveFlash_put_ProfileAddress(This,pVal)  \\r
+    (This)->lpVtbl -> put_ProfileAddress(This,pVal)\r
+\r
+#define IShockwaveFlash_get_ProfilePort(This,pVal)     \\r
+    (This)->lpVtbl -> get_ProfilePort(This,pVal)\r
+\r
+#define IShockwaveFlash_put_ProfilePort(This,pVal)     \\r
+    (This)->lpVtbl -> put_ProfilePort(This,pVal)\r
+\r
+#define IShockwaveFlash_CallFunction(This,request,response)    \\r
+    (This)->lpVtbl -> CallFunction(This,request,response)\r
+\r
+#define IShockwaveFlash_SetReturnValue(This,returnValue)       \\r
+    (This)->lpVtbl -> SetReturnValue(This,returnValue)\r
+\r
+#define IShockwaveFlash_DisableLocalSecurity(This)     \\r
+    (This)->lpVtbl -> DisableLocalSecurity(This)\r
+\r
+#define IShockwaveFlash_get_AllowNetworking(This,pVal) \\r
+    (This)->lpVtbl -> get_AllowNetworking(This,pVal)\r
+\r
+#define IShockwaveFlash_put_AllowNetworking(This,pVal) \\r
+    (This)->lpVtbl -> put_AllowNetworking(This,pVal)\r
+\r
+#define IShockwaveFlash_get_AllowFullScreen(This,pVal) \\r
+    (This)->lpVtbl -> get_AllowFullScreen(This,pVal)\r
+\r
+#define IShockwaveFlash_put_AllowFullScreen(This,pVal) \\r
+    (This)->lpVtbl -> put_AllowFullScreen(This,pVal)\r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_ReadyState_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ long *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_get_ReadyState_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_TotalFrames_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ long *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_get_TotalFrames_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_Playing_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ VARIANT_BOOL *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_get_Playing_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_Playing_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ VARIANT_BOOL pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_put_Playing_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_Quality_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ int *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_get_Quality_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_Quality_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ int pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_put_Quality_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_ScaleMode_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ int *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_get_ScaleMode_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_ScaleMode_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ int pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_put_ScaleMode_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_AlignMode_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ int *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_get_AlignMode_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_AlignMode_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ int pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_put_AlignMode_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_BackgroundColor_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ long *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_get_BackgroundColor_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_BackgroundColor_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ long pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_put_BackgroundColor_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_Loop_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ VARIANT_BOOL *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_get_Loop_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_Loop_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ VARIANT_BOOL pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_put_Loop_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_Movie_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ BSTR *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_get_Movie_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_Movie_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_put_Movie_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_FrameNum_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ long *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_get_FrameNum_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_FrameNum_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ long pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_put_FrameNum_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_SetZoomRect_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ long left,\r
+    /* [in] */ long top,\r
+    /* [in] */ long right,\r
+    /* [in] */ long bottom);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_SetZoomRect_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_Zoom_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ int factor);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_Zoom_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_Pan_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ long x,\r
+    /* [in] */ long y,\r
+    /* [in] */ int mode);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_Pan_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_Play_Proxy( \r
+    IShockwaveFlash * This);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_Play_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_Stop_Proxy( \r
+    IShockwaveFlash * This);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_Stop_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_Back_Proxy( \r
+    IShockwaveFlash * This);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_Back_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_Forward_Proxy( \r
+    IShockwaveFlash * This);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_Forward_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_Rewind_Proxy( \r
+    IShockwaveFlash * This);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_Rewind_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_StopPlay_Proxy( \r
+    IShockwaveFlash * This);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_StopPlay_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_GotoFrame_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ long FrameNum);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_GotoFrame_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_CurrentFrame_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ long *FrameNum);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_CurrentFrame_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_IsPlaying_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ VARIANT_BOOL *Playing);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_IsPlaying_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_PercentLoaded_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ long *percent);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_PercentLoaded_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_FrameLoaded_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ long FrameNum,\r
+    /* [retval][out] */ VARIANT_BOOL *loaded);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_FrameLoaded_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_FlashVersion_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ long *version);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_FlashVersion_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_WMode_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ BSTR *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_get_WMode_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_WMode_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_put_WMode_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_SAlign_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ BSTR *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_get_SAlign_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_SAlign_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_put_SAlign_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_Menu_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ VARIANT_BOOL *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_get_Menu_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_Menu_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ VARIANT_BOOL pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_put_Menu_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_Base_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ BSTR *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_get_Base_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_Base_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_put_Base_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_Scale_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ BSTR *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_get_Scale_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_Scale_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_put_Scale_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_DeviceFont_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ VARIANT_BOOL *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_get_DeviceFont_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_DeviceFont_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ VARIANT_BOOL pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_put_DeviceFont_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_EmbedMovie_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ VARIANT_BOOL *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_get_EmbedMovie_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_EmbedMovie_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ VARIANT_BOOL pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_put_EmbedMovie_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_BGColor_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ BSTR *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_get_BGColor_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_BGColor_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_put_BGColor_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_Quality2_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ BSTR *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_get_Quality2_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_Quality2_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_put_Quality2_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_LoadMovie_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ int layer,\r
+    /* [in] */ BSTR url);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_LoadMovie_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_TGotoFrame_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR target,\r
+    /* [in] */ long FrameNum);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_TGotoFrame_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_TGotoLabel_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR target,\r
+    /* [in] */ BSTR label);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_TGotoLabel_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_TCurrentFrame_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR target,\r
+    /* [retval][out] */ long *FrameNum);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_TCurrentFrame_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_TCurrentLabel_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR target,\r
+    /* [retval][out] */ BSTR *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_TCurrentLabel_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_TPlay_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR target);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_TPlay_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_TStopPlay_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR target);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_TStopPlay_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_SetVariable_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR name,\r
+    /* [in] */ BSTR value);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_SetVariable_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_GetVariable_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR name,\r
+    /* [retval][out] */ BSTR *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_GetVariable_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_TSetProperty_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR target,\r
+    /* [in] */ int property,\r
+    /* [in] */ BSTR value);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_TSetProperty_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_TGetProperty_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR target,\r
+    /* [in] */ int property,\r
+    /* [retval][out] */ BSTR *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_TGetProperty_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_TCallFrame_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR target,\r
+    /* [in] */ int FrameNum);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_TCallFrame_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_TCallLabel_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR target,\r
+    /* [in] */ BSTR label);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_TCallLabel_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_TSetPropertyNum_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR target,\r
+    /* [in] */ int property,\r
+    /* [in] */ double value);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_TSetPropertyNum_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_TGetPropertyNum_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR target,\r
+    /* [in] */ int property,\r
+    /* [retval][out] */ double *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_TGetPropertyNum_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_TGetPropertyAsNumber_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR target,\r
+    /* [in] */ int property,\r
+    /* [retval][out] */ double *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_TGetPropertyAsNumber_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_SWRemote_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ BSTR *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_get_SWRemote_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_SWRemote_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_put_SWRemote_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_FlashVars_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ BSTR *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_get_FlashVars_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_FlashVars_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_put_FlashVars_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_AllowScriptAccess_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ BSTR *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_get_AllowScriptAccess_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_AllowScriptAccess_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_put_AllowScriptAccess_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_MovieData_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ BSTR *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_get_MovieData_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_MovieData_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_put_MovieData_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_InlineData_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ IUnknown **ppIUnknown);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_get_InlineData_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_InlineData_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ IUnknown *ppIUnknown);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_put_InlineData_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_SeamlessTabbing_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ VARIANT_BOOL *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_get_SeamlessTabbing_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_SeamlessTabbing_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ VARIANT_BOOL pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_put_SeamlessTabbing_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_EnforceLocalSecurity_Proxy( \r
+    IShockwaveFlash * This);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_EnforceLocalSecurity_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_Profile_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ VARIANT_BOOL *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_get_Profile_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_Profile_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ VARIANT_BOOL pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_put_Profile_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_ProfileAddress_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ BSTR *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_get_ProfileAddress_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_ProfileAddress_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_put_ProfileAddress_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_ProfilePort_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ long *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_get_ProfilePort_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_ProfilePort_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ long pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_put_ProfilePort_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_CallFunction_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR request,\r
+    /* [retval][out] */ BSTR *response);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_CallFunction_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_SetReturnValue_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR returnValue);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_SetReturnValue_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_DisableLocalSecurity_Proxy( \r
+    IShockwaveFlash * This);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_DisableLocalSecurity_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_AllowNetworking_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ BSTR *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_get_AllowNetworking_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_AllowNetworking_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_put_AllowNetworking_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_AllowFullScreen_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [retval][out] */ BSTR *pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_get_AllowFullScreen_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_AllowFullScreen_Proxy( \r
+    IShockwaveFlash * This,\r
+    /* [in] */ BSTR pVal);\r
+\r
+\r
+void __RPC_STUB IShockwaveFlash_put_AllowFullScreen_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+\r
+#endif         /* __IShockwaveFlash_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef ___IShockwaveFlashEvents_DISPINTERFACE_DEFINED__\r
+#define ___IShockwaveFlashEvents_DISPINTERFACE_DEFINED__\r
+\r
+/* dispinterface _IShockwaveFlashEvents */\r
+/* [hidden][helpstring][uuid] */ \r
+\r
+\r
+EXTERN_C const IID DIID__IShockwaveFlashEvents;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+\r
+    MIDL_INTERFACE("D27CDB6D-AE6D-11CF-96B8-444553540000")\r
+    _IShockwaveFlashEvents : public IDispatch\r
+    {\r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct _IShockwaveFlashEventsVtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            _IShockwaveFlashEvents * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            _IShockwaveFlashEvents * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            _IShockwaveFlashEvents * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( \r
+            _IShockwaveFlashEvents * This,\r
+            /* [out] */ UINT *pctinfo);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( \r
+            _IShockwaveFlashEvents * This,\r
+            /* [in] */ UINT iTInfo,\r
+            /* [in] */ LCID lcid,\r
+            /* [out] */ ITypeInfo **ppTInfo);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( \r
+            _IShockwaveFlashEvents * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [size_is][in] */ LPOLESTR *rgszNames,\r
+            /* [in] */ UINT cNames,\r
+            /* [in] */ LCID lcid,\r
+            /* [size_is][out] */ DISPID *rgDispId);\r
+        \r
+        /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( \r
+            _IShockwaveFlashEvents * This,\r
+            /* [in] */ DISPID dispIdMember,\r
+            /* [in] */ REFIID riid,\r
+            /* [in] */ LCID lcid,\r
+            /* [in] */ WORD wFlags,\r
+            /* [out][in] */ DISPPARAMS *pDispParams,\r
+            /* [out] */ VARIANT *pVarResult,\r
+            /* [out] */ EXCEPINFO *pExcepInfo,\r
+            /* [out] */ UINT *puArgErr);\r
+        \r
+        END_INTERFACE\r
+    } _IShockwaveFlashEventsVtbl;\r
+\r
+    interface _IShockwaveFlashEvents\r
+    {\r
+        CONST_VTBL struct _IShockwaveFlashEventsVtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define _IShockwaveFlashEvents_QueryInterface(This,riid,ppvObject)     \\r
+    (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)\r
+\r
+#define _IShockwaveFlashEvents_AddRef(This)    \\r
+    (This)->lpVtbl -> AddRef(This)\r
+\r
+#define _IShockwaveFlashEvents_Release(This)   \\r
+    (This)->lpVtbl -> Release(This)\r
+\r
+\r
+#define _IShockwaveFlashEvents_GetTypeInfoCount(This,pctinfo)  \\r
+    (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)\r
+\r
+#define _IShockwaveFlashEvents_GetTypeInfo(This,iTInfo,lcid,ppTInfo)   \\r
+    (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)\r
+\r
+#define _IShockwaveFlashEvents_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \\r
+    (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)\r
+\r
+#define _IShockwaveFlashEvents_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)   \\r
+    (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)\r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+#endif         /* ___IShockwaveFlashEvents_DISPINTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IFlashFactory_INTERFACE_DEFINED__\r
+#define __IFlashFactory_INTERFACE_DEFINED__\r
+\r
+/* interface IFlashFactory */\r
+/* [object][helpstring][uuid] */ \r
+\r
+\r
+EXTERN_C const IID IID_IFlashFactory;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("D27CDB70-AE6D-11CF-96B8-444553540000")\r
+    IFlashFactory : public IUnknown\r
+    {\r
+    public:\r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IFlashFactoryVtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IFlashFactory * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IFlashFactory * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IFlashFactory * This);\r
+        \r
+        END_INTERFACE\r
+    } IFlashFactoryVtbl;\r
+\r
+    interface IFlashFactory\r
+    {\r
+        CONST_VTBL struct IFlashFactoryVtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IFlashFactory_QueryInterface(This,riid,ppvObject)      \\r
+    (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)\r
+\r
+#define IFlashFactory_AddRef(This)     \\r
+    (This)->lpVtbl -> AddRef(This)\r
+\r
+#define IFlashFactory_Release(This)    \\r
+    (This)->lpVtbl -> Release(This)\r
+\r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IFlashFactory_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IFlashObjectInterface_INTERFACE_DEFINED__\r
+#define __IFlashObjectInterface_INTERFACE_DEFINED__\r
+\r
+/* interface IFlashObjectInterface */\r
+/* [object][helpstring][uuid] */ \r
+\r
+\r
+EXTERN_C const IID IID_IFlashObjectInterface;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("D27CDB72-AE6D-11CF-96B8-444553540000")\r
+    IFlashObjectInterface : public IDispatchEx\r
+    {\r
+    public:\r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IFlashObjectInterfaceVtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IFlashObjectInterface * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IFlashObjectInterface * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IFlashObjectInterface * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( \r
+            IFlashObjectInterface * This,\r
+            /* [out] */ UINT *pctinfo);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( \r
+            IFlashObjectInterface * This,\r
+            /* [in] */ UINT iTInfo,\r
+            /* [in] */ LCID lcid,\r
+            /* [out] */ ITypeInfo **ppTInfo);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( \r
+            IFlashObjectInterface * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [size_is][in] */ LPOLESTR *rgszNames,\r
+            /* [in] */ UINT cNames,\r
+            /* [in] */ LCID lcid,\r
+            /* [size_is][out] */ DISPID *rgDispId);\r
+        \r
+        /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( \r
+            IFlashObjectInterface * This,\r
+            /* [in] */ DISPID dispIdMember,\r
+            /* [in] */ REFIID riid,\r
+            /* [in] */ LCID lcid,\r
+            /* [in] */ WORD wFlags,\r
+            /* [out][in] */ DISPPARAMS *pDispParams,\r
+            /* [out] */ VARIANT *pVarResult,\r
+            /* [out] */ EXCEPINFO *pExcepInfo,\r
+            /* [out] */ UINT *puArgErr);\r
+        \r
+        HRESULT ( __stdcall *GetDispID )( \r
+            IFlashObjectInterface * This,\r
+            /* [in] */ BSTR bstrName,\r
+            /* [in] */ unsigned long grfdex,\r
+            /* [out] */ long *pid);\r
+        \r
+        HRESULT ( __stdcall *RemoteInvokeEx )( \r
+            IFlashObjectInterface * This,\r
+            /* [in] */ long id,\r
+            /* [in] */ unsigned long lcid,\r
+            /* [in] */ unsigned long dwFlags,\r
+            /* [in] */ DISPPARAMS *pdp,\r
+            /* [out] */ VARIANT *pvarRes,\r
+            /* [out] */ EXCEPINFO *pei,\r
+            /* [in] */ IServiceProvider *pspCaller,\r
+            /* [in] */ unsigned int cvarRefArg,\r
+            /* [in] */ unsigned int *rgiRefArg,\r
+            /* [out][in] */ VARIANT *rgvarRefArg);\r
+        \r
+        HRESULT ( __stdcall *DeleteMemberByName )( \r
+            IFlashObjectInterface * This,\r
+            /* [in] */ BSTR bstrName,\r
+            /* [in] */ unsigned long grfdex);\r
+        \r
+        HRESULT ( __stdcall *DeleteMemberByDispID )( \r
+            IFlashObjectInterface * This,\r
+            /* [in] */ long id);\r
+        \r
+        HRESULT ( __stdcall *GetMemberProperties )( \r
+            IFlashObjectInterface * This,\r
+            /* [in] */ long id,\r
+            /* [in] */ unsigned long grfdexFetch,\r
+            /* [out] */ unsigned long *pgrfdex);\r
+        \r
+        HRESULT ( __stdcall *GetMemberName )( \r
+            IFlashObjectInterface * This,\r
+            /* [in] */ long id,\r
+            /* [out] */ BSTR *pbstrName);\r
+        \r
+        HRESULT ( __stdcall *GetNextDispID )( \r
+            IFlashObjectInterface * This,\r
+            /* [in] */ unsigned long grfdex,\r
+            /* [in] */ long id,\r
+            /* [out] */ long *pid);\r
+        \r
+        HRESULT ( __stdcall *GetNameSpaceParent )( \r
+            IFlashObjectInterface * This,\r
+            /* [out] */ IUnknown **ppunk);\r
+        \r
+        END_INTERFACE\r
+    } IFlashObjectInterfaceVtbl;\r
+\r
+    interface IFlashObjectInterface\r
+    {\r
+        CONST_VTBL struct IFlashObjectInterfaceVtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IFlashObjectInterface_QueryInterface(This,riid,ppvObject)      \\r
+    (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)\r
+\r
+#define IFlashObjectInterface_AddRef(This)     \\r
+    (This)->lpVtbl -> AddRef(This)\r
+\r
+#define IFlashObjectInterface_Release(This)    \\r
+    (This)->lpVtbl -> Release(This)\r
+\r
+\r
+#define IFlashObjectInterface_GetTypeInfoCount(This,pctinfo)   \\r
+    (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)\r
+\r
+#define IFlashObjectInterface_GetTypeInfo(This,iTInfo,lcid,ppTInfo)    \\r
+    (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)\r
+\r
+#define IFlashObjectInterface_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)  \\r
+    (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)\r
+\r
+#define IFlashObjectInterface_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)    \\r
+    (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)\r
+\r
+\r
+#define IFlashObjectInterface_GetDispID(This,bstrName,grfdex,pid)      \\r
+    (This)->lpVtbl -> GetDispID(This,bstrName,grfdex,pid)\r
+\r
+#define IFlashObjectInterface_RemoteInvokeEx(This,id,lcid,dwFlags,pdp,pvarRes,pei,pspCaller,cvarRefArg,rgiRefArg,rgvarRefArg)  \\r
+    (This)->lpVtbl -> RemoteInvokeEx(This,id,lcid,dwFlags,pdp,pvarRes,pei,pspCaller,cvarRefArg,rgiRefArg,rgvarRefArg)\r
+\r
+#define IFlashObjectInterface_DeleteMemberByName(This,bstrName,grfdex) \\r
+    (This)->lpVtbl -> DeleteMemberByName(This,bstrName,grfdex)\r
+\r
+#define IFlashObjectInterface_DeleteMemberByDispID(This,id)    \\r
+    (This)->lpVtbl -> DeleteMemberByDispID(This,id)\r
+\r
+#define IFlashObjectInterface_GetMemberProperties(This,id,grfdexFetch,pgrfdex) \\r
+    (This)->lpVtbl -> GetMemberProperties(This,id,grfdexFetch,pgrfdex)\r
+\r
+#define IFlashObjectInterface_GetMemberName(This,id,pbstrName) \\r
+    (This)->lpVtbl -> GetMemberName(This,id,pbstrName)\r
+\r
+#define IFlashObjectInterface_GetNextDispID(This,grfdex,id,pid)        \\r
+    (This)->lpVtbl -> GetNextDispID(This,grfdex,id,pid)\r
+\r
+#define IFlashObjectInterface_GetNameSpaceParent(This,ppunk)   \\r
+    (This)->lpVtbl -> GetNameSpaceParent(This,ppunk)\r
+\r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif         /* __IFlashObjectInterface_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IDispatchEx_INTERFACE_DEFINED__\r
+#define __IDispatchEx_INTERFACE_DEFINED__\r
+\r
+/* interface IDispatchEx */\r
+/* [object][uuid] */ \r
+\r
+\r
+EXTERN_C const IID IID_IDispatchEx;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("A6EF9860-C720-11D0-9337-00A0C90DCAA9")\r
+    IDispatchEx : public IDispatch\r
+    {\r
+    public:\r
+        virtual HRESULT __stdcall GetDispID( \r
+            /* [in] */ BSTR bstrName,\r
+            /* [in] */ unsigned long grfdex,\r
+            /* [out] */ long *pid) = 0;\r
+        \r
+        virtual HRESULT __stdcall RemoteInvokeEx( \r
+            /* [in] */ long id,\r
+            /* [in] */ unsigned long lcid,\r
+            /* [in] */ unsigned long dwFlags,\r
+            /* [in] */ DISPPARAMS *pdp,\r
+            /* [out] */ VARIANT *pvarRes,\r
+            /* [out] */ EXCEPINFO *pei,\r
+            /* [in] */ IServiceProvider *pspCaller,\r
+            /* [in] */ unsigned int cvarRefArg,\r
+            /* [in] */ unsigned int *rgiRefArg,\r
+            /* [out][in] */ VARIANT *rgvarRefArg) = 0;\r
+        \r
+        virtual HRESULT __stdcall DeleteMemberByName( \r
+            /* [in] */ BSTR bstrName,\r
+            /* [in] */ unsigned long grfdex) = 0;\r
+        \r
+        virtual HRESULT __stdcall DeleteMemberByDispID( \r
+            /* [in] */ long id) = 0;\r
+        \r
+        virtual HRESULT __stdcall GetMemberProperties( \r
+            /* [in] */ long id,\r
+            /* [in] */ unsigned long grfdexFetch,\r
+            /* [out] */ unsigned long *pgrfdex) = 0;\r
+        \r
+        virtual HRESULT __stdcall GetMemberName( \r
+            /* [in] */ long id,\r
+            /* [out] */ BSTR *pbstrName) = 0;\r
+        \r
+        virtual HRESULT __stdcall GetNextDispID( \r
+            /* [in] */ unsigned long grfdex,\r
+            /* [in] */ long id,\r
+            /* [out] */ long *pid) = 0;\r
+        \r
+        virtual HRESULT __stdcall GetNameSpaceParent( \r
+            /* [out] */ IUnknown **ppunk) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IDispatchExVtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IDispatchEx * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IDispatchEx * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IDispatchEx * This);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( \r
+            IDispatchEx * This,\r
+            /* [out] */ UINT *pctinfo);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( \r
+            IDispatchEx * This,\r
+            /* [in] */ UINT iTInfo,\r
+            /* [in] */ LCID lcid,\r
+            /* [out] */ ITypeInfo **ppTInfo);\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( \r
+            IDispatchEx * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [size_is][in] */ LPOLESTR *rgszNames,\r
+            /* [in] */ UINT cNames,\r
+            /* [in] */ LCID lcid,\r
+            /* [size_is][out] */ DISPID *rgDispId);\r
+        \r
+        /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( \r
+            IDispatchEx * This,\r
+            /* [in] */ DISPID dispIdMember,\r
+            /* [in] */ REFIID riid,\r
+            /* [in] */ LCID lcid,\r
+            /* [in] */ WORD wFlags,\r
+            /* [out][in] */ DISPPARAMS *pDispParams,\r
+            /* [out] */ VARIANT *pVarResult,\r
+            /* [out] */ EXCEPINFO *pExcepInfo,\r
+            /* [out] */ UINT *puArgErr);\r
+        \r
+        HRESULT ( __stdcall *GetDispID )( \r
+            IDispatchEx * This,\r
+            /* [in] */ BSTR bstrName,\r
+            /* [in] */ unsigned long grfdex,\r
+            /* [out] */ long *pid);\r
+        \r
+        HRESULT ( __stdcall *RemoteInvokeEx )( \r
+            IDispatchEx * This,\r
+            /* [in] */ long id,\r
+            /* [in] */ unsigned long lcid,\r
+            /* [in] */ unsigned long dwFlags,\r
+            /* [in] */ DISPPARAMS *pdp,\r
+            /* [out] */ VARIANT *pvarRes,\r
+            /* [out] */ EXCEPINFO *pei,\r
+            /* [in] */ IServiceProvider *pspCaller,\r
+            /* [in] */ unsigned int cvarRefArg,\r
+            /* [in] */ unsigned int *rgiRefArg,\r
+            /* [out][in] */ VARIANT *rgvarRefArg);\r
+        \r
+        HRESULT ( __stdcall *DeleteMemberByName )( \r
+            IDispatchEx * This,\r
+            /* [in] */ BSTR bstrName,\r
+            /* [in] */ unsigned long grfdex);\r
+        \r
+        HRESULT ( __stdcall *DeleteMemberByDispID )( \r
+            IDispatchEx * This,\r
+            /* [in] */ long id);\r
+        \r
+        HRESULT ( __stdcall *GetMemberProperties )( \r
+            IDispatchEx * This,\r
+            /* [in] */ long id,\r
+            /* [in] */ unsigned long grfdexFetch,\r
+            /* [out] */ unsigned long *pgrfdex);\r
+        \r
+        HRESULT ( __stdcall *GetMemberName )( \r
+            IDispatchEx * This,\r
+            /* [in] */ long id,\r
+            /* [out] */ BSTR *pbstrName);\r
+        \r
+        HRESULT ( __stdcall *GetNextDispID )( \r
+            IDispatchEx * This,\r
+            /* [in] */ unsigned long grfdex,\r
+            /* [in] */ long id,\r
+            /* [out] */ long *pid);\r
+        \r
+        HRESULT ( __stdcall *GetNameSpaceParent )( \r
+            IDispatchEx * This,\r
+            /* [out] */ IUnknown **ppunk);\r
+        \r
+        END_INTERFACE\r
+    } IDispatchExVtbl;\r
+\r
+    interface IDispatchEx\r
+    {\r
+        CONST_VTBL struct IDispatchExVtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IDispatchEx_QueryInterface(This,riid,ppvObject)        \\r
+    (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)\r
+\r
+#define IDispatchEx_AddRef(This)       \\r
+    (This)->lpVtbl -> AddRef(This)\r
+\r
+#define IDispatchEx_Release(This)      \\r
+    (This)->lpVtbl -> Release(This)\r
+\r
+\r
+#define IDispatchEx_GetTypeInfoCount(This,pctinfo)     \\r
+    (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)\r
+\r
+#define IDispatchEx_GetTypeInfo(This,iTInfo,lcid,ppTInfo)      \\r
+    (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)\r
+\r
+#define IDispatchEx_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)    \\r
+    (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)\r
+\r
+#define IDispatchEx_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)      \\r
+    (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)\r
+\r
+\r
+#define IDispatchEx_GetDispID(This,bstrName,grfdex,pid)        \\r
+    (This)->lpVtbl -> GetDispID(This,bstrName,grfdex,pid)\r
+\r
+#define IDispatchEx_RemoteInvokeEx(This,id,lcid,dwFlags,pdp,pvarRes,pei,pspCaller,cvarRefArg,rgiRefArg,rgvarRefArg)    \\r
+    (This)->lpVtbl -> RemoteInvokeEx(This,id,lcid,dwFlags,pdp,pvarRes,pei,pspCaller,cvarRefArg,rgiRefArg,rgvarRefArg)\r
+\r
+#define IDispatchEx_DeleteMemberByName(This,bstrName,grfdex)   \\r
+    (This)->lpVtbl -> DeleteMemberByName(This,bstrName,grfdex)\r
+\r
+#define IDispatchEx_DeleteMemberByDispID(This,id)      \\r
+    (This)->lpVtbl -> DeleteMemberByDispID(This,id)\r
+\r
+#define IDispatchEx_GetMemberProperties(This,id,grfdexFetch,pgrfdex)   \\r
+    (This)->lpVtbl -> GetMemberProperties(This,id,grfdexFetch,pgrfdex)\r
+\r
+#define IDispatchEx_GetMemberName(This,id,pbstrName)   \\r
+    (This)->lpVtbl -> GetMemberName(This,id,pbstrName)\r
+\r
+#define IDispatchEx_GetNextDispID(This,grfdex,id,pid)  \\r
+    (This)->lpVtbl -> GetNextDispID(This,grfdex,id,pid)\r
+\r
+#define IDispatchEx_GetNameSpaceParent(This,ppunk)     \\r
+    (This)->lpVtbl -> GetNameSpaceParent(This,ppunk)\r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+HRESULT __stdcall IDispatchEx_GetDispID_Proxy( \r
+    IDispatchEx * This,\r
+    /* [in] */ BSTR bstrName,\r
+    /* [in] */ unsigned long grfdex,\r
+    /* [out] */ long *pid);\r
+\r
+\r
+void __RPC_STUB IDispatchEx_GetDispID_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+HRESULT __stdcall IDispatchEx_RemoteInvokeEx_Proxy( \r
+    IDispatchEx * This,\r
+    /* [in] */ long id,\r
+    /* [in] */ unsigned long lcid,\r
+    /* [in] */ unsigned long dwFlags,\r
+    /* [in] */ DISPPARAMS *pdp,\r
+    /* [out] */ VARIANT *pvarRes,\r
+    /* [out] */ EXCEPINFO *pei,\r
+    /* [in] */ IServiceProvider *pspCaller,\r
+    /* [in] */ unsigned int cvarRefArg,\r
+    /* [in] */ unsigned int *rgiRefArg,\r
+    /* [out][in] */ VARIANT *rgvarRefArg);\r
+\r
+\r
+void __RPC_STUB IDispatchEx_RemoteInvokeEx_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+HRESULT __stdcall IDispatchEx_DeleteMemberByName_Proxy( \r
+    IDispatchEx * This,\r
+    /* [in] */ BSTR bstrName,\r
+    /* [in] */ unsigned long grfdex);\r
+\r
+\r
+void __RPC_STUB IDispatchEx_DeleteMemberByName_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+HRESULT __stdcall IDispatchEx_DeleteMemberByDispID_Proxy( \r
+    IDispatchEx * This,\r
+    /* [in] */ long id);\r
+\r
+\r
+void __RPC_STUB IDispatchEx_DeleteMemberByDispID_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+HRESULT __stdcall IDispatchEx_GetMemberProperties_Proxy( \r
+    IDispatchEx * This,\r
+    /* [in] */ long id,\r
+    /* [in] */ unsigned long grfdexFetch,\r
+    /* [out] */ unsigned long *pgrfdex);\r
+\r
+\r
+void __RPC_STUB IDispatchEx_GetMemberProperties_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+HRESULT __stdcall IDispatchEx_GetMemberName_Proxy( \r
+    IDispatchEx * This,\r
+    /* [in] */ long id,\r
+    /* [out] */ BSTR *pbstrName);\r
+\r
+\r
+void __RPC_STUB IDispatchEx_GetMemberName_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+HRESULT __stdcall IDispatchEx_GetNextDispID_Proxy( \r
+    IDispatchEx * This,\r
+    /* [in] */ unsigned long grfdex,\r
+    /* [in] */ long id,\r
+    /* [out] */ long *pid);\r
+\r
+\r
+void __RPC_STUB IDispatchEx_GetNextDispID_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+HRESULT __stdcall IDispatchEx_GetNameSpaceParent_Proxy( \r
+    IDispatchEx * This,\r
+    /* [out] */ IUnknown **ppunk);\r
+\r
+\r
+void __RPC_STUB IDispatchEx_GetNameSpaceParent_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+\r
+#endif         /* __IDispatchEx_INTERFACE_DEFINED__ */\r
+\r
+\r
+#ifndef __IServiceProvider_INTERFACE_DEFINED__\r
+#define __IServiceProvider_INTERFACE_DEFINED__\r
+\r
+/* interface IServiceProvider */\r
+/* [object][uuid] */ \r
+\r
+\r
+EXTERN_C const IID IID_IServiceProvider;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+    \r
+    MIDL_INTERFACE("6D5140C1-7436-11CE-8034-00AA006009FA")\r
+    IServiceProvider : public IUnknown\r
+    {\r
+    public:\r
+        virtual HRESULT __stdcall RemoteQueryService( \r
+            /* [in] */ GUID *guidService,\r
+            /* [in] */ GUID *riid,\r
+            /* [out] */ IUnknown **ppvObject) = 0;\r
+        \r
+    };\r
+    \r
+#else  /* C style interface */\r
+\r
+    typedef struct IServiceProviderVtbl\r
+    {\r
+        BEGIN_INTERFACE\r
+        \r
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+            IServiceProvider * This,\r
+            /* [in] */ REFIID riid,\r
+            /* [iid_is][out] */ void **ppvObject);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+            IServiceProvider * This);\r
+        \r
+        ULONG ( STDMETHODCALLTYPE *Release )( \r
+            IServiceProvider * This);\r
+        \r
+        HRESULT ( __stdcall *RemoteQueryService )( \r
+            IServiceProvider * This,\r
+            /* [in] */ GUID *guidService,\r
+            /* [in] */ GUID *riid,\r
+            /* [out] */ IUnknown **ppvObject);\r
+        \r
+        END_INTERFACE\r
+    } IServiceProviderVtbl;\r
+\r
+    interface IServiceProvider\r
+    {\r
+        CONST_VTBL struct IServiceProviderVtbl *lpVtbl;\r
+    };\r
+\r
+    \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IServiceProvider_QueryInterface(This,riid,ppvObject)   \\r
+    (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)\r
+\r
+#define IServiceProvider_AddRef(This)  \\r
+    (This)->lpVtbl -> AddRef(This)\r
+\r
+#define IServiceProvider_Release(This) \\r
+    (This)->lpVtbl -> Release(This)\r
+\r
+\r
+#define IServiceProvider_RemoteQueryService(This,guidService,riid,ppvObject)   \\r
+    (This)->lpVtbl -> RemoteQueryService(This,guidService,riid,ppvObject)\r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif         /* C style interface */\r
+\r
+\r
+\r
+HRESULT __stdcall IServiceProvider_RemoteQueryService_Proxy( \r
+    IServiceProvider * This,\r
+    /* [in] */ GUID *guidService,\r
+    /* [in] */ GUID *riid,\r
+    /* [out] */ IUnknown **ppvObject);\r
+\r
+\r
+void __RPC_STUB IServiceProvider_RemoteQueryService_Stub(\r
+    IRpcStubBuffer *This,\r
+    IRpcChannelBuffer *_pRpcChannelBuffer,\r
+    PRPC_MESSAGE _pRpcMessage,\r
+    DWORD *_pdwStubPhase);\r
+\r
+\r
+\r
+#endif         /* __IServiceProvider_INTERFACE_DEFINED__ */\r
+\r
+\r
+EXTERN_C const CLSID CLSID_ShockwaveFlash;\r
+\r
+#ifdef __cplusplus\r
+\r
+class DECLSPEC_UUID("D27CDB6E-AE6D-11CF-96B8-444553540000")\r
+ShockwaveFlash;\r
+#endif\r
+\r
+EXTERN_C const CLSID CLSID_FlashObjectInterface;\r
+\r
+#ifdef __cplusplus\r
+\r
+class DECLSPEC_UUID("D27CDB71-AE6D-11CF-96B8-444553540000")\r
+FlashObjectInterface;\r
+#endif\r
+#endif /* __ShockwaveFlashObjects_LIBRARY_DEFINED__ */\r
+\r
+/* Additional Prototypes for ALL interfaces */\r
+\r
+/* end of Additional Prototypes */\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
+\r
+\r
diff --git a/server/producers/targa/TargaManager.cpp b/server/producers/targa/TargaManager.cpp
new file mode 100644 (file)
index 0000000..082b9fd
--- /dev/null
@@ -0,0 +1,372 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\..\stdafx.h"\r
+\r
+#include "TargaManager.h"\r
+#include "..\..\frame\FrameManager.h"\r
+#include "..\..\frame\FrameMediaController.h"\r
+#include "..\..\utils\FileInputStream.h"\r
+#include "..\..\fileinfo.h"\r
+#include "..\..\frame\buffers\StaticFrameBuffer.h"\r
+\r
+namespace caspar {\r
+\r
+using namespace caspar::utils;\r
+\r
+///////////////////////////////\r
+//  TargaProducer declaration\r
+//\r
+class TargaProducer : public MediaProducer, public FrameMediaController\r
+{\r
+public:\r
+       explicit TargaProducer(PixmapDataPtr pImage);\r
+       virtual ~TargaProducer();\r
+\r
+       virtual IMediaController* QueryController(const tstring& id);\r
+\r
+       virtual bool Initialize(FrameManagerPtr pFrameManager);\r
+       virtual FrameBuffer& GetFrameBuffer() {\r
+               return frameBuffer_;\r
+       }\r
+\r
+private:\r
+       StaticFrameBuffer frameBuffer_;\r
+       caspar::utils::PixmapDataPtr pImage_;\r
+};\r
+\r
+//////////////////////////////\r
+//  TargaManager definition\r
+//\r
+TargaManager::TargaManager()\r
+{\r
+       _extensions.push_back(TEXT("tga"));\r
+}\r
+\r
+TargaManager::~TargaManager()\r
+{}\r
+\r
+MediaProducerPtr TargaManager::CreateProducer(const tstring& filename) {\r
+       MediaProducerPtr result;\r
+       if(filename.length() > 0) {\r
+               utils::InputStreamPtr pTgaFile(new utils::FileInputStream(filename));\r
+               if(pTgaFile->Open()) {\r
+                       PixmapDataPtr pImage;\r
+                       if(TargaManager::Load(pTgaFile, pImage)) {\r
+                               result = MediaProducerPtr(new TargaProducer(pImage));\r
+                       }\r
+               }\r
+       }\r
+       return result;\r
+}\r
+\r
+bool TargaManager::getFileInfo(FileInfo* pFileInfo)\r
+{\r
+       if(pFileInfo != 0) {\r
+               pFileInfo->length = 1;\r
+               pFileInfo->type = TEXT("still");\r
+               pFileInfo->encoding = TEXT("TGA");\r
+               return true;\r
+       }\r
+       return false;\r
+}\r
+\r
+PixmapDataPtr TargaManager::CropPadToFrameFormat(PixmapDataPtr pSource, const FrameFormatDescription& fmtDesc)\r
+{\r
+       if(pSource->width == fmtDesc.width && pSource->height == fmtDesc.height)\r
+               return pSource;\r
+\r
+       unsigned short colsToCopy = pSource->width;\r
+       unsigned short rowsToCopy = pSource->height;\r
+\r
+       int offsetX = 0;\r
+       if(pSource->width > fmtDesc.width)\r
+       {\r
+               offsetX = (pSource->width-fmtDesc.width)/2;\r
+               colsToCopy = fmtDesc.width;\r
+       }\r
+\r
+       int offsetY = 0;\r
+       if(pSource->height > fmtDesc.height)\r
+       {\r
+               offsetY = (pSource->height-fmtDesc.height)/2;\r
+               rowsToCopy = fmtDesc.height;\r
+       }\r
+\r
+       int bytesPerPixel = pSource->bpp;\r
+\r
+       PixmapDataPtr pNewImage(new caspar::utils::PixmapData(fmtDesc.width, fmtDesc.height, bytesPerPixel));\r
+       unsigned char* pNewImageData = pNewImage->GetDataPtr();\r
+\r
+       //initialize new buffer with zeroes\r
+       memset(pNewImageData, 0, fmtDesc.width*fmtDesc.height*bytesPerPixel);\r
+\r
+       for(int i=0;i<rowsToCopy;++i)\r
+               memcpy(&(pNewImageData[bytesPerPixel*fmtDesc.width*i]), &(pSource->GetDataPtr()[bytesPerPixel*(pSource->width*(i+offsetY)+offsetX)]), bytesPerPixel*colsToCopy);\r
+\r
+       return pNewImage;\r
+}\r
+\r
+\r
+bool TargaManager::Load(utils::InputStreamPtr spTGA, PixmapDataPtr& pResult)\r
+{\r
+       utils::InputStream* pTGA = spTGA.get();\r
+       PixmapDataPtr pImage(new utils::PixmapData());\r
+\r
+       bool returnValue = true;\r
+       //correct headers to compare to\r
+       char headerUncompressed[12]     = {0,0, 2,0,0,0,0,0,0,0,0,0};\r
+       char headerCompressed[12]       = {0,0,10,0,0,0,0,0,0,0,0,0};\r
+\r
+       unsigned char header[12];\r
+       unsigned char tgaInfo[6];\r
+       unsigned int nImageSize = 0, nBytesPerPixel = 0;\r
+\r
+       unsigned char *pColorBuffer = NULL;\r
+\r
+       unsigned int i;\r
+       unsigned int nBytesPerRow;\r
+       int nCurrentRow = 0;\r
+\r
+       char rowDirection = -1;\r
+\r
+       pTGA->Read(header, 12); //read header to be able to process compressed files in one way and uncompressed files in another\r
+       pTGA->Read(tgaInfo, 6); //read image-info such as height and width\r
+\r
+       int width = tgaInfo[1] * 256 + tgaInfo[0];      //extract width\r
+       int height = tgaInfo[3] * 256 + tgaInfo[2];     //extract height\r
+       int bits = tgaInfo[4];                                          //extract bits/pixel\r
+\r
+       pImage->Set(width, height, 4);\r
+       unsigned char* pImageData = pImage->GetDataPtr();\r
+\r
+       rowDirection = -1;\r
+       if(tgaInfo[5] & 0x20)\r
+               rowDirection = 1;\r
+\r
+       //calculate usefull numbers\r
+       nBytesPerPixel = bits / 8;\r
+       nBytesPerRow = pImage->width * nBytesPerPixel;\r
+\r
+       //internal data always have 4 bytes / pixel\r
+       nImageSize = pImage->width * pImage->height * 4;\r
+\r
+       if(nBytesPerPixel != 3 && nBytesPerPixel != 4)\r
+       {\r
+               returnValue = false;\r
+               goto tgaLoaderExit;\r
+       }\r
+\r
+       memset(pImageData, 0, nImageSize);\r
+\r
+       //Workaround for image identification field problem\r
+       {\r
+               unsigned char iifSize = header[0];\r
+               unsigned char temp[256];\r
+               if(iifSize > 0)\r
+                       pTGA->Read(temp, iifSize);\r
+       }\r
+       header[0] = 0;\r
+       header[7] = 0;\r
+       //END workaround\r
+\r
+       //We've got an uncompressed file on our hands, take care of it\r
+       if(memcmp(headerUncompressed, header, 12) == 0)\r
+       {\r
+               unsigned char* pRowBuffer = new unsigned char[nBytesPerRow];\r
+\r
+               int rowIndex=0;\r
+               if(rowDirection == -1)\r
+                       nCurrentRow = height-1;\r
+               else\r
+                       nCurrentRow = 0;\r
+\r
+               for(; rowIndex < height; nCurrentRow+=rowDirection, ++rowIndex)\r
+               {\r
+                       if(pTGA->Read(pRowBuffer, nBytesPerRow) < nBytesPerRow)\r
+                       {\r
+                               delete[] pRowBuffer;\r
+                               returnValue = false;\r
+                               goto tgaLoaderExit;\r
+                       }\r
\r
+                       //Swap color-channels\r
+                       for(i=0;i<pImage->width;i++)\r
+                       {\r
+                               pImageData[4*(nCurrentRow*width+i)+0] = pRowBuffer[i*nBytesPerPixel+0];\r
+                               pImageData[4*(nCurrentRow*width+i)+1] = pRowBuffer[i*nBytesPerPixel+1];\r
+                               pImageData[4*(nCurrentRow*width+i)+2] = pRowBuffer[i*nBytesPerPixel+2];\r
+                               if(nBytesPerPixel == 4)\r
+                                       pImageData[4*(nCurrentRow*width+i)+3] = pRowBuffer[i*nBytesPerPixel+3];\r
+                               else\r
+                                       pImageData[4*(nCurrentRow*width+i)+3] = 255;\r
+                       }\r
+               }\r
+               delete[] pRowBuffer;\r
+       }\r
+\r
+       //wasn't uncompressed, is it compressed? in that case, take care of it!\r
+       else if(memcmp(headerCompressed, header, 12) == 0)\r
+       {\r
+               int rowIndex=0;\r
+               if(rowDirection == -1)\r
+                       nCurrentRow = pImage->height-1;\r
+               else\r
+                       nCurrentRow = 0;\r
+\r
+               nBytesPerRow = width * 4;\r
+\r
+               int nPixelCount = height * width;\r
+               int nCurrentPixel = 0;\r
+               int nCurrentByte = 0;\r
+\r
+               pColorBuffer = new unsigned char[nBytesPerPixel];\r
+\r
+               do\r
+               {\r
+                       unsigned char chunkHeader = 0;\r
+\r
+                       //read chunkHeader - exit on error\r
+                       if(pTGA->Read(&chunkHeader, 1) < 0)\r
+                       {\r
+                               returnValue = false;\r
+                               goto tgaLoaderExit;\r
+                       }\r
+                       \r
+                       if(chunkHeader < 128) //it's a RAW-header\r
+                       {\r
+                               chunkHeader++;\r
+                               \r
+                               for(unsigned short counter=0; counter<chunkHeader; counter++)\r
+                               {\r
+                                       //read pixeldata - exit on error\r
+                                       if(pTGA->Read(pColorBuffer, nBytesPerPixel) < nBytesPerPixel)\r
+                                       {\r
+                                               returnValue = false;\r
+                                               goto tgaLoaderExit;\r
+                                       }\r
+\r
+                                       unsigned int thisByte = nCurrentRow*nBytesPerRow+nCurrentByte;\r
+\r
+\r
+                                       pImageData[thisByte+0] = pColorBuffer[0];\r
+                                       pImageData[thisByte+1] = pColorBuffer[1];\r
+                                       pImageData[thisByte+2] = pColorBuffer[2];\r
+                                       if(nBytesPerPixel == 4)\r
+                                               pImageData[thisByte+3] = pColorBuffer[3];\r
+                                       else\r
+                                               pImageData[thisByte+3] = 255;\r
+\r
+                                       nCurrentByte += 4;\r
+                                       nCurrentPixel++;\r
+                                       if(nCurrentByte >= nBytesPerRow)\r
+                                       {\r
+                                               nCurrentRow +=  rowDirection;\r
+                                               ++rowIndex;\r
+                                               nCurrentByte = 0;\r
+                                       }\r
+                               }\r
+                       }\r
+                       else //it's a RLE header\r
+                       {\r
+                               chunkHeader -= 127;\r
+\r
+                               //read pixeldata - exit on error\r
+                               if(pTGA->Read(pColorBuffer, nBytesPerPixel) < nBytesPerPixel)\r
+                               {\r
+                                       returnValue = false;\r
+                                       goto tgaLoaderExit;\r
+                               }\r
+\r
+                               //repeat this pixel\r
+                               for(unsigned short counter=0; counter<chunkHeader; counter++)\r
+                               {\r
+                                       unsigned int thisByte = nCurrentRow*nBytesPerRow+nCurrentByte;\r
+\r
+\r
+                                       pImageData[thisByte+0] = pColorBuffer[0];\r
+                                       pImageData[thisByte+1] = pColorBuffer[1];\r
+                                       pImageData[thisByte+2] = pColorBuffer[2];\r
+                                       if(nBytesPerPixel == 4)\r
+                                               pImageData[thisByte+3] = pColorBuffer[3];\r
+                                       else\r
+                                               pImageData[thisByte+3] = 255;\r
+\r
+                                       nCurrentByte += 4;\r
+                                       nCurrentPixel++;\r
+                                       if(nCurrentByte >= nBytesPerRow)\r
+                                       {\r
+                                               nCurrentRow += rowDirection;\r
+                                               ++rowIndex;\r
+                                               nCurrentByte = 0;\r
+                                       }\r
+                               }\r
+                       }\r
+               }while(nCurrentPixel<nPixelCount && rowIndex < pImage->height);\r
+       }\r
+       else\r
+               returnValue = false;\r
+\r
+tgaLoaderExit:\r
+       if(pColorBuffer != NULL)\r
+               delete[] pColorBuffer;\r
+\r
+       if(returnValue)\r
+               pResult = pImage;\r
+\r
+       return returnValue;\r
+}\r
+\r
+\r
+///////////////////////////////\r
+//  TargaProducer definition\r
+//\r
+TargaProducer::TargaProducer(PixmapDataPtr pImage) : pImage_(pImage) {\r
+}\r
+\r
+TargaProducer::~TargaProducer() {\r
+}\r
+\r
+IMediaController* TargaProducer::QueryController(const tstring& id) {\r
+       if(id == TEXT("FrameController"))\r
+               return this;\r
+       \r
+       return 0;\r
+}\r
+\r
+bool TargaProducer::Initialize(FrameManagerPtr pFrameManager) {\r
+       if(pFrameManager != 0) {\r
+               FramePtr pFrame = pFrameManager->CreateFrame();\r
+               if(pFrame != 0 && pFrame->GetDataPtr() != 0) {\r
+                       PixmapDataPtr pResult = TargaManager::CropPadToFrameFormat(pImage_, pFrameManager->GetFrameFormatDescription());\r
+\r
+                       unsigned char* pFrameData = pFrame->GetDataPtr();\r
+                       unsigned char* pImageData = pResult->GetDataPtr();\r
+\r
+                       memcpy(pFrameData, pImageData, pFrame->GetDataSize());\r
+\r
+                       frameBuffer_.push_back(pFrame);\r
+                       return true;\r
+               }\r
+       }\r
+       return false;\r
+}\r
+\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/producers/targa/TargaManager.h b/server/producers/targa/TargaManager.h
new file mode 100644 (file)
index 0000000..bb1e16e
--- /dev/null
@@ -0,0 +1,46 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+\r
+#include "..\..\frame\Frame.h"\r
+#include "..\..\MediaManager.h"\r
+#include "..\..\MediaProducer.h"\r
+#include "..\..\utils\InputStream.h"\r
+#include "..\..\utils\PixmapData.h"\r
+\r
+namespace caspar {\r
+\r
+class FileInfo;\r
+\r
+class TargaManager : public IMediaManager\r
+{\r
+public:\r
+       TargaManager();\r
+       virtual ~TargaManager();\r
+\r
+       virtual MediaProducerPtr CreateProducer(const tstring& filename);\r
+       virtual bool getFileInfo(FileInfo* pFileInfo);\r
+\r
+       static utils::PixmapDataPtr CropPadToFrameFormat(utils::PixmapDataPtr pSource, const FrameFormatDescription& fmtDesc);\r
+       static bool Load(utils::InputStreamPtr pTGA, utils::PixmapDataPtr& pResult);\r
+};\r
+\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/producers/targascroll/TargaScrollManager.cpp b/server/producers/targascroll/TargaScrollManager.cpp
new file mode 100644 (file)
index 0000000..b19205c
--- /dev/null
@@ -0,0 +1,57 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\..\StdAfx.h"\r
+\r
+#include "TargaScrollManager.h"\r
+#include "TargaScrollProducer.h"\r
+#include "..\..\FileInfo.h"\r
+#include "..\..\MediaManager.h"\r
+\r
+namespace caspar {\r
+\r
+TargaScrollMediaManager::TargaScrollMediaManager() : IMediaManager()\r
+{\r
+       IMediaManager::_extensions.push_back(TEXT("stga"));\r
+}\r
+\r
+TargaScrollMediaManager::~TargaScrollMediaManager()\r
+{\r
+}\r
+\r
+MediaProducerPtr TargaScrollMediaManager::CreateProducer(const tstring& filename)\r
+{\r
+       TargaScrollMediaProducerPtr pTargaScrollMediaProducer(new TargaScrollMediaProducer());\r
+       if (!pTargaScrollMediaProducer->Load(filename))\r
+               pTargaScrollMediaProducer.reset();\r
+\r
+       return pTargaScrollMediaProducer;\r
+}\r
+\r
+bool TargaScrollMediaManager::getFileInfo(FileInfo* pFileInfo)\r
+{\r
+       pFileInfo->length = 1;\r
+       pFileInfo->type = TEXT("movie");\r
+       pFileInfo->encoding = TEXT("NA");\r
+\r
+       return true;\r
+}\r
+\r
+}
\ No newline at end of file
diff --git a/server/producers/targascroll/TargaScrollManager.h b/server/producers/targascroll/TargaScrollManager.h
new file mode 100644 (file)
index 0000000..13059a6
--- /dev/null
@@ -0,0 +1,45 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef TARGASCROLLMEIDAMANAGER_H\r
+#define TARGASCROLLMEIDAMANAGER_H\r
+\r
+#include "..\..\MediaManager.h"\r
+\r
+namespace caspar {\r
+\r
+class TargaScrollMediaProducer;\r
+\r
+class TargaScrollMediaManager : public IMediaManager\r
+{\r
+       public:\r
+               TargaScrollMediaManager();\r
+               virtual ~TargaScrollMediaManager();\r
+\r
+               virtual bool getFileInfo(FileInfo* pFileInfo);\r
+               virtual MediaProducerPtr CreateProducer(const tstring& filename);\r
+\r
+       private:\r
+               typedef std::tr1::shared_ptr<TargaScrollMediaProducer> TargaScrollMediaProducerPtr;\r
+};\r
+\r
+}\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/producers/targascroll/TargaScrollProducer.cpp b/server/producers/targascroll/TargaScrollProducer.cpp
new file mode 100644 (file)
index 0000000..abc2b76
--- /dev/null
@@ -0,0 +1,293 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\..\StdAfx.h"\r
+\r
+#include "TargaScrollProducer.h"\r
+#include "..\Targa\TargaManager.h"\r
+#include "..\..\MediaProducer.h"\r
+#include "..\..\FileInfo.h"\r
+#include "..\..\utils\FileInputStream.h"\r
+#include "..\..\utils\PixmapData.h"\r
+\r
+#include <boost/lexical_cast.hpp>\r
+\r
+namespace caspar {\r
+using namespace utils;\r
+\r
+int TargaScrollMediaProducer::DEFAULT_SPEED = 4;\r
+\r
+TargaScrollMediaProducer::TargaScrollMediaProducer() : initializeEvent_(FALSE, FALSE)\r
+{\r
+}\r
+\r
+TargaScrollMediaProducer::~TargaScrollMediaProducer()\r
+{\r
+       this->workerThread.Stop();\r
+}\r
+\r
+bool TargaScrollMediaProducer::Load(const tstring& filename)\r
+{\r
+       if (filename.length() > 0)\r
+       {\r
+               tstring::size_type pos = filename.find_last_of(TEXT('_'));\r
+               if(pos != tstring::npos && (pos+1) < filename.size()) {\r
+                       tstring speedStr = filename.substr(pos + 1);\r
+                       pos = speedStr.find_first_of(TEXT('.'));\r
+                       if(pos != tstring::npos)\r
+                               speedStr = speedStr.substr(0, pos);             \r
+\r
+                       try\r
+                       {\r
+                               speed = boost::lexical_cast<int, tstring>(speedStr);\r
+                       }\r
+                       catch(...)\r
+                       {\r
+                               speed = DEFAULT_SPEED;\r
+                       }\r
+               }\r
+\r
+               utils::InputStreamPtr pTgaFile(new utils::FileInputStream(filename));\r
+               if (pTgaFile->Open())\r
+                       return TargaManager::Load(pTgaFile, this->pImage);\r
+       }\r
+\r
+       return false;\r
+}\r
+\r
+IMediaController* TargaScrollMediaProducer::QueryController(const tstring& id) {\r
+       if(id == TEXT("FrameController"))\r
+               return this;\r
+       \r
+       return 0;\r
+}\r
+\r
+bool TargaScrollMediaProducer::Initialize(FrameManagerPtr pFrameManager) {\r
+       if(pFrameManager != this->pFrameManager_) {\r
+               if(pFrameManager == 0)\r
+                       return false;\r
+\r
+               if(!workerThread.IsRunning()) {\r
+                       pFrameManager_ = pFrameManager;\r
+                       return workerThread.Start(this);\r
+               }\r
+               else\r
+               {\r
+                       {\r
+                               Lock lock(*this);\r
+\r
+                               if(pFrameManager_->GetFrameFormatDescription().width != pFrameManager->GetFrameFormatDescription().width || pFrameManager_->GetFrameFormatDescription().height != pFrameManager->GetFrameFormatDescription().height) {\r
+                                       return false;\r
+                               }\r
+\r
+                               pTempFrameManager_ = pFrameManager;\r
+                       }\r
+\r
+                       initializeEvent_.Set();\r
+               }\r
+       }\r
+\r
+       return true;\r
+}\r
+\r
+\r
+void TargaScrollMediaProducer::PadImageToFrameFormat()\r
+{\r
+       const FrameFormatDescription& formatDescription = pFrameManager_->GetFrameFormatDescription();\r
+\r
+       const unsigned int PIXMAP_WIDTH = max(this->pImage->width, formatDescription.width);\r
+       const unsigned int PIXMAP_HEIGHT = max(this->pImage->height, formatDescription.height);\r
+\r
+       utils::PixmapDataPtr pNewImage(new utils::PixmapData(PIXMAP_WIDTH, PIXMAP_HEIGHT, this->pImage->bpp));\r
+\r
+       unsigned char* pNewImageData = pNewImage->GetDataPtr();\r
+       unsigned char* pImageData = this->pImage->GetDataPtr();\r
+\r
+       memset(pNewImageData, 0, pNewImage->width * pNewImage->height * pNewImage->bpp);\r
+\r
+       for (int i = 0; i < this->pImage->height; ++i)\r
+               memcpy(&pNewImageData[i* pNewImage->width * pNewImage->bpp], &pImageData[i* this->pImage->width * this->pImage->bpp], this->pImage->width * this->pImage->bpp);\r
+\r
+       this->pImage = pNewImage;\r
+}\r
+\r
+FramePtr TargaScrollMediaProducer::FillVideoFrame(FramePtr pFrame)\r
+{\r
+       const FrameFormatDescription& formatDescription = pFrameManager_->GetFrameFormatDescription();\r
+\r
+       const short deltaX = this->direction == DirectionFlag::ScrollLeft ? this->speed : -this->speed;\r
+       const short deltaY = this->direction == DirectionFlag::ScrollUp ? this->speed : -this->speed;\r
+\r
+       unsigned char* pFrameData = pFrame->GetDataPtr();\r
+       unsigned char* pImageData = this->pImage->GetDataPtr();\r
+       \r
+       bool isFirstFrame = false, isLastFrame = false;\r
+       if (this->direction == DirectionFlag::ScrollUp || this->direction == DirectionFlag::ScrollDown)\r
+       {\r
+               for (int i = 0; i < formatDescription.height; ++i)\r
+               {\r
+                       int srcRow = i + this->offset; // Assume progressive.\r
+                       if (formatDescription.mode == Interlaced)\r
+                       {\r
+                               const int nextOffset = this->offset + (deltaY * 2);\r
+                               isFirstFrame = this->offset == 0 || this->offset == (this->pImage->height - formatDescription.height);\r
+                               isLastFrame = nextOffset <= 0 || nextOffset >= (this->pImage->height - formatDescription.height);\r
+                               if (!isFirstFrame && !isLastFrame)\r
+                                       srcRow = (i % 2 == 0) ? i + this->offset : min(i + this->offset + deltaY, this->pImage->height);\r
+                       }\r
+\r
+                       int dstInxex = i * formatDescription.width * this->pImage->bpp;\r
+                       int srcIndex = srcRow * formatDescription.width * this->pImage->bpp;\r
+                       int size = formatDescription.width * this->pImage->bpp;\r
+\r
+                       memcpy(&pFrameData[dstInxex], &pImageData[srcIndex], size);     \r
+               }\r
+\r
+               if (formatDescription.mode == Interlaced && !isFirstFrame && !isLastFrame)\r
+                       this->offset += deltaY * 2;\r
+               else\r
+                       this->offset += deltaY;\r
+       }\r
+       else\r
+       {\r
+               for (int i = 0; i < formatDescription.height; ++i)\r
+               {\r
+                       int correctOffset = this->offset; // Assume progressive.\r
+                       if (formatDescription.mode == Interlaced)\r
+                       {\r
+                               const int nextOffset = this->offset + (deltaX * 2); // Next offset.\r
+                               isFirstFrame = this->offset == 0 || this->offset == (this->pImage->width - formatDescription.width);\r
+                               isLastFrame = nextOffset <= 0 || nextOffset >= (this->pImage->width - formatDescription.width);\r
+                               if (!isFirstFrame && !isLastFrame)\r
+                                       correctOffset = (i % 2 == 0) ? this->offset: this->offset + deltaX;\r
+                       }\r
+\r
+                       int dstIndex = i * formatDescription.width * this->pImage->bpp;\r
+                       int srcIndex = (i * this->pImage->width + correctOffset) * this->pImage->bpp;\r
+                       \r
+                       int stopOffset = min(correctOffset + formatDescription .width, this->pImage->width);\r
+                       int size = (stopOffset - correctOffset) * this->pImage->bpp;\r
+\r
+                       memcpy(&pFrameData[dstIndex], &pImageData[srcIndex], size);\r
+               }\r
+\r
+               if (formatDescription.mode == Interlaced && !isFirstFrame && !isLastFrame)\r
+                       this->offset += deltaX * 2;\r
+               else\r
+                       this->offset += deltaX;\r
+       }\r
+\r
+       return pFrame;\r
+}\r
+\r
+void TargaScrollMediaProducer::Run(HANDLE stopEvent)\r
+{\r
+       LOG << LogLevel::Verbose << TEXT("Targa scroll thread started");\r
+\r
+       const short waitHandleCount = 3;\r
+       HANDLE waitHandles[waitHandleCount] = { stopEvent, initializeEvent_, this->frameBuffer.GetWriteWaitHandle() };\r
+\r
+       int formatWidth = 0;\r
+       int formatHeight = 0;\r
+       {\r
+               const FrameFormatDescription& formatDescription = pFrameManager_->GetFrameFormatDescription();\r
+               formatWidth = formatDescription.width;\r
+               formatHeight = formatDescription.height;\r
+\r
+               //determine whether to scroll horizontally or vertically\r
+               if((this->pImage->width - formatWidth) > (pImage->height - formatHeight))\r
+                       direction = (speed < 0) ? DirectionFlag::ScrollRight : DirectionFlag::ScrollLeft;\r
+               else\r
+                       direction = (speed < 0) ? DirectionFlag::ScrollDown : DirectionFlag::ScrollUp;\r
+\r
+               this->speed = abs(speed / formatDescription.fps);\r
+               this->offset = 0;\r
+               if (this->direction == DirectionFlag::ScrollDown)\r
+                       this->offset = this->pImage->height - formatHeight;\r
+               else if (this->direction == DirectionFlag::ScrollRight)\r
+                       this->offset = this->pImage->width - formatWidth;\r
+       }\r
+\r
+\r
+       if (formatWidth > this->pImage->width || formatHeight > this->pImage->height)\r
+               PadImageToFrameFormat();\r
+\r
+       bool quitLoop = false;\r
+       while (!quitLoop)\r
+       {\r
+               HRESULT waitResult = WaitForMultipleObjects(waitHandleCount, waitHandles, FALSE, 1000);\r
+               switch(waitResult)\r
+               {\r
+                       case WAIT_OBJECT_0 + 0:         // Stop.\r
+                       case WAIT_FAILED:                       // Wait failiure.\r
+                               quitLoop = true;\r
+                               continue;\r
+                       case WAIT_TIMEOUT:                      // Nothing has happened.\r
+                               continue;\r
+                       case WAIT_OBJECT_0 + 1:         //initialize\r
+                               {\r
+                                       Lock lock(*this);\r
+                                       pFrameManager_ = pTempFrameManager_;\r
+                                       pTempFrameManager_.reset();\r
+                               }\r
+                               break;\r
+\r
+                       case WAIT_OBJECT_0 + 2:         // Framebuffer is ready to be filled.\r
+                       {\r
+                               // Render next frame.\r
+                               FramePtr pFrame = pFrameManager_->CreateFrame();\r
+                               pFrame = FillVideoFrame(pFrame);\r
+                               this->frameBuffer.push_back(pFrame);\r
+\r
+                               // Should we stop scrolling?\r
+                               if ((this->direction == DirectionFlag::ScrollDown || this->direction == DirectionFlag::ScrollRight) && this->offset <= 0)\r
+                                       quitLoop = true;\r
+                               else if (this->direction == DirectionFlag::ScrollUp && this->offset >= (this->pImage->height - formatHeight))\r
+                                       quitLoop = true;\r
+                               else if (this->direction == DirectionFlag::ScrollLeft && this->offset >= (this->pImage->width - formatWidth))\r
+                                       quitLoop = true;\r
+                       }\r
+               }\r
+       }\r
+       \r
+       // Render a null frame to indicate EOF.\r
+       FramePtr pNullFrame;\r
+       this->frameBuffer.push_back(pNullFrame);\r
+\r
+       LOG << LogLevel::Verbose << TEXT("Targa scroll thread ended");\r
+}\r
+\r
+bool TargaScrollMediaProducer::OnUnhandledException(const std::exception& ex) throw()\r
+{\r
+       try\r
+       {\r
+               FramePtr pNullFrame;\r
+               this->frameBuffer.push_back(pNullFrame);\r
+\r
+               LOG << LogLevel::Critical << TEXT("UNHANDLED EXCEPTION in targa scroll thread. Message: ") << ex.what();\r
+       }\r
+       catch (...)\r
+       {\r
+       }\r
+\r
+       return false;\r
+}\r
+\r
+}
\ No newline at end of file
diff --git a/server/producers/targascroll/TargaScrollProducer.h b/server/producers/targascroll/TargaScrollProducer.h
new file mode 100644 (file)
index 0000000..11c5fc4
--- /dev/null
@@ -0,0 +1,86 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef TARGASCROLLMediaProducer_H\r
+#define TARGASCROLLMediaProducer_H\r
+\r
+#include "..\..\MediaProducer.h"\r
+#include "..\..\utils\Thread.h"\r
+#include "..\..\utils\Lockable.h"\r
+#include "..\..\frame\Framemediacontroller.h"\r
+#include "..\..\frame\buffers\MotionFrameBuffer.h"\r
+\r
+namespace caspar {\r
+namespace utils {\r
+       class PixmapData;\r
+       typedef std::tr1::shared_ptr<PixmapData> PixmapDataPtr;\r
+}\r
+\r
+class TargaScrollMediaProducer : public MediaProducer, public FrameMediaController, public utils::IRunnable, utils::LockableObject\r
+{\r
+       static int DEFAULT_SPEED;\r
+public:\r
+       explicit TargaScrollMediaProducer();\r
+       TargaScrollMediaProducer(const TargaScrollMediaProducer&);\r
+       virtual ~TargaScrollMediaProducer();\r
+\r
+       bool Load(const tstring& filename);\r
+\r
+       virtual IMediaController* QueryController(const tstring& id);\r
+       virtual bool Initialize(FrameManagerPtr pFrameManager);\r
+       virtual FrameBuffer& GetFrameBuffer() {\r
+               return frameBuffer;\r
+       }\r
+\r
+       virtual void Run(HANDLE stopEvent);\r
+       virtual bool OnUnhandledException(const std::exception& ex) throw();\r
+\r
+private:\r
+       void PadImageToFrameFormat();\r
+       FramePtr FillVideoFrame(FramePtr pFrame);\r
+\r
+       struct DirectionFlag\r
+       {\r
+               enum DirectionFlagEnum\r
+               {\r
+                       ScrollUp = 1,\r
+                       ScrollDown,\r
+                       ScrollLeft,\r
+                       ScrollRight\r
+               };\r
+       };\r
+\r
+       int offset;\r
+       short speed;\r
+\r
+       utils::Thread workerThread;\r
+       utils::PixmapDataPtr pImage;\r
+\r
+       MotionFrameBuffer frameBuffer;\r
+       DirectionFlag::DirectionFlagEnum direction;\r
+\r
+       utils::Event initializeEvent_;\r
+       FrameManagerPtr pFrameManager_;\r
+       FrameManagerPtr pTempFrameManager_;\r
+};\r
+\r
+}\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/resources/Server.rc b/server/resources/Server.rc
new file mode 100644 (file)
index 0000000..0a1899d
--- /dev/null
@@ -0,0 +1,85 @@
+// Microsoft Visual C++ generated resource script.\r
+//\r
+#include "resource.h"\r
+\r
+#define APSTUDIO_READONLY_SYMBOLS\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Generated from the TEXTINCLUDE 2 resource.\r
+//\r
+#include "afxres.h"\r
+#include "VersionNo.h"\r
+#include "server.rc2"\r
+/////////////////////////////////////////////////////////////////////////////\r
+#undef APSTUDIO_READONLY_SYMBOLS\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// English (U.S.) resources\r
+\r
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r
+#ifdef _WIN32\r
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US\r
+#pragma code_page(1252)\r
+#endif //_WIN32\r
+\r
+#ifdef APSTUDIO_INVOKED\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// TEXTINCLUDE\r
+//\r
+\r
+1 TEXTINCLUDE \r
+BEGIN\r
+    "resource.h\0"\r
+END\r
+\r
+2 TEXTINCLUDE \r
+BEGIN\r
+    "#include ""afxres.h""\r\n"\r
+    "#include ""VersionNo.h""\r\n"\r
+    "#include ""server.rc2\0"\r
+END\r
+\r
+3 TEXTINCLUDE \r
+BEGIN\r
+    "\r\0"\r
+END\r
+\r
+#endif    // APSTUDIO_INVOKED\r
+\r
+#endif    // English (U.S.) resources\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// Swedish resources\r
+\r
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_SVE)\r
+#ifdef _WIN32\r
+LANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT\r
+#pragma code_page(1252)\r
+#endif //_WIN32\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Icon\r
+//\r
+\r
+// Icon with lowest ID value placed first to ensure application icon\r
+// remains consistent on all systems.\r
+IDI_ICON1               ICON                    "icon2.ico"\r
+#endif    // Swedish resources\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+\r
+#ifndef APSTUDIO_INVOKED\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Generated from the TEXTINCLUDE 3 resource.\r
+//\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+#endif    // not APSTUDIO_INVOKED\r
+\r
diff --git a/server/resources/icon2.ico b/server/resources/icon2.ico
new file mode 100644 (file)
index 0000000..3e6ad48
Binary files /dev/null and b/server/resources/icon2.ico differ
diff --git a/server/resources/server.rc2 b/server/resources/server.rc2
new file mode 100644 (file)
index 0000000..81ec9d5
--- /dev/null
@@ -0,0 +1,25 @@
+////////////////////////////////////////////////////////////\r
+// Version\r
+//\r
+#include "VersionNo.h"\r
+VS_VERSION_INFO VERSIONINFO\r
+FILEVERSION VERSION_FILE\r
+PRODUCTVERSION VERSION_PRODUCT\r
+\r
+BEGIN\r
+    BLOCK "StringFileInfo"\r
+    BEGIN\r
+        BLOCK "040904b0"\r
+        BEGIN\r
+            VALUE "CompanyName", "Sveriges Television AB\0"\r
+            VALUE "FileVersion", VERSION_FILESTR\r
+            VALUE "LegalCopyright", "Copyright (C) 2007\0"\r
+            VALUE "ProductName", "Caspar CG\0"\r
+            VALUE "ProductVersion", VERSION_PRODUCTSTR\r
+        END\r
+    END\r
+    BLOCK "VarFileInfo"\r
+    BEGIN\r
+        VALUE "Translation", 0x409, 1200\r
+    END\r
+END\r
diff --git a/server/string_convert.h b/server/string_convert.h
new file mode 100644 (file)
index 0000000..a51da9c
--- /dev/null
@@ -0,0 +1,81 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _STRING_CONVERT_H_\r
+#define _STRING_CONVERT_H_\r
+\r
+#include <locale>\r
+#include <iostream>\r
+#include <string>\r
+#include <sstream>\r
+#include <boost/lexical_cast.hpp>\r
+       \r
+namespace caspar { namespace utils {\r
+\r
+std::wstring widen(const std::string& str, const std::locale& locale = std::locale())\r
+{\r
+       std::wstringstream wsstr ;\r
+       wsstr.imbue(locale);\r
+       const std::ctype<wchar_t>& ctfacet = std::use_facet<std::ctype<wchar_t>>(wsstr.getloc()) ;\r
+       for(size_t i = 0 ;i < str.size(); ++i)\r
+               wsstr << ctfacet.widen(str[i]) ;\r
+       return wsstr.str() ;\r
+}\r
+       \r
+std::string narrow(const std::wstring& str, const std::locale& locale = std::locale())\r
+{\r
+       std::stringstream sstr;\r
+       sstr.imbue(locale);\r
+       const std::ctype<char>& ctfacet = std::use_facet<std::ctype<char>>(sstr.getloc());\r
+       for(size_t i = 0; i < str.size(); ++i)\r
+               sstr << ctfacet.narrow(str[i], 0) ;\r
+       return sstr.str() ;\r
+}\r
+\r
+std::string narrow_to_latin1(const std::wstring& wideString)\r
+{\r
+       std::string destBuffer;\r
+       //28591 = ISO 8859-1 Latin I\r
+       int bytesWritten = 0;\r
+       int multibyteBufferCapacity = WideCharToMultiByte(28591, 0, wideString.c_str(), -1, 0, 0, nullptr, nullptr);\r
+       if(multibyteBufferCapacity > 0) \r
+       {\r
+               destBuffer.resize(multibyteBufferCapacity);\r
+               bytesWritten = WideCharToMultiByte(28591, 0, wideString.c_str(), -1, &destBuffer[0], destBuffer.size(), nullptr, nullptr);\r
+       }\r
+       destBuffer.resize(bytesWritten);\r
+       return destBuffer;\r
+}\r
+\r
+template <typename T>\r
+T lexical_cast_or_default(const std::wstring str, T defaultValue)\r
+{\r
+       try\r
+       {\r
+               if(!str.empty())\r
+                       return boost::lexical_cast<T>(str);\r
+       }\r
+       catch(...){}\r
+       return defaultValue;\r
+}\r
+\r
+}}\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/utils/Allocator.h b/server/utils/Allocator.h
new file mode 100644 (file)
index 0000000..f54706b
--- /dev/null
@@ -0,0 +1,219 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+\r
+#include <vector>\r
+#include "lockable.h"\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+// TODO: (R.N) Create a scalable allocator with seperate memory pools for different threads, aka. tbb::scalable_allocator\r
+\r
+template<unsigned char BlocksInChunk = 8, unsigned char Alignment = 16>\r
+class FixedAllocator : private utils::LockableObject\r
+{\r
+       struct Chunk\r
+       {\r
+               void Init(std::size_t blockSize, unsigned char blocks);\r
+               void Destroy();\r
+\r
+               void* Allocate();\r
+               void Deallocate(void* p);\r
+\r
+               unsigned char blocksAvailable_;\r
+               unsigned char* GetDataPtr() const {\r
+                       return pData_;\r
+               }\r
+               unsigned char GetAlignmentOffset() const {\r
+                       return alignmentOffset_;\r
+               }\r
+\r
+       private:\r
+               unsigned char alignmentOffset_;\r
+               unsigned char firstAvailableBlock_;\r
+               unsigned char* pData_;\r
+               unsigned int blockSize_;\r
+       };\r
+       typedef std::vector<Chunk> Chunks;\r
+\r
+       FixedAllocator(const FixedAllocator&);\r
+       FixedAllocator& operator=(const FixedAllocator&);\r
+public:\r
+       explicit FixedAllocator(unsigned int blockSize);\r
+\r
+       ~FixedAllocator();\r
+\r
+       void* Allocate();\r
+       void Deallocate(void* p);\r
+\r
+private:\r
+       bool IsPtrInChunk(void* p, const Chunk& c) {\r
+               return (p >= c.GetDataPtr() && p < (c.GetDataPtr() + chunkSize + c.GetAlignmentOffset()));\r
+       }\r
+\r
+       unsigned int blockSize_;\r
+       const std::size_t chunkSize;\r
+       Chunks chunks_;\r
+\r
+       Chunk* pAllocChunk_;\r
+       Chunk* pDeallocChunk_;\r
+};\r
+typedef std::tr1::shared_ptr<FixedAllocator<> > FixedAllocatorPtr;\r
+\r
+template<unsigned char BlocksInChunk, unsigned char Alignment>\r
+void FixedAllocator<BlocksInChunk, Alignment>::Chunk::Init(std::size_t blockSize, unsigned char blocks) {\r
+       pData_ = new unsigned char[blockSize*blocks + Alignment];\r
+       alignmentOffset_ = static_cast<unsigned char>(Alignment - (reinterpret_cast<std::size_t>(pData_) % Alignment));\r
+       firstAvailableBlock_ = 0;\r
+       blocksAvailable_ = blocks;\r
+       blockSize_ = blockSize;\r
+\r
+       unsigned char i = 0;\r
+       unsigned char* p = pData_ + alignmentOffset_;\r
+       while(i < blocks) {\r
+               *p = ++i;\r
+               p += blockSize;\r
+       }\r
+}\r
+template<unsigned char BlocksInChunk, unsigned char Alignment>\r
+void FixedAllocator<BlocksInChunk, Alignment>::Chunk::Destroy() {\r
+       if(pData_ != 0) {\r
+               delete[] pData_;\r
+               pData_ = 0;\r
+               blocksAvailable_ = 0;\r
+               firstAvailableBlock_ = 0;\r
+               alignmentOffset_ = 0;\r
+               blockSize_ = 0;\r
+       }       \r
+}\r
+\r
+template<unsigned char BlocksInChunk, unsigned char Alignment>\r
+void* FixedAllocator<BlocksInChunk, Alignment>::Chunk::Allocate() {\r
+       if(blocksAvailable_ < 1) return 0;\r
+\r
+       unsigned char* pResult = pData_ + (firstAvailableBlock_ * blockSize_ + alignmentOffset_);\r
+       firstAvailableBlock_ = *pResult;\r
+       --blocksAvailable_;\r
+\r
+       return pResult;\r
+}\r
+\r
+template<unsigned char BlocksInChunk, unsigned char Alignment>\r
+void FixedAllocator<BlocksInChunk, Alignment>::Chunk::Deallocate(void* p) {\r
+       _ASSERT(p >= pData_);\r
+\r
+       unsigned char* pToRelease = static_cast<unsigned char*>(p);\r
+       _ASSERT((pToRelease - pData_) % blockSize_ == alignmentOffset_);\r
+       *pToRelease = firstAvailableBlock_;\r
+\r
+       firstAvailableBlock_ = static_cast<unsigned char>((pToRelease - pData_) / blockSize_);\r
+       _ASSERT(firstAvailableBlock_ == (pToRelease - pData_) / blockSize_);\r
+\r
+       ++blocksAvailable_;\r
+}\r
+\r
+\r
+template<unsigned char BlocksInChunk, unsigned char Alignment>\r
+FixedAllocator<BlocksInChunk, Alignment>::FixedAllocator(unsigned int blockSize) : blockSize_(blockSize), chunkSize(blockSize*BlocksInChunk), pAllocChunk_(0), pDeallocChunk_(0) {\r
+}\r
+\r
+template<unsigned char BlocksInChunk, unsigned char Alignment>\r
+FixedAllocator<BlocksInChunk, Alignment>::~FixedAllocator() {\r
+       Chunks::iterator it = chunks_.begin();\r
+       Chunks::iterator end = chunks_.end();\r
+\r
+       for(; it != end; ++it) {\r
+               (*it).Destroy();\r
+       }\r
+\r
+       chunks_.clear();\r
+}\r
+\r
+template<unsigned char BlocksInChunk, unsigned char Alignment>\r
+void* FixedAllocator<BlocksInChunk, Alignment>::Allocate() {\r
+       Lock lock(*this);\r
+\r
+       if(pAllocChunk_ == 0 || pAllocChunk_->blocksAvailable_ == 0) {\r
+               Chunks::iterator it = chunks_.begin();\r
+               Chunks::iterator end = chunks_.end();\r
+               for(;; ++it) {\r
+                       if(it == end) {\r
+                               Chunk newChunk;\r
+                               newChunk.Init(blockSize_, BlocksInChunk);\r
+                               chunks_.push_back(newChunk);\r
+                               pAllocChunk_ = &chunks_.back();\r
+                               pDeallocChunk_ = &chunks_.back();\r
+                               break;\r
+                       }\r
+\r
+                       if(it->blocksAvailable_ > 0) {\r
+                               pAllocChunk_ = &(*it);\r
+                               break;\r
+                       }\r
+               }\r
+       }\r
+\r
+       _ASSERT(pAllocChunk_ != 0);\r
+       _ASSERT(pAllocChunk_->blocksAvailable_ > 0);\r
+       return pAllocChunk_->Allocate();\r
+}\r
+\r
+template<unsigned char BlocksInChunk, unsigned char Alignment>\r
+void FixedAllocator<BlocksInChunk, Alignment>::Deallocate(void *p) {\r
+       Lock lock(*this);\r
+\r
+       _ASSERT(pDeallocChunk_ != 0);\r
+\r
+       Chunks::iterator end = chunks_.end();\r
+\r
+       if(IsPtrInChunk(p, *pDeallocChunk_)) {\r
+               pDeallocChunk_->Deallocate(p);\r
+       }\r
+       else {\r
+               Chunks::iterator it = chunks_.begin();\r
+               for(; it != end; ++it) {\r
+                       if(IsPtrInChunk(p, (*it))) {\r
+                               (*it).Deallocate(p);\r
+                               pDeallocChunk_ = &(*it);\r
+                               break;\r
+                       }\r
+               }\r
+               _ASSERT(it != end);\r
+       }\r
+       \r
+       //If this deallocation emptied the chunk, move it to the end\r
+       if(pDeallocChunk_->blocksAvailable_ == BlocksInChunk) {\r
+               --end;\r
+               //destroy the currently last chunk if the that also is empty\r
+               if(&(*end) != pDeallocChunk_ && end->blocksAvailable_ == BlocksInChunk) {\r
+                       end->Destroy();\r
+                       chunks_.erase(end);\r
+               }\r
+\r
+               std::swap(*pDeallocChunk_, chunks_.back());\r
+\r
+//             ASSERT(pDeallocChunk_->blocksAvailable_ > 0);\r
+       }\r
+}\r
+\r
+}      //namespace utils\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/utils/BitmapHolder.cpp b/server/utils/BitmapHolder.cpp
new file mode 100644 (file)
index 0000000..6b2cbb0
--- /dev/null
@@ -0,0 +1,129 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\StdAfx.h"\r
+\r
+#include "BitmapHolder.h"\r
+#include "DCWrapper.h"\r
+\r
+namespace caspar{\r
+\r
+bool CreateBitmap(HDC dc, size_t width, size_t height, HBITMAP& hBitmap, void** pBitmapData, void* memory)\r
+{\r
+       BITMAPINFO bitmapInfo;\r
+       bitmapInfo.bmiHeader.biBitCount = 32;\r
+       bitmapInfo.bmiHeader.biClrImportant = 0;\r
+       bitmapInfo.bmiHeader.biClrUsed = 0;\r
+       bitmapInfo.bmiHeader.biCompression = BI_RGB;\r
+       bitmapInfo.bmiHeader.biHeight = -height;\r
+       bitmapInfo.bmiHeader.biPlanes = 1;\r
+       bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFO);\r
+       bitmapInfo.bmiHeader.biWidth = width;\r
+       bitmapInfo.bmiHeader.biSizeImage = 0;\r
+       bitmapInfo.bmiHeader.biXPelsPerMeter = 0;\r
+       bitmapInfo.bmiHeader.biYPelsPerMeter = 0;\r
+\r
+       if(memory != NULL)\r
+       {               \r
+               HDC memoryDC = CreateCompatibleDC(dc);\r
+               if(memoryDC == NULL)\r
+                       return false;\r
+\r
+               HANDLE hMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, width*height*4, NULL);\r
+               MapViewOfFileEx(hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0, memory);\r
+\r
+               hBitmap = CreateDIBSection(memoryDC, &bitmapInfo, DIB_RGB_COLORS, pBitmapData, hMapping, 0);\r
+       }\r
+       else\r
+               hBitmap = CreateDIBSection(dc, &bitmapInfo, DIB_RGB_COLORS, pBitmapData, NULL, 0);\r
+\r
+       return (hBitmap != 0);\r
+}\r
+\r
+struct BitmapHolder::Implementation\r
+{      \r
+\r
+       Implementation(HWND hWnd, size_t width, size_t height, void* memory)\r
+               : hDC_(0), hBitmap_(0), pBitmapData_(0), width_(width), height_(height)\r
+       {\r
+               DCWrapper hDC(hWnd);\r
+\r
+               hDC_ = CreateCompatibleDC(hDC);\r
+               if(CreateBitmap(hDC_, width_, height_, hBitmap_, reinterpret_cast<void**>(&pBitmapData_), memory))\r
+                       SelectObject(hDC_, hBitmap_);   \r
+               else\r
+               {\r
+                       hDC_ = 0;\r
+                       hBitmap_ = 0;\r
+                       pBitmapData_ = 0;\r
+                       throw std::exception("Failed to create bitmap");\r
+               }\r
+       }\r
+\r
+       ~Implementation()\r
+       {       \r
+               if(hBitmap_ != 0) \r
+               {\r
+                       DeleteObject(hBitmap_);\r
+                       hBitmap_ = 0;\r
+               }\r
+\r
+               if(hDC_ != 0) \r
+               {\r
+                       DeleteDC(hDC_);\r
+                       hDC_ = 0;\r
+               }\r
+       }\r
+\r
+       size_t width_;\r
+       size_t height_;\r
+       HDC hDC_;\r
+       HBITMAP hBitmap_;\r
+       unsigned char* pBitmapData_;\r
+};\r
+\r
+BitmapHolder::BitmapHolder(HWND hWnd, size_t width, size_t height, void* memory): pImpl_(new Implementation(hWnd, width, height, memory))\r
+{\r
+}\r
+\r
+HDC BitmapHolder::GetDC() const {\r
+       return pImpl_->hDC_;\r
+}\r
+\r
+unsigned char* BitmapHolder::GetPtr() const {\r
+       return pImpl_->pBitmapData_;\r
+}\r
+\r
+size_t BitmapHolder::Width() const\r
+{\r
+       return pImpl_->width_;\r
+}\r
+\r
+size_t BitmapHolder::Height() const\r
+{\r
+       return pImpl_->height_;\r
+}\r
+\r
+size_t BitmapHolder::Size() const\r
+{\r
+       return pImpl_->width_*pImpl_->height_*4;\r
+}\r
+\r
+}
\ No newline at end of file
diff --git a/server/utils/BitmapHolder.h b/server/utils/BitmapHolder.h
new file mode 100644 (file)
index 0000000..067376a
--- /dev/null
@@ -0,0 +1,61 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _BITMAP_HOLDER_\r
+#define _BITMAP_HOLDER_\r
+\r
+#include <memory>\r
+#include "..\frame\Frame.h"\r
+#include "Noncopyable.hpp"\r
+\r
+namespace caspar{\r
+\r
+/*\r
+   Class: BitmapHolder   \r
+\r
+   Changes: \r
+   2010/4/2 (R.N), Refactored\r
+   2010/4/3 (R.N), Implemented functionality to map bitmap to allocated memory\r
+\r
+   Author: Niklas P. Andersson, N.A            \r
+*/\r
+\r
+class BitmapHolder : private utils::Noncopyable\r
+{\r
+public:\r
+       BitmapHolder(HWND hWnd, size_t height, size_t width, void* memory = NULL);\r
+\r
+       HDC GetDC() const;\r
+       unsigned char* GetPtr() const;\r
+       size_t Width() const;\r
+       size_t Height() const;\r
+       size_t Size() const;\r
+\r
+private:\r
+\r
+       struct Implementation;\r
+       std::tr1::shared_ptr<Implementation> pImpl_;\r
+};\r
+typedef std::tr1::shared_ptr<BitmapHolder> BitmapHolderPtr;\r
+\r
+}\r
+\r
+#endif\r
+\r
diff --git a/server/utils/CPUID.cpp b/server/utils/CPUID.cpp
new file mode 100644 (file)
index 0000000..4b4ef51
--- /dev/null
@@ -0,0 +1,158 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\stdafx.h"\r
+#include "CPUID.hpp"\r
+#include <intrin.h>\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+CPUID::CPUID() : \r
+       FPU(0),\r
+       VME(0),         \r
+       DE(0),          \r
+       PSE(0),         \r
+       TSC(0),         \r
+       MSR(0),         \r
+       PAE(0),         \r
+       MCE(0),         \r
+       CX8(0),         \r
+       APIC(0),        \r
+       SEP(0),         \r
+       MTRR(0),        \r
+       PGE(0),         \r
+       MCA(0),         \r
+       CMOV(0),        \r
+       PAT(0),         \r
+       PSE_36(0),      \r
+       PSN(0),         \r
+       CLFSH(0),               \r
+       DS(0),  \r
+       ACPI(0),                \r
+       MMX(0), \r
+       FXSR(0),\r
+       SSE(0), \r
+       SSE2(0),        \r
+       SSE3(0),        \r
+       SSSE3(0),        \r
+       SSE4_1(0),      \r
+       SSE4_2(0),      \r
+       SSE5(0),        \r
+       SS(0),  \r
+       HTT(0), \r
+       TM(0),  \r
+       IA_64(0),\r
+       Family(0),\r
+       Model(0),\r
+       ModelEx(0),\r
+       Stepping(0),\r
+       FamilyEx(0),\r
+       Brand(0),\r
+       Type(0)\r
+{              \r
+       int CPUInfo[4] = {-1};\r
+       __cpuid(CPUInfo, 0);    \r
+\r
+       int nIds = CPUInfo[0];\r
+       ID.append(reinterpret_cast<char*>(&CPUInfo[1]), 4);\r
+       ID.append(reinterpret_cast<char*>(&CPUInfo[3]), 4);\r
+       ID.append(reinterpret_cast<char*>(&CPUInfo[2]), 4);\r
+\r
+       for (int i = 0; i <= nIds; ++i)\r
+       {\r
+               __cpuid(CPUInfo, i);\r
+\r
+               if  (i == 1)\r
+               {\r
+                       Stepping =      (CPUInfo[0]      ) & 0x0F;\r
+                       Model =         (CPUInfo[0] >> 4 ) & 0x0F;\r
+                       Family =        (CPUInfo[0] >> 8 ) & 0x0F;\r
+                       Type =          (CPUInfo[0] >> 12) & 0x03;\r
+                       ModelEx =       (CPUInfo[0] >> 16) & 0x0F;\r
+                       FamilyEx =      (CPUInfo[0] >> 20) & 0xFF;\r
+                       Brand =         (CPUInfo[1]              ) & 0xFF;                      \r
+\r
+                       if(ID == "GenuineIntel") \r
+                       {\r
+                               FPU             = (CPUInfo[3] & (1 << 0))  != 0;\r
+                               VME             = (CPUInfo[3] & (1 << 1))  != 0;\r
+                               DE              = (CPUInfo[3] & (1 << 2))  != 0;\r
+                               PSE             = (CPUInfo[3] & (1 << 3))  != 0;\r
+                               TSC             = (CPUInfo[3] & (1 << 4))  != 0;\r
+                               MSR             = (CPUInfo[3] & (1 << 5))  != 0;\r
+                               PAE             = (CPUInfo[3] & (1 << 6))  != 0;\r
+                               MCE             = (CPUInfo[3] & (1 << 7))  != 0;\r
+                               CX8             = (CPUInfo[3] & (1 << 8))  != 0;\r
+                               APIC    = (CPUInfo[3] & (1 << 9))  != 0;\r
+                               //              = (CPUInfo[3] & (1 << 10)) != 0;\r
+                               SEP             = (CPUInfo[3] & (1 << 11)) != 0;\r
+                               MTRR    = (CPUInfo[3] & (1 << 12)) != 0;\r
+                               PGE             = (CPUInfo[3] & (1 << 13)) != 0;\r
+                               MCA             = (CPUInfo[3] & (1 << 14)) != 0;\r
+                               CMOV    = (CPUInfo[3] & (1 << 15)) != 0;\r
+                               PAT             = (CPUInfo[3] & (1 << 16)) != 0;\r
+                               PSE_36  = (CPUInfo[3] & (1 << 17)) != 0;\r
+                               PSN             = (CPUInfo[3] & (1 << 18)) != 0;\r
+                               CLFSH   = (CPUInfo[3] & (1 << 19)) != 0;\r
+                               //              = (CPUInfo[3] & (1 << 20)) != 0;\r
+                               DS              = (CPUInfo[3] & (1 << 21)) != 0;\r
+                               ACPI    = (CPUInfo[3] & (1 << 22)) != 0;\r
+                               MMX             = (CPUInfo[3] & (1 << 23)) != 0;\r
+                               FXSR    = (CPUInfo[3] & (1 << 24)) != 0;\r
+                               SSE             = (CPUInfo[3] & (1 << 25)) != 0;\r
+                               SSE2    = (CPUInfo[3] & (1 << 26)) != 0;\r
+                               SS              = (CPUInfo[3] & (1 << 27)) != 0;\r
+                               HTT             = (CPUInfo[3] & (1 << 28)) != 0;\r
+                               TM              = (CPUInfo[3] & (1 << 29)) != 0;\r
+                               //              = (CPUInfo[3] & (1 << 30)) != 0;\r
+                               IA_64   = (CPUInfo[3] & (1 << 31)) != 0;\r
+\r
+                               SSE3    = (CPUInfo[2] & (1 << 0))  != 0;\r
+                               SSSE3   = (CPUInfo[2] & (1 << 9))  != 0;\r
+                               SSE4_1  = (CPUInfo[2] & (1 << 19)) != 0;\r
+                               SSE4_2  = (CPUInfo[2] & (1 << 20)) != 0;\r
+                       }\r
+                       else if(ID == "AuthenticAMD") \r
+                       {\r
+                       }\r
+               }\r
+       }       \r
+\r
+       if(SSE5)\r
+               SIMD = utils::SSE5;\r
+       else if(SSE4_2)\r
+               SIMD = utils::SSE4_2;\r
+       else if(SSE4_1)\r
+               SIMD = utils::SSE4_1;\r
+       else if(SSSE3)\r
+               SIMD = utils::SSSE3;\r
+       else if(SSE3)\r
+               SIMD = utils::SSE3;\r
+       else if(SSE2)\r
+               SIMD = utils::SSE2;\r
+       else if(SSE)\r
+               SIMD = utils::SSE;\r
+       else \r
+               SIMD = utils::REF;\r
+}\r
+\r
+}\r
+}\r
diff --git a/server/utils/CPUID.hpp b/server/utils/CPUID.hpp
new file mode 100644 (file)
index 0000000..bb21db8
--- /dev/null
@@ -0,0 +1,110 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _CPUID_H_\r
+#define _CPUID_H_\r
+\r
+#include <string>\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+enum SIMD\r
+{\r
+       AUTO,\r
+       REF,\r
+       SSE,\r
+       SSE2,\r
+       SSE3,\r
+       SSSE3,\r
+       SSE4_1,\r
+       SSE4_2,\r
+       SSE5\r
+};\r
+\r
+/*\r
+   Class: CPUID\r
+\r
+   Retrieves CPU hardware inforomation.\r
+\r
+   Author: Robert Nagy, R.N (SVT 2009)\r
+               \r
+*/\r
+struct CPUID\r
+{\r
+       CPUID();\r
+\r
+       std::string ID;\r
+\r
+       bool FPU;               //Floating Point Unit\r
+       bool VME;               //Virtual Mode Extension\r
+       bool DE;                //Debugging Extension\r
+       bool PSE;               //Page Size Extension\r
+       bool TSC;               //Time Stamp Counter\r
+       bool MSR;               //Model Specific Registers\r
+       bool PAE;               //Physical Address Extesnion\r
+       bool MCE;               //Machine Check Extension\r
+       bool CX8;               //CMPXCHG8 Instruction\r
+       bool APIC;              //On-chip APIC Hardware\r
+       bool SEP;               //SYSENTER SYSEXIT\r
+       bool MTRR;              //Machine Type Range Registers\r
+       bool PGE;               //Global Paging Extension\r
+       bool MCA;               //Machine Check Architecture\r
+       bool CMOV;              //Conditional Move Instrction\r
+       bool PAT;               //Page Attribute Table\r
+       bool PSE_36;    //36-bit Page Size Extension\r
+       bool PSN;               //96-bit Processor Serial Number\r
+       bool CLFSH;             //CLFLUSH Instruction\r
+       bool DS;                //Debug Trace Store\r
+       bool ACPI;              //ACPI Support\r
+       bool MMX;               //MMX Technology\r
+       bool FXSR;              //FXSAVE FXRSTOR (Fast save and restore)\r
+       bool SSE;               //Streaming SIMD Extensions\r
+       bool SSE2;              //Streaming SIMD Extensions 2\r
+       bool SSE3;\r
+       bool SSSE3; \r
+       bool SSE4_1;\r
+       bool SSE4_2;\r
+       bool SSE5;\r
+       bool SS;                //Self-Snoop\r
+       bool HTT;               //Hyper-Threading Technology\r
+       bool TM;                //Thermal Monitor Supported\r
+       bool IA_64;             //IA-64 capable \r
+\r
+       int Family;\r
+       int Model;\r
+       int ModelEx;\r
+       int Stepping;\r
+       int FamilyEx;\r
+       int Brand; \r
+       int Type;\r
+\r
+       utils::SIMD SIMD;\r
+\r
+       //int CacheLineSize;\r
+       //int LogicalProcessorCount;\r
+       //int LocalAPICID;\r
+\r
+};\r
+\r
+}\r
+}\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/utils/CommandQueue.h b/server/utils/CommandQueue.h
new file mode 100644 (file)
index 0000000..2d7b86c
--- /dev/null
@@ -0,0 +1,152 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _COMMANDQUEUE_H__\r
+#define _COMMANDQUEUE_H__\r
+\r
+#pragma once\r
+\r
+#include <list>\r
+#include "thread.h"\r
+#include "Lockable.h"\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+//TODO: Add idle-processing. preferably as a functor suplied at construction-time\r
+\r
+//CommandQueue is a \r
+template<typename T>\r
+class CommandQueue\r
+{\r
+       template<typename U>\r
+       class WorkerThread : public utils::IRunnable, private utils::LockableObject\r
+       {\r
+       public:\r
+               WorkerThread() : commandAvailibleEvent_(TRUE, FALSE)\r
+               {}\r
+\r
+               void AddCommand(U pCommand);\r
+               virtual void Run(HANDLE stopEvent);\r
+               virtual bool OnUnhandledException(const std::exception& ex) throw();\r
+\r
+       private:\r
+               utils::Event    commandAvailibleEvent_;\r
+\r
+               //Needs synro-protection\r
+               std::list<U> commands_;\r
+       };\r
+\r
+       CommandQueue(const CommandQueue&);\r
+       CommandQueue& operator=(const CommandQueue&);\r
+public:\r
+       CommandQueue() : pWorker_(new WorkerThread<T>())\r
+       {}\r
+       ~CommandQueue() \r
+       {}\r
+\r
+       bool Start();\r
+       void Stop();\r
+       void AddCommand(T pCommand);\r
+\r
+private:\r
+       utils::Thread   commandPump_;\r
+       std::tr1::shared_ptr<WorkerThread<T> > pWorker_;\r
+\r
+};\r
+\r
+template<typename T>\r
+bool CommandQueue<T>::Start() {\r
+       return commandPump_.Start(pWorker_.get());\r
+}\r
+\r
+template<typename T>\r
+void CommandQueue<T>::Stop() {\r
+       commandPump_.Stop();\r
+}\r
+\r
+template<typename T>\r
+void CommandQueue<T>::AddCommand(T pCommand) {\r
+       pWorker_->AddCommand(pCommand);\r
+}\r
+\r
+template<typename T>\r
+template<typename U>\r
+void CommandQueue<T>::WorkerThread<U>::AddCommand(U pCommand) {\r
+       Lock lock(*this);\r
+\r
+       commands_.push_back(pCommand);\r
+       commandAvailibleEvent_.Set();\r
+}\r
+\r
+template<typename T>\r
+template<typename U>\r
+void CommandQueue<T>::WorkerThread<U>::Run(HANDLE stopEvent)\r
+{\r
+       HANDLE events[2] = {commandAvailibleEvent_, stopEvent};\r
+       U pCommand;\r
+\r
+       while(true) {\r
+               DWORD waitResult = WaitForMultipleObjects(2, events, FALSE, 1000);\r
+               int result = waitResult - WAIT_OBJECT_0;\r
+\r
+               if(result == 1) {\r
+                       break;\r
+               }\r
+               else if(result == 0) {\r
+                       Lock lock(*this);\r
+\r
+                       if(commands_.size() > 0) {\r
+                               pCommand = commands_.front();\r
+                               commands_.pop_front();\r
+\r
+                               if(commands_.size() == 0)\r
+                                       commandAvailibleEvent_.Reset();\r
+                       }\r
+               }\r
+\r
+               if(pCommand != 0) {\r
+                       pCommand->Execute();\r
+                       pCommand.reset();\r
+               }\r
+       }\r
+}\r
+\r
+template<typename T>\r
+template<typename U>\r
+bool CommandQueue<T>::WorkerThread<U>::OnUnhandledException(const std::exception& ex) throw() {\r
+       bool bDoRestart = true;\r
+\r
+       try \r
+       {\r
+               LOG << LogLevel::Critical << TEXT("UNHANDLED EXCEPTION in commandqueue. Message: ") << ex.what() << LogStream::Flush;\r
+       }\r
+       catch(...)\r
+       {\r
+               bDoRestart = false;\r
+       }\r
+\r
+       return bDoRestart;\r
+}\r
+\r
+}      //namespace utils\r
+}      //namespace caspar\r
+\r
+#endif //_COMMANDQUEUE_H__
\ No newline at end of file
diff --git a/server/utils/CritSectLock.h b/server/utils/CritSectLock.h
new file mode 100644 (file)
index 0000000..cf5da20
--- /dev/null
@@ -0,0 +1,48 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef        _CASPAR_CRITSECTLOCK_H__\r
+#define _CASPAR_CRITSECTLOCK_H__\r
+\r
+#pragma once\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+class CritSectLock\r
+{\r
+public:\r
+       CritSectLock(CRITICAL_SECTION* pCritSect) : pCriticalSection_(pCritSect)\r
+       {\r
+               EnterCriticalSection(pCriticalSection_);\r
+       }\r
+       ~CritSectLock()\r
+       {\r
+               LeaveCriticalSection(pCriticalSection_);\r
+       }\r
+\r
+private:\r
+       CRITICAL_SECTION* pCriticalSection_;\r
+};\r
+\r
+}      //namespace utils\r
+}      //namespace caspar\r
+\r
+#endif //_CASPAR_CRITSECTLOCK_H__
\ No newline at end of file
diff --git a/server/utils/DCWrapper.cpp b/server/utils/DCWrapper.cpp
new file mode 100644 (file)
index 0000000..b7c1f62
--- /dev/null
@@ -0,0 +1,37 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\stdafx.h"\r
+#include "DCWrapper.h"\r
+\r
+namespace caspar\r
+{\r
+\r
+DCWrapper::DCWrapper(HWND hWnd) : hWnd_(hWnd), dc_(::GetDC(hWnd))\r
+{}\r
+\r
+DCWrapper::~DCWrapper()\r
+{\r
+       if(dc_ != 0)\r
+               ::ReleaseDC(hWnd_, dc_);\r
+}\r
+\r
+\r
+}
\ No newline at end of file
diff --git a/server/utils/DCWrapper.h b/server/utils/DCWrapper.h
new file mode 100644 (file)
index 0000000..48efeff
--- /dev/null
@@ -0,0 +1,44 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _DCWRAPPER_H_\r
+#define _DCWRAPPER_H_\r
+\r
+namespace caspar\r
+{\r
+\r
+class DCWrapper\r
+{\r
+public:\r
+       explicit DCWrapper(HWND hWnd);\r
+       ~DCWrapper();\r
+       \r
+       operator HDC() {\r
+               return dc_;\r
+       }\r
+\r
+private:\r
+       HWND hWnd_;\r
+       HDC dc_;\r
+};\r
+\r
+}\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/utils/DataBuffer.h b/server/utils/DataBuffer.h
new file mode 100644 (file)
index 0000000..c855970
--- /dev/null
@@ -0,0 +1,98 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+template<typename T>\r
+class DataBuffer\r
+{\r
+public:\r
+       typedef T DataType;\r
+\r
+       DataBuffer() : pData_(0), length_(0), capacity_(0)\r
+       {}\r
+       DataBuffer(const DataBuffer& b) : pData_(new T[b.capacity_]), capacity_(b.capacity_)\r
+       {\r
+               memcpy(pData_, b.pData_, b.capacity_*sizeof(T));\r
+       }\r
+       const DataBuffer& operator=(const DataBuffer& b)\r
+       {\r
+               DataBuffer temp(b);\r
+               swap(temp);\r
+       }\r
+       ~DataBuffer() {\r
+               FreeData();\r
+       }\r
+\r
+       void Fill(const T* pSrc, unsigned int count, unsigned int offset=0) {\r
+               int neededCapacity = count + offset;\r
+               Realloc(neededCapacity);\r
+\r
+               length_ = neededCapacity;\r
+               memcpy(pData_+offset, pSrc, count*sizeof(T));\r
+       }\r
+\r
+       T* GetPtr(unsigned int offset=0) {\r
+               return (pData_+offset);\r
+       }\r
+       unsigned int GetCapacity() {\r
+               return capacity_;\r
+       }\r
+       void SetLength(unsigned int len) {\r
+               length_ = len;\r
+       }\r
+       unsigned int GetLength() {\r
+               return length_;\r
+       }\r
+\r
+       void Realloc(unsigned int neededCapacity) {\r
+               if(neededCapacity > capacity_) {\r
+                       T* pNewData = new T[neededCapacity];\r
+                       FreeData();\r
+                       pData_ = pNewData;\r
+                       capacity_ = neededCapacity;\r
+               }\r
+       }\r
+\r
+private:\r
+       void swap(const DataBuffer& b) throw()\r
+       {\r
+               std::swap(pData_, b.pData_);\r
+               std::swap(capacity_, b.capacity_);\r
+       }\r
+\r
+       void FreeData() {\r
+               if(pData_ != 0) {\r
+                       delete[] pData_;\r
+                       pData_ = 0;\r
+               }\r
+               capacity_ = 0;\r
+       }\r
+\r
+       T* pData_;\r
+       unsigned int capacity_;\r
+       unsigned int length_;\r
+};\r
+\r
+}      //namespace utils\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/utils/Event.h b/server/utils/Event.h
new file mode 100644 (file)
index 0000000..e9fbbab
--- /dev/null
@@ -0,0 +1,51 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _CASPAR_EVENT_H__\r
+#define _CASPAR_EVENT_H__\r
+\r
+#pragma once\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+class Event\r
+{\r
+public:\r
+       Event(bool bManualReset, bool bInitialState);\r
+       ~Event();\r
+\r
+       operator const HANDLE() const {\r
+               return handle_;\r
+       }\r
+\r
+       void Set();\r
+       void Reset();\r
+\r
+private:\r
+       HANDLE handle_;\r
+};\r
+\r
+typedef std::tr1::shared_ptr<Event> EventPtr;\r
+\r
+}      //namespace utils\r
+}      //namespace caspar\r
+\r
+#endif //_CASPAR_EVENT_H__
\ No newline at end of file
diff --git a/server/utils/FileExists.cpp b/server/utils/FileExists.cpp
new file mode 100644 (file)
index 0000000..bacd5e0
--- /dev/null
@@ -0,0 +1,36 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\stdafx.h"\r
+\r
+#include "FileExists.h"\r
+#include "FindWrapper.h"\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+bool exists(const tstring& name, bool isDirectory) {\r
+       WIN32_FIND_DATA findInfo;\r
+       FindWrapper findWrapper(name, &findInfo);\r
+       return findWrapper.Success() && (!isDirectory || (findInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);\r
+}\r
+\r
+}      //namespace utils\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/utils/FileExists.h b/server/utils/FileExists.h
new file mode 100644 (file)
index 0000000..379ae2b
--- /dev/null
@@ -0,0 +1,31 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#pragma once\r
+\r
+#include <string>\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+       bool exists(const tstring& name, bool isDirectory = false);\r
+\r
+}      //namespace utils\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/utils/FileInputStream.cpp b/server/utils/FileInputStream.cpp
new file mode 100644 (file)
index 0000000..f1ef0d3
--- /dev/null
@@ -0,0 +1,82 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\stdafx.h"\r
+#include "fileinputstream.h"\r
+\r
+namespace caspar {\r
+namespace utils        {\r
+\r
+FileInputStream::FileInputStream(const tstring& filename) : filename_(filename)\r
+{\r
+}\r
+\r
+FileInputStream::~FileInputStream()\r
+{\r
+       Close();\r
+}\r
+\r
+bool FileInputStream::Open()\r
+{\r
+       ifs_.open(filename_.c_str(), std::ios::in | std::ios::binary);\r
+       return !ifs_.fail();\r
+}\r
+\r
+void FileInputStream::Close()\r
+{\r
+       ifs_.close();\r
+}\r
+\r
+\r
+unsigned int FileInputStream::Read(unsigned char* buf, size_t length)\r
+{\r
+       if(!ifs_.eof())\r
+       {\r
+               ifs_.read(reinterpret_cast<char*>(buf), (std::streamsize)length);\r
+               return ifs_.gcount();\r
+       }\r
+       return 0;\r
+}\r
+\r
+/* removed 2008-03-06 - InputStream should be binary only. Make a separate TextInputStream for text\r
+bool FileInputStream::Readln(tstring& out)\r
+{\r
+       static TCHAR buf[256];\r
+       if(!ifs_.eof())\r
+       {\r
+               ifs_.getline(buf, 256, TEXT('\n'));\r
+               out = buf;\r
+               size_t findPos = out.find_first_of(TEXT('\r'));\r
+               if(findPos != tstring::npos)\r
+                       out = out.substr(0,findPos);\r
+\r
+               if(ifs_.peek() == TEXT('\r'))\r
+                       ifs_.get();\r
+               if(ifs_.peek() == TEXT('\n'))\r
+                       ifs_.get();\r
+               \r
+               return true;\r
+       }\r
+       return false;\r
+}\r
+*/\r
+\r
+}      //namespace utils\r
+}      //namespace caspar\r
diff --git a/server/utils/FileInputStream.h b/server/utils/FileInputStream.h
new file mode 100644 (file)
index 0000000..9f630d8
--- /dev/null
@@ -0,0 +1,53 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef CASPAR_FILEINPUTSTREAM_H__\r
+#define CASPAR_FILEINPUTSTREAM_H__\r
+\r
+#if _MSC_VER > 1000\r
+#pragma once\r
+#endif // _MSC_VER > 1000\r
+\r
+#include "inputstream.h"\r
+#include <fstream>\r
+\r
+namespace caspar {\r
+namespace utils        {\r
+\r
+class FileInputStream : public InputStream\r
+{\r
+public:\r
+       FileInputStream(const tstring& filename);\r
+       virtual ~FileInputStream();\r
+\r
+       virtual bool Open();\r
+\r
+       virtual unsigned int Read(unsigned char*, size_t);\r
+       virtual void Close();\r
+\r
+private:\r
+       tstring filename_;\r
+       std::ifstream   ifs_;\r
+};\r
+\r
+}      //namespace utils\r
+}      //namespace caspar\r
+\r
+#endif //CASPAR_FILEINPUTSTREAM_H__
\ No newline at end of file
diff --git a/server/utils/FileOutputStream.cpp b/server/utils/FileOutputStream.cpp
new file mode 100644 (file)
index 0000000..b31404c
--- /dev/null
@@ -0,0 +1,140 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\StdAfx.h"\r
+\r
+#include "FileOutputStream.h"\r
+#include "LogException.h"\r
+\r
+#include <time.h>\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+FileOutputStream::FileOutputStream(const TCHAR* filename, bool append) : filename(filename), append(append), timestamp(true)\r
+{\r
+       Open();\r
+}\r
+\r
+FileOutputStream::~FileOutputStream()\r
+{\r
+       Close();\r
+}\r
+\r
+bool FileOutputStream::Open()\r
+{\r
+       this->outStream.open(this->filename.c_str(), this->append ? std::ios_base::out | std::ios_base::app : std::ios_base::out | std::ios_base::trunc);\r
+       if(this->outStream.fail())\r
+               return false;\r
+\r
+       return true;\r
+}\r
+\r
+void FileOutputStream::Close()\r
+{\r
+       this->outStream.close();\r
+}\r
+\r
+void FileOutputStream::SetTimestamp(bool timestamp)\r
+{\r
+       this->timestamp = timestamp;\r
+}\r
+\r
+void FileOutputStream::WriteTimestamp()\r
+{\r
+       if (this->timestamp)\r
+       {\r
+               \r
+               TCHAR timeBuffer[30];\r
+               __time64_t ltime;\r
+               _time64(&ltime);\r
+               _tctime64_s<30>(timeBuffer, &ltime);\r
+\r
+               tstring logString = TEXT("");\r
+               logString = TEXT("[");\r
+               logString += timeBuffer;\r
+               logString.resize(logString.size()-1);\r
+               logString += TEXT("] ");\r
+\r
+               this->outStream << logString;\r
+       }\r
+}\r
+\r
+void FileOutputStream::Println(const tstring& message)\r
+{\r
+       try\r
+       {\r
+               Lock lock(*this);\r
+               if (this->timestamp)\r
+                       WriteTimestamp();\r
+\r
+               this->outStream << message <<  TEXT(" (Thread: ") << GetCurrentThreadId() << TEXT(")") << std::endl;\r
+\r
+               // HACK: Because not all unicode chars can be converted to the current locale, the above line could cause the stream to be flagged\r
+               // as beeing in a "bad"-state. just clear the state and ignore. That particular line won't be logged, but subsequent logging will work.\r
+               this->outStream.clear();\r
+               this->outStream.flush();\r
+       }\r
+       catch (LogException& ex)\r
+       {\r
+               new LogException(ex.what());\r
+       }\r
+}\r
+\r
+void FileOutputStream::Print(const tstring& message)\r
+{\r
+       try\r
+       {\r
+               Lock lock(*this);\r
+               if (this->timestamp)\r
+                       WriteTimestamp();\r
+\r
+               this->outStream << message;\r
+\r
+               // HACK: Because not all unicode chars can be converted to the current locale, the above line could cause the stream to be flagged\r
+               // as beeing in a "bad"-state. just clear the state and ignore. That particular line won't be logged, but subsequent logging will work.\r
+               this->outStream.clear();\r
+               this->outStream.flush();\r
+       }\r
+       catch (LogException& ex)\r
+       {\r
+               new LogException(ex.what());\r
+       }\r
+}\r
+\r
+void FileOutputStream::Write(const void* buffer, size_t size)\r
+{\r
+       try\r
+       {\r
+               Lock lock(*this);\r
+               if (this->timestamp)\r
+                       WriteTimestamp();\r
+\r
+               this->outStream.write((const TCHAR*)buffer, static_cast<std::streamsize>(size));\r
+               this->outStream.flush();\r
+       }\r
+       catch (LogException& ex)\r
+       {\r
+               new LogException(ex.what());\r
+       }\r
+}\r
+\r
+}\r
+}
\ No newline at end of file
diff --git a/server/utils/FileOutputStream.h b/server/utils/FileOutputStream.h
new file mode 100644 (file)
index 0000000..229b97b
--- /dev/null
@@ -0,0 +1,63 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef FILEOUTPUTSTREAM_H\r
+#define FILEOUTPUTSTREAM_H\r
+\r
+#include "OutputStream.h"\r
+\r
+#include <string>\r
+#include <fstream>\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+class FileOutputStream : public OutputStream, private LockableObject\r
+{\r
+       public:\r
+               FileOutputStream(const TCHAR* filename, bool bAppend = false);\r
+               virtual ~FileOutputStream();\r
+\r
+               virtual bool Open();\r
+               virtual void Close();\r
+               virtual void SetTimestamp(bool timestamp);\r
+               virtual void Print(const tstring& message);\r
+               virtual void Println(const tstring& message);\r
+               virtual void Write(const void* buffer, size_t);\r
+\r
+       private:\r
+               void WriteTimestamp();\r
+\r
+       private:\r
+               bool append;\r
+               bool timestamp;\r
+               tstring filename;\r
+       \r
+               #ifndef _UNICODE\r
+                       std::ofstream   outStream;\r
+               #else\r
+                       std::wofstream  outStream;\r
+               #endif\r
+};\r
+\r
+}\r
+}\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/utils/FindWrapper.cpp b/server/utils/FindWrapper.cpp
new file mode 100644 (file)
index 0000000..503fc98
--- /dev/null
@@ -0,0 +1,45 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\stdafx.h"\r
+\r
+#include "FindWrapper.h"\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+       FindWrapper::FindWrapper(const tstring& filename, WIN32_FIND_DATA* pFindData) : hFile_(INVALID_HANDLE_VALUE) {\r
+               hFile_ = FindFirstFile(filename.c_str(), pFindData);\r
+       }\r
+\r
+       FindWrapper::~FindWrapper() {\r
+               if(hFile_ != INVALID_HANDLE_VALUE) {\r
+                       FindClose(hFile_);\r
+                       hFile_ = INVALID_HANDLE_VALUE;\r
+               }\r
+       }\r
+\r
+       bool FindWrapper::FindNext(WIN32_FIND_DATA* pFindData)\r
+       {\r
+               return FindNextFile(hFile_, pFindData) != 0;\r
+       }\r
+\r
+}      //namespace utils\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/utils/FindWrapper.h b/server/utils/FindWrapper.h
new file mode 100644 (file)
index 0000000..b7aff19
--- /dev/null
@@ -0,0 +1,51 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _FINDWRAPPER_H__\r
+#define _FINDWRAPPER_H__\r
+\r
+#include <io.h>\r
+#include <string>\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+       class FindWrapper\r
+       {\r
+               FindWrapper(const FindWrapper&);\r
+               FindWrapper& operator=(const FindWrapper&);\r
+       public:\r
+               FindWrapper(const tstring&, WIN32_FIND_DATA*);\r
+               ~FindWrapper();\r
+\r
+               bool FindNext(WIN32_FIND_DATA*);\r
+\r
+               bool Success() {\r
+                       return (hFile_ != INVALID_HANDLE_VALUE);\r
+               }\r
+\r
+       private:\r
+               HANDLE  hFile_;\r
+       };\r
+\r
+}      //namespace utils\r
+}      //namespace caspar\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/utils/ID.cpp b/server/utils/ID.cpp
new file mode 100644 (file)
index 0000000..fbf56c4
--- /dev/null
@@ -0,0 +1,63 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "stdafx.h"\r
+#include "ID.h"\r
+\r
+namespace caspar\r
+{\r
+       namespace utils\r
+       {\r
+\r
+               ID::ID() : value_(0){}\r
+\r
+               const ID::value_type& ID::Value() const\r
+               {\r
+                       return value_;\r
+               }\r
+               ID ID::Generate(void* ptr)\r
+               {                       \r
+                       assert(sizeof(value_type) >= sizeof(LARGE_INTEGER));\r
+                       ID id;\r
+                       QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER*>(&id.value_));  \r
+                       id.value_ <<= 32;\r
+                       id.value_ |= reinterpret_cast<int>(ptr);\r
+                       return id;\r
+               }\r
+\r
+               bool operator ==(const ID& lhs,const ID& rhs)\r
+               {\r
+                       return lhs.Value() == rhs.Value();\r
+               }\r
+\r
+               bool operator !=(const ID& lhs,const ID& rhs)\r
+               {\r
+                       return lhs.Value() != rhs.Value();\r
+               }\r
+\r
+               Identifiable::Identifiable() : id_(utils::ID::Generate(this))\r
+               {}\r
+\r
+               const utils::ID& Identifiable::ID() const\r
+               {\r
+                       return id_;\r
+               }\r
+       }\r
+}
\ No newline at end of file
diff --git a/server/utils/ID.h b/server/utils/ID.h
new file mode 100644 (file)
index 0000000..bee7e30
--- /dev/null
@@ -0,0 +1,55 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _ID_H_\r
+#define _ID_H_\r
+\r
+namespace caspar\r
+{\r
+       namespace utils\r
+       {\r
+               class ID \r
+               {                       \r
+               public:\r
+                       typedef long long value_type;\r
+\r
+                       ID();\r
+                       const value_type& Value() const;\r
+                       static ID Generate(void* ptr);\r
+               private:\r
+                       value_type value_; \r
+               };\r
+\r
+               class Identifiable\r
+               {\r
+               public:\r
+                       Identifiable();\r
+                       virtual ~Identifiable(){}\r
+                       const utils::ID& ID() const;\r
+               private:\r
+                       const utils::ID id_;\r
+               };\r
+\r
+               bool operator==(const ID& lhs,const ID& rhs);\r
+               bool operator!=(const ID& lhs,const ID& rhs);\r
+       }\r
+}\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/utils/InputStream.h b/server/utils/InputStream.h
new file mode 100644 (file)
index 0000000..fa9959e
--- /dev/null
@@ -0,0 +1,63 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef CASPAR_INPUTSTREAM_H__\r
+#define CASPAR_INPUTSTREAM_H__\r
+\r
+#if _MSC_VER > 1000\r
+#pragma once\r
+#endif // _MSC_VER > 1000\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+class InputStream\r
+{\r
+public:\r
+       virtual ~InputStream() {}\r
+\r
+       virtual bool Open() = 0;\r
+       virtual unsigned int Read(unsigned char*, size_t) = 0;\r
+       virtual void Close() = 0;\r
+};\r
+typedef std::tr1::shared_ptr<InputStream> InputStreamPtr;\r
+\r
+template <typename CharType>\r
+class TextInputStream\r
+{\r
+public:\r
+       virtual ~TextInputStream() {}\r
+\r
+       virtual bool Open() = 0;\r
+       virtual bool Readln(std::basic_string<CharType>&) = 0;\r
+       virtual unsigned int Read(CharType*, size_t) = 0;\r
+       virtual void Close() = 0;\r
+};\r
+\r
+#ifdef UNICODE\r
+       typedef std::tr1::shared_ptr<TextInputStream<wchar_t> > TextInputStreamPtr;\r
+#else\r
+       typedef std::tr1::shared_ptr<TextInputStream<char> > TextInputStreamPtr;\r
+#endif\r
+\r
+}      //namespace utils\r
+}      //namespace caspar\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/utils/Lockable.h b/server/utils/Lockable.h
new file mode 100644 (file)
index 0000000..e54183d
--- /dev/null
@@ -0,0 +1,74 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _CASPAR_LOCKABLE_H__\r
+#define _CASPAR_LOCKABLE_H__\r
+\r
+#pragma once\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+class LockableObject\r
+{\r
+       mutable CRITICAL_SECTION mtx_;\r
+\r
+       LockableObject(const LockableObject&);\r
+       LockableObject& operator=(const LockableObject&);\r
+\r
+protected:\r
+       LockableObject(unsigned int spincount = 4000)\r
+       {\r
+               ::InitializeCriticalSectionAndSpinCount(&mtx_, spincount);\r
+       }\r
+\r
+public:\r
+       ~LockableObject()\r
+       {\r
+               ::DeleteCriticalSection(&mtx_);\r
+       }\r
+\r
+       class Lock;\r
+       friend class Lock;\r
+\r
+       class Lock\r
+       {\r
+               LockableObject const& host_;\r
+\r
+               Lock(const Lock&);\r
+               Lock& operator=(const Lock&);\r
+\r
+       public:\r
+               explicit Lock(const LockableObject& host) : host_(host)\r
+               {\r
+                       ::EnterCriticalSection(&host_.mtx_);\r
+               }\r
+\r
+               ~Lock()\r
+               {\r
+                       ::LeaveCriticalSection(&host_.mtx_);\r
+               }\r
+       };\r
+};\r
+\r
+}      //namespace utils\r
+}      //namespace caspar\r
+\r
+#endif //_CASPAR_LOCKABLE_H__
\ No newline at end of file
diff --git a/server/utils/LogException.cpp b/server/utils/LogException.cpp
new file mode 100644 (file)
index 0000000..5ff4613
--- /dev/null
@@ -0,0 +1,42 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\StdAfx.h"\r
+\r
+#include "LogException.h"\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+LogException::LogException(const char* message) : std::runtime_error(message)\r
+{\r
+}\r
+\r
+LogException::~LogException()\r
+{\r
+}\r
+\r
+const char* LogException::GetMassage() const\r
+{\r
+       return std::runtime_error::what();\r
+}\r
+\r
+}\r
+}
\ No newline at end of file
diff --git a/server/utils/LogException.h b/server/utils/LogException.h
new file mode 100644 (file)
index 0000000..9da52be
--- /dev/null
@@ -0,0 +1,39 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef LOGEXCEPTION_H\r
+#define LOGEXCEPTION_H\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+class LogException : public std::runtime_error\r
+{\r
+       public:\r
+               explicit LogException(const char* message = "Caught exception while logging");\r
+               ~LogException();\r
+\r
+               const char* GetMassage() const;\r
+};\r
+\r
+}\r
+}\r
+\r
+#endif\r
diff --git a/server/utils/LogLevel.h b/server/utils/LogLevel.h
new file mode 100644 (file)
index 0000000..a04ac05
--- /dev/null
@@ -0,0 +1,41 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef LOGLEVEL_H\r
+#define LOGLEVEL_H\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+struct LogLevel\r
+{\r
+       enum LogLevelEnum\r
+       {\r
+               Debug = 1,\r
+               Verbose,\r
+               Release,\r
+               Critical\r
+       };\r
+};\r
+\r
+}\r
+}\r
+\r
+#endif\r
diff --git a/server/utils/LogStream.cpp b/server/utils/LogStream.cpp
new file mode 100644 (file)
index 0000000..1c9b4fb
--- /dev/null
@@ -0,0 +1,68 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\StdAfx.h"\r
+#include "LogStream.h"\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+LogStream::LogStream(Logger* pLogger) : pLogger(pLogger), pSstream(0)\r
+{\r
+}\r
+\r
+LogStream::LogStream(const LogStream& logStream) : pSstream(0),\r
+                                                                                                  pLogger(logStream.pLogger), level(logStream.level)\r
+{\r
+       if(logStream.pSstream != 0)\r
+               this->pSstream = new tstringstream(logStream.pSstream->str());\r
+}\r
+\r
+LogStream& LogStream::operator=(const LogStream& rhs)\r
+{\r
+       if(rhs.pSstream != 0)\r
+               this->pSstream = new tstringstream(rhs.pSstream->str());\r
+\r
+       this->pLogger = rhs.pLogger;\r
+       this->level = rhs.level;\r
+\r
+       return *this;\r
+}\r
+\r
+LogStream::~LogStream()\r
+{\r
+       if (this->pSstream != NULL)\r
+       {\r
+               DoFlush();\r
+               delete this->pSstream;\r
+       }\r
+}\r
+\r
+void LogStream::DoFlush()\r
+{\r
+       if(this->pSstream != 0 && this->pSstream->str().length() > 0)\r
+       {\r
+               this->pLogger->WriteLog(this->pSstream->str());\r
+               this->pSstream->str(TEXT(""));\r
+       }\r
+}\r
+\r
+}\r
+}
\ No newline at end of file
diff --git a/server/utils/LogStream.h b/server/utils/LogStream.h
new file mode 100644 (file)
index 0000000..93fada4
--- /dev/null
@@ -0,0 +1,76 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef LOGSTREAM_H\r
+#define LOGSTREAM_H\r
+\r
+#include "LogLevel.h"\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+class Logger;\r
+\r
+class LogStream\r
+{\r
+       public:\r
+               enum LogStreamEnum { Flush = 1 };\r
+\r
+               explicit LogStream(Logger* pLogger);\r
+               LogStream(const LogStream& logStream);\r
+               LogStream& operator=(const LogStream& rhs);\r
+\r
+               ~LogStream();\r
+\r
+               template<typename T>\r
+               LogStream& operator<<(const T& rhs) {\r
+                       if (this->level >= this->pLogger->GetLevel()) {\r
+                               if(this->pSstream == 0)\r
+                                       this->pSstream = new tstringstream();\r
+\r
+                               *pSstream << rhs;\r
+                       }\r
+\r
+                       return *this;\r
+               }\r
+\r
+               template<> LogStream& operator<<(const LogLevel::LogLevelEnum& rhs) {\r
+                       this->level = rhs;\r
+                       return *this;\r
+               }\r
+\r
+               template<> LogStream& operator<<(const LogStream::LogStreamEnum& rhs) {\r
+                       if (rhs == LogStream::Flush)\r
+                               DoFlush();\r
+                       return *this;\r
+               }\r
+\r
+       private:\r
+               void DoFlush();\r
+\r
+               Logger* pLogger;\r
+               tstringstream* pSstream;\r
+               LogLevel::LogLevelEnum level;\r
+};\r
+\r
+}\r
+}\r
+\r
+#endif\r
diff --git a/server/utils/Logger.cpp b/server/utils/Logger.cpp
new file mode 100644 (file)
index 0000000..404b7c9
--- /dev/null
@@ -0,0 +1,101 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\StdAfx.h"\r
+\r
+#include "Logger.h"\r
+#include "LogException.h"\r
+#include "LogStream.h"\r
+#include "OutputStream.h"\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+Logger::Logger() : level(LogLevel::Release)\r
+{\r
+}\r
+\r
+Logger::~Logger()\r
+{\r
+}\r
+\r
+Logger& Logger::GetInstance()\r
+{\r
+       static Logger logger;\r
+       return logger;\r
+}\r
+\r
+LogStream Logger::GetStream(LogLevel::LogLevelEnum level)\r
+{\r
+       LogStream logStream(this);\r
+       logStream << level;\r
+       return logStream;\r
+}\r
+\r
+void Logger::WriteLog(const tstring& message)\r
+{\r
+       try\r
+       {\r
+               this->pOutputStream->Println(message);\r
+       }\r
+       catch(const std::exception& ex)\r
+       {\r
+               throw LogException(ex.what());\r
+       }\r
+}\r
+\r
+void Logger::SetTimestamp(bool timestamp)\r
+{\r
+       if (pOutputStream != NULL)\r
+               this->pOutputStream->SetTimestamp(timestamp);\r
+}\r
+\r
+bool Logger::SetOutputStream(OutputStreamPtr pOutputStream)\r
+{\r
+       try\r
+       {\r
+               if (pOutputStream != NULL)\r
+               {\r
+                       Lock lock(*this);\r
+                       this->pOutputStream = pOutputStream;\r
+\r
+                       return true;\r
+               }\r
+\r
+               return false;\r
+       }\r
+       catch(const std::exception& ex)\r
+       {\r
+               throw LogException(ex.what());\r
+       }\r
+}\r
+\r
+LogLevel::LogLevelEnum Logger::GetLevel()\r
+{\r
+       return this->level;\r
+}\r
+\r
+void Logger::SetLevel(LogLevel::LogLevelEnum level)\r
+{\r
+       this->level = level;\r
+}\r
+\r
+}\r
+}
\ No newline at end of file
diff --git a/server/utils/Logger.h b/server/utils/Logger.h
new file mode 100644 (file)
index 0000000..50e16d7
--- /dev/null
@@ -0,0 +1,57 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef LOGGER_H\r
+#define LOGGER_H\r
+\r
+#include "Lockable.h"\r
+#include "LogStream.h"\r
+#include "LogLevel.h"\r
+#include "OutputStream.h"\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+class Logger : private LockableObject\r
+{\r
+       public:\r
+               ~Logger();\r
+\r
+               static Logger& GetInstance();\r
+               \r
+               LogLevel::LogLevelEnum GetLevel();\r
+               void SetTimestamp(bool timestamp);\r
+               void WriteLog(const tstring& message);\r
+               void SetLevel(LogLevel::LogLevelEnum Level);\r
+               bool SetOutputStream(OutputStreamPtr pOutputStream);\r
+               LogStream GetStream(LogLevel::LogLevelEnum level = LogLevel::Release);\r
+\r
+       private:\r
+               Logger();\r
+\r
+       private:\r
+               OutputStreamPtr pOutputStream;\r
+               LogLevel::LogLevelEnum level;\r
+};\r
+\r
+}\r
+}\r
+\r
+#endif\r
diff --git a/server/utils/Noncopyable.hpp b/server/utils/Noncopyable.hpp
new file mode 100644 (file)
index 0000000..83a9299
--- /dev/null
@@ -0,0 +1,40 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef __NONCOPYABLE_H__\r
+#define __NONCOPYABLE_H__\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+class Noncopyable\r
+{\r
+protected:\r
+       Noncopyable() {}\r
+       ~Noncopyable() {}\r
+private:\r
+       Noncopyable( const Noncopyable& );\r
+       const Noncopyable& operator=( const Noncopyable& );\r
+};\r
+\r
+} // namespace utils\r
+} //namespace caspar\r
+\r
+#endif __NONCOPYABLE_H__
\ No newline at end of file
diff --git a/server/utils/ObjectPool.h b/server/utils/ObjectPool.h
new file mode 100644 (file)
index 0000000..30cf2b9
--- /dev/null
@@ -0,0 +1,87 @@
+#ifndef _OBJECTPOOL_H_\r
+#define _OBJECTPOOL_H_\r
+\r
+#include <functional>\r
+#include <memory>\r
+#include <type_traits>\r
+\r
+#include <tbb/concurrent_queue.h>\r
+\r
+namespace caspar\r
+{\r
+\r
+namespace utils\r
+{\r
+\r
+template<typename T, typename Factory = std::function<T*()>, typename PoolType = tbb::concurrent_queue<T*>>\r
+class ObjectPool\r
+{\r
+       static_assert(std::tr1::is_reference<T>::value == false, "Object type cannot be reference type");\r
+public:\r
+       typedef std::shared_ptr<PoolType> PoolTypePtr;\r
+\r
+       ObjectPool(const Factory& factory, const std::function<void(T*)>& destructor) : factory_(factory)\r
+       {\r
+               pPool_ = PoolTypePtr(new PoolType(), [=](PoolType* pPool)\r
+                       {\r
+                               T* pItem;\r
+                               while(pPool->try_pop(pItem))\r
+                                       destructor(pItem);\r
+                               delete pPool;\r
+                       });\r
+       }\r
+\r
+       ObjectPool(Factory&& factory, std::function<void(T*)>&& destructor)     : factory_(std::move(factory))\r
+       {\r
+               pPool_ = PoolTypePtr(new PoolType(), [=](PoolType* pPool)\r
+                       {\r
+                               T* pItem;\r
+                               while(pPool->try_pop(pItem))\r
+                                       destructor(pItem);\r
+                               delete pPool;\r
+                       });\r
+       }\r
+\r
+       std::shared_ptr<T> Create()\r
+       {\r
+               T* pItem = pPool_->try_pop(pItem) ? pItem : factory_();\r
+               return std::shared_ptr<T>(pItem, [=](T* item){ pPool_->push(item); });\r
+       }\r
+\r
+       template<typename P0>\r
+       std::shared_ptr<T> Create(P0&& p0)\r
+       {\r
+               T* pItem = pPool_->try_pop(pItem) ? pItem : factory_(std::forward<P0>(p0));\r
+               return std::shared_ptr<T>(pItem, [=](T* item){ pPool_->push(item); });\r
+       }\r
+\r
+       template<typename P0, typename P1>\r
+       std::shared_ptr<T> Create(P0&& p0, P1&& p1)\r
+       {\r
+               T* pItem = pPool_->try_pop(pItem) ? pItem : factory_(std::forward<P0>(p0), std::forward<P1>(p1));\r
+               return std::shared_ptr<T>(pItem, [=](T* item){ pPool_->push(item); });\r
+       }       \r
+\r
+       template<typename P0, typename P1, typename P2>\r
+       std::shared_ptr<T> Create(P0&& p0, P1&& p1, P2&& p2)\r
+       {\r
+               T* pItem = pPool_->try_pop(pItem) ? pItem : factory_(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2));\r
+               return std::shared_ptr<T>(pItem, [=](T* item){ pPool_->push(item); });\r
+       }\r
+\r
+       template<typename P0, typename P1, typename P2, typename P3>\r
+       std::shared_ptr<T> Create(P0&& p0, P1&& p1, P2&& p2, P3&& p3)\r
+       {\r
+               T* pItem = pPool_->try_pop(pItem) ? pItem : factory_(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2), std::forward<P3>(p3));\r
+               return std::shared_ptr<T>(pItem, [=](T* item){ pPool_->push(item); });\r
+       }\r
+\r
+private:\r
+       PoolTypePtr pPool_;\r
+       const Factory factory_;\r
+};\r
+\r
+}\r
+}\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/utils/OutputStream.h b/server/utils/OutputStream.h
new file mode 100644 (file)
index 0000000..8766eaa
--- /dev/null
@@ -0,0 +1,45 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef OUTPUTSTREAM_H\r
+#define OUTPUTSTREAM_H\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+class OutputStream\r
+{\r
+       public:\r
+               virtual ~OutputStream() {}\r
+\r
+               virtual bool Open() = 0;\r
+               virtual void Close() = 0;\r
+               virtual void SetTimestamp(bool timestamp) = 0;\r
+               virtual void Write(const void*, size_t) = 0;\r
+               virtual void Print(const tstring& message) = 0;\r
+               virtual void Println(const tstring& message) = 0;\r
+};\r
+\r
+typedef std::tr1::shared_ptr<OutputStream> OutputStreamPtr;\r
+\r
+}\r
+}\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/utils/PixmapData.h b/server/utils/PixmapData.h
new file mode 100644 (file)
index 0000000..8a1731f
--- /dev/null
@@ -0,0 +1,85 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef __IMAGEDATA_H__\r
+#define __IMAGEDATA_H__\r
+\r
+#include <memory>\r
+\r
+#if _MSC_VER > 1000\r
+#pragma once\r
+#endif // _MSC_VER > 1000\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+class PixmapData\r
+{\r
+       PixmapData(const PixmapData&);\r
+       PixmapData& operator=(const PixmapData&);\r
+\r
+public:\r
+       PixmapData() : height(0), width(0), bpp(0), pData_(0) \r
+       {}\r
+       PixmapData(int w, int h, int b) : width(w), height(h), bpp(b), pData_(new unsigned char[w*h*b])\r
+       {}\r
+\r
+       ~PixmapData() {\r
+               Clear();\r
+       }\r
+\r
+       void Set(int w, int h, int b) {\r
+               Clear();\r
+               width = w;\r
+               height = h;\r
+               bpp = b;\r
+               pData_ = new unsigned char[w*h*b];\r
+       }\r
+\r
+       void Clear() {\r
+               height = 0;\r
+               width = 0;\r
+               bpp = 0;\r
+\r
+               if(pData_ != 0)\r
+               {\r
+                       delete[] pData_;\r
+                       pData_ = 0;\r
+               }\r
+       }\r
+\r
+       unsigned char* GetDataPtr() {\r
+               return pData_;\r
+       }\r
+\r
+       int height;\r
+       int width;\r
+       int bpp;\r
+\r
+private:\r
+       unsigned char *pData_;\r
+};\r
+\r
+typedef std::tr1::shared_ptr<PixmapData> PixmapDataPtr;\r
+\r
+}      //namespace utils\r
+}      //namespace caspar\r
+\r
+#endif //__IMAGEDATA_H__\r
diff --git a/server/utils/Process.cpp b/server/utils/Process.cpp
new file mode 100644 (file)
index 0000000..4bc40ac
--- /dev/null
@@ -0,0 +1,43 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\StdAfx.h"\r
+#include "Process.h"\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+Process::Process()\r
+{\r
+       hProcess_ = ::GetCurrentProcess();\r
+}\r
+\r
+bool Process::SetWorkingSetSize(SIZE_T minSize, SIZE_T maxSize) \r
+{\r
+       return (::SetProcessWorkingSetSize(hProcess_, minSize, maxSize) != 0);\r
+}\r
+\r
+bool Process::GetWorkingSetSize(SIZE_T& minSize, SIZE_T& maxSize) \r
+{\r
+       return (::GetProcessWorkingSetSize(hProcess_, &minSize, &maxSize) != 0);\r
+}\r
+\r
+}\r
+}
\ No newline at end of file
diff --git a/server/utils/Process.h b/server/utils/Process.h
new file mode 100644 (file)
index 0000000..ad51295
--- /dev/null
@@ -0,0 +1,50 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _CASPARUTILS_PROCESS_H__\r
+#define _CASPARUTILS_PROCESS_H__\r
+\r
+#pragma once\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+class Process\r
+{\r
+       Process();\r
+       Process(const Process&);\r
+       Process& operator=(const Process&);\r
+\r
+public:\r
+       static Process& GetCurrentProcess() {\r
+               static Process instance;\r
+               return instance;\r
+       }\r
+\r
+       bool SetWorkingSetSize(SIZE_T minSize, SIZE_T maxSize);\r
+       bool GetWorkingSetSize(SIZE_T& minSize, SIZE_T& maxSize);\r
+\r
+private:\r
+       HANDLE hProcess_;\r
+};\r
+\r
+}      //namespace utils\r
+}      //namespace caspar\r
+#endif //_CASPARUTILS_PROCESS_H__
\ No newline at end of file
diff --git a/server/utils/Semaphore.cpp b/server/utils/Semaphore.cpp
new file mode 100644 (file)
index 0000000..035913b
--- /dev/null
@@ -0,0 +1,45 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\StdAfx.h"\r
+\r
+#include "Semaphore.h"\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+Semaphore::Semaphore(long initialCount, long maximumCount) : handle_(0)\r
+{\r
+       handle_ = CreateSemaphore(0, initialCount, maximumCount, 0);\r
+       if(handle_ == 0) {\r
+               throw std::exception("Failed to create semaphore");\r
+       }\r
+}\r
+bool Semaphore::Release(long releaseCount, long* pPrevCount) {\r
+       return ReleaseSemaphore(handle_, releaseCount, pPrevCount) != 0;\r
+}\r
+\r
+Semaphore::~Semaphore()\r
+{\r
+       CloseHandle(handle_);\r
+}\r
+\r
+}      //namespace utils\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/utils/Semaphore.h b/server/utils/Semaphore.h
new file mode 100644 (file)
index 0000000..7f13931
--- /dev/null
@@ -0,0 +1,50 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _CSAPAR_SEMAPHORE_H__\r
+#define _CASPAR_SEMAPHORE_H__\r
+\r
+#pragma once\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+class Semaphore\r
+{\r
+public:\r
+       Semaphore(long initialCount, long maximumCount);\r
+       ~Semaphore();\r
+\r
+       bool Semaphore::Release(long releaseCount = 1, long* pPrevCount = 0);\r
+\r
+       operator const HANDLE() const {\r
+               return handle_;\r
+       }\r
+\r
+private:\r
+       HANDLE handle_;\r
+};\r
+\r
+typedef std::tr1::shared_ptr<Semaphore> SemaphorePtr;\r
+\r
+}      //namespace utils\r
+}      //namespace caspar\r
+\r
+#endif //_CASPAR_SEMAPHORE_H__
\ No newline at end of file
diff --git a/server/utils/TaskQueue.h b/server/utils/TaskQueue.h
new file mode 100644 (file)
index 0000000..157cb64
--- /dev/null
@@ -0,0 +1,74 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _CASPAR_TASKQUEUE_H__\r
+#define _CASPAR_TASKQUEUE_H__\r
+\r
+#pragma once\r
+#include <functional>\r
+#include "lockable.h"\r
+#include "noncopyable.hpp"\r
+#include "event.h"\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+typedef std::tr1::function<void()> Task;\r
+class TaskQueue : private utils::LockableObject, private utils::Noncopyable {\r
+public:\r
+       TaskQueue() : waitEvent_(TRUE, FALSE) {}\r
+       ~TaskQueue() {}\r
+       void push_back(const Task& task) {\r
+               Lock lock(*this);\r
+               taskList_.push_back(task);\r
+               waitEvent_.Set();\r
+       }\r
+\r
+       void pop_front(Task& dest) {\r
+               Lock lock(*this);\r
+               if(taskList_.size() > 0) {\r
+                       dest = taskList_.front();\r
+\r
+                       taskList_.pop_front();\r
+                       if(taskList_.empty())\r
+                               waitEvent_.Reset();\r
+               }\r
+       }\r
+\r
+       void pop_and_execute_front() {\r
+               Task task;\r
+               pop_front(task);\r
+               if(task)\r
+                       task();\r
+       }\r
+\r
+       HANDLE GetWaitEvent() {\r
+               return waitEvent_;\r
+       }\r
+private:\r
+       utils::Event waitEvent_;\r
+       std::list<Task> taskList_;\r
+};\r
+\r
+\r
+}      //namespace utils\r
+}      //namespace caspar\r
+\r
+#endif //_CASPAR_TASKQUEUE_H__
\ No newline at end of file
diff --git a/server/utils/Thread.cpp b/server/utils/Thread.cpp
new file mode 100644 (file)
index 0000000..7a257da
--- /dev/null
@@ -0,0 +1,123 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\StdAfx.h"\r
+\r
+#include "thread.h"\r
+#include "win32exception.h"\r
+\r
+/*\r
+\r
+*/\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+bool Thread::static_bInstallWin32ExceptionHandler_ = true;\r
+\r
+Thread::Thread() : pRunnable_(0), hThread_(0), stopEvent_(TRUE, FALSE), timeout_(10000)  {\r
+}\r
+\r
+Thread::~Thread() {\r
+       Stop();\r
+}\r
+\r
+bool Thread::IsRunning() {\r
+       if(hThread_ != 0) {\r
+               if(WaitForSingleObject(hThread_, 0) == WAIT_OBJECT_0) {\r
+                       CloseHandle(hThread_);\r
+                       hThread_ = 0;\r
+                       pRunnable_ = 0;\r
+               }\r
+       }\r
+\r
+       return (hThread_ != 0);\r
+}\r
+\r
+bool Thread::Start(IRunnable* pRunnable) {\r
+       if(hThread_ == 0) {\r
+               if(pRunnable != 0) {\r
+                       pRunnable_ = pRunnable;\r
+                       stopEvent_.Reset();\r
+                       hThread_ = CreateThread(0, 0, ThreadEntrypoint, this, 0, 0);\r
+\r
+                       if(hThread_ == 0)\r
+                               pRunnable_ = 0;\r
+\r
+                       return (hThread_ != 0);\r
+               }\r
+       }\r
+       return false;\r
+}\r
+\r
+bool Thread::Stop(bool bWait) {\r
+       bool returnValue = true;\r
+\r
+       if(hThread_ != 0) {\r
+               stopEvent_.Set();\r
+\r
+               if(bWait) {\r
+                       DWORD successCode = WaitForSingleObject(hThread_, timeout_);\r
+                       if(successCode != WAIT_OBJECT_0)\r
+                               returnValue = false;\r
+               }\r
+               CloseHandle(hThread_);\r
+\r
+               hThread_ = 0;\r
+               pRunnable_ = 0;\r
+       }\r
+\r
+       return returnValue;\r
+}\r
+\r
+void Thread::EnableWin32ExceptionHandler(bool bEnable) {\r
+       static_bInstallWin32ExceptionHandler_ = bEnable;\r
+}\r
+\r
+DWORD WINAPI Thread::ThreadEntrypoint(LPVOID pParam) {\r
+       Thread* pThis = reinterpret_cast<Thread*>(pParam);\r
+       \r
+       if(Thread::static_bInstallWin32ExceptionHandler_)\r
+               Win32Exception::InstallHandler();\r
+\r
+       _configthreadlocale(_DISABLE_PER_THREAD_LOCALE);\r
+\r
+       pThis->Run();\r
+\r
+       return 0;\r
+}\r
+\r
+void Thread::Run() {\r
+       bool bDoRestart = false;\r
+\r
+       do {\r
+               try {\r
+                       bDoRestart = false;\r
+                       stopEvent_.Reset();\r
+                       pRunnable_->Run(stopEvent_);\r
+               }\r
+               catch(const std::exception& e) {\r
+                       bDoRestart = pRunnable_->OnUnhandledException(e);\r
+               }\r
+       }while(bDoRestart);\r
+}\r
+\r
+}      //namespace utils\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/utils/Thread.h b/server/utils/Thread.h
new file mode 100644 (file)
index 0000000..162914e
--- /dev/null
@@ -0,0 +1,71 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _CASPAR_THREAD_H__\r
+#define _CASPAR_THREAD_H__\r
+\r
+#pragma once\r
+\r
+#include "runnable.h"\r
+#include "event.h"\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+class Thread\r
+{\r
+       Thread(const Thread&);\r
+       Thread& operator=(const Thread&);\r
+public:\r
+       Thread();\r
+       ~Thread();\r
+\r
+       bool Start(IRunnable*);\r
+       bool Stop(bool bWait = true);\r
+\r
+       bool IsRunning();\r
+\r
+       static void EnableWin32ExceptionHandler(bool bEnable);\r
+\r
+       void SetTimeout(DWORD timeout) {\r
+               timeout_ = timeout;\r
+       }\r
+       DWORD GetTimeout() {\r
+               return timeout_;\r
+       }\r
+\r
+private:\r
+       static DWORD WINAPI ThreadEntrypoint(LPVOID pParam);\r
+       void Run();\r
+\r
+       HANDLE                  hThread_;\r
+       IRunnable*              pRunnable_;\r
+\r
+       Event                   stopEvent_;\r
+\r
+       DWORD                   timeout_;\r
+       static bool             static_bInstallWin32ExceptionHandler_;\r
+};\r
+\r
+}      //namespace utils\r
+}      //namespace caspar\r
+\r
+\r
+#endif //_CASPAR_THREAD_H__\r
diff --git a/server/utils/Types.hpp b/server/utils/Types.hpp
new file mode 100644 (file)
index 0000000..4f63a6e
--- /dev/null
@@ -0,0 +1,33 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _TYPES_H_\r
+#define _TYPES_H_\r
+\r
+typedef unsigned char  u8;\r
+typedef char                   s8;\r
+\r
+typedef unsigned short u16;\r
+typedef short                  s16;\r
+\r
+typedef unsigned int   u32;\r
+typedef int                            s32;\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/utils/UnhandledException.h b/server/utils/UnhandledException.h
new file mode 100644 (file)
index 0000000..7484619
--- /dev/null
@@ -0,0 +1,146 @@
+#ifndef _UNHANDLED_EXCEPTION_H_\r
+#define _UNHANDLED_EXCEPTION_H_\r
+\r
+#include <exception>\r
+#include <system_error>\r
+#include <string>\r
+\r
+#include "Logger.h"\r
+#include "LogLevel.h"\r
+#include "Win32Exception.h"\r
+\r
+#define CASPAR_TRY try\r
+#define CASPAR_CATCH_UNHANDLED(desc) \\r
+               catch(std::system_error& er)    \\r
+               {       \\r
+                       try     \\r
+                       {       \\r
+                               LOG << caspar::utils::LogLevel::Critical << desc << TEXT(" UNHANDLED EXCEPTION Message:")  << er.code().message().c_str();      \\r
+                       }       \\r
+                       catch(...){}    \\r
+               }       \\r
+               catch(std::exception& ex)       \\r
+               {       \\r
+                       try     \\r
+                       {       \\r
+                               LOG << caspar::utils::LogLevel::Critical << desc << TEXT(" UNHANDLED EXCEPTION Message:")  << ex.what();        \\r
+                       }       \\r
+                       catch(...){}    \\r
+               }       \\r
+               catch(...)      \\r
+               {       \\r
+                       try     \\r
+                       {       \\r
+                               LOG << caspar::utils::LogLevel::Critical << desc << TEXT(" UNHANDLED EXCEPTION");       \\r
+                       }       \\r
+                       catch(...){}    \\r
+               }\r
+\r
+#define CASPAR_RETHROW_AND_LOG(desc) \\r
+               catch(std::system_error& er)    \\r
+               {       \\r
+                       try     \\r
+                       {       \\r
+                               LOG << caspar::utils::LogLevel::Critical << desc << TEXT(" Message:") << er.code().message().c_str();   \\r
+                       }       \\r
+                       catch(...){}    \\r
+                       throw;\\r
+               }       \\r
+               catch(std::exception& ex)       \\r
+               {       \\r
+                       try     \\r
+                       {       \\r
+                               LOG << caspar::utils::LogLevel::Critical << desc << TEXT(" Message:") << ex.what();     \\r
+                       }       \\r
+                       catch(...){}    \\r
+                       throw;\\r
+               }       \\r
+               catch(...)      \\r
+               {       \\r
+                       try     \\r
+                       {       \\r
+                               LOG << caspar::utils::LogLevel::Critical << desc;       \\r
+                       }       \\r
+                       catch(...){}    \\r
+                       throw;\\r
+               }\r
+\r
+#define CASPAR_CATCH_AND_LOG(desc) \\r
+               catch(std::system_error& er)    \\r
+               {       \\r
+                       try     \\r
+                       {       \\r
+                               LOG << caspar::utils::LogLevel::Critical << desc << TEXT(" Message:") << er.code().message().c_str();   \\r
+                       }       \\r
+                       catch(...){}    \\r
+               }       \\r
+               catch(std::exception& ex)       \\r
+               {       \\r
+                       try     \\r
+                       {       \\r
+                               LOG << caspar::utils::LogLevel::Critical << desc << TEXT(" Message:") << ex.what();     \\r
+                       }       \\r
+                       catch(...){}    \\r
+               }       \\r
+               catch(...)      \\r
+               {       \\r
+                       try     \\r
+                       {       \\r
+                               LOG << caspar::utils::LogLevel::Critical << desc;       \\r
+                       }       \\r
+                       catch(...){}    \\r
+               }\r
+\r
+template<typename F>\r
+void CASPAR_THREAD_GUARD(const wchar_t* desc, const F& func)   \r
+{\r
+       CASPAR_THREAD_GUARD(0, desc, func);\r
+}\r
+\r
+template<typename F>\r
+void CASPAR_THREAD_GUARD(int restart_count, const std::wstring& desc, const F& func)   \r
+{\r
+               LOG << caspar::utils::LogLevel::Verbose << desc << TEXT(" Thread Started");\r
+\r
+#ifdef WIN32\r
+               Win32Exception::InstallHandler();\r
+               _configthreadlocale(_DISABLE_PER_THREAD_LOCALE);\r
+#endif\r
+               for(int n = -1; n < restart_count; ++n)\r
+               {\r
+                       try\r
+                       {\r
+                               if(n >= 0)\r
+                                       LOG << caspar::utils::LogLevel::Critical << desc << TEXT(" Restarting Count:")  << n+1 << "/" << restart_count;\r
+                               func();\r
+                               n = restart_count;\r
+                       }\r
+                       catch(std::system_error& er)    \r
+                       {       \r
+                               try     \r
+                               {       \r
+                                       LOG << caspar::utils::LogLevel::Critical << desc << TEXT(" UNHANDLED EXCEPTION Message:")  << er.code().message().c_str();      \r
+                               }       \r
+                               catch(...){}    \r
+                       }       \r
+                       catch(std::exception& ex)       \r
+                       {       \r
+                               try     \r
+                               {       \r
+                                       LOG << caspar::utils::LogLevel::Critical << desc << TEXT(" UNHANDLED EXCEPTION Message:")  << ex.what();        \r
+                               }       \r
+                               catch(...){}    \r
+                       }       \r
+                       catch(...)      \r
+                       {       \r
+                               try     \r
+                               {       \r
+                                       LOG << caspar::utils::LogLevel::Critical << desc << TEXT(" UNHANDLED EXCEPTION");       \r
+                               }       \r
+                               catch(...){}    \r
+                       }\r
+               }\r
+               LOG << caspar::utils::LogLevel::Verbose << desc << TEXT(" Thread Ended");\r
+}\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/utils/Win32Exception.cpp b/server/utils/Win32Exception.cpp
new file mode 100644 (file)
index 0000000..76831af
--- /dev/null
@@ -0,0 +1,64 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\stdafx.h"\r
+#include "win32exception.h"\r
+\r
+void Win32Exception::InstallHandler() {\r
+       _set_se_translator(Win32Exception::Handler);\r
+}\r
+\r
+void Win32Exception::Handler(unsigned int errorCode, EXCEPTION_POINTERS* pInfo) {\r
+       switch(errorCode)\r
+       {\r
+       case EXCEPTION_ACCESS_VIOLATION:\r
+               throw Win32AccessViolationException(*(pInfo->ExceptionRecord));\r
+               break;\r
+\r
+       default:\r
+               throw Win32Exception(*(pInfo->ExceptionRecord));\r
+       }\r
+}\r
+\r
+Win32Exception::Win32Exception(const EXCEPTION_RECORD& info) : message_("Win32 exception"), location_(info.ExceptionAddress), errorCode_(info.ExceptionCode)\r
+{\r
+       switch(info.ExceptionCode)\r
+       {\r
+       case EXCEPTION_ACCESS_VIOLATION:\r
+               message_ = "Access violation";\r
+               break;\r
+       case EXCEPTION_FLT_DIVIDE_BY_ZERO:\r
+       case EXCEPTION_INT_DIVIDE_BY_ZERO:\r
+               message_ = "Divide by zero";\r
+               break;\r
+       }\r
+}\r
+\r
+Win32AccessViolationException::Win32AccessViolationException(const EXCEPTION_RECORD& info) : Win32Exception(info), isWrite_(false), badAddress_(0) \r
+{\r
+       isWrite_ = info.ExceptionInformation[0] == 1;\r
+       badAddress_ = reinterpret_cast<Win32Exception::Address>(info.ExceptionInformation[1]);\r
+}\r
+\r
+const char* Win32AccessViolationException::what() const {\r
+       sprintf_s<>(messageBuffer_, "Access violation at %p, trying to %s %p", Location(), isWrite_?"write":"read", badAddress_);\r
+\r
+       return messageBuffer_;\r
+}
\ No newline at end of file
diff --git a/server/utils/Win32Exception.h b/server/utils/Win32Exception.h
new file mode 100644 (file)
index 0000000..1535276
--- /dev/null
@@ -0,0 +1,77 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _CASPAR_WIN32EXCEPTION_H__\r
+#define _CASPAR_WIN32EXCEPTION_H__\r
+\r
+#pragma once\r
+\r
+#include <exception>\r
+\r
+class Win32Exception : public std::exception \r
+{\r
+public:\r
+       typedef const void* Address;\r
+       static void InstallHandler();\r
+\r
+       Address Location() const {\r
+               return location_;\r
+       }\r
+       unsigned int ErrorCode() const {\r
+               return errorCode_;\r
+       }\r
+       virtual const char* what() const {\r
+               return message_;\r
+       }\r
+\r
+protected:\r
+       Win32Exception(const EXCEPTION_RECORD& info);\r
+       static void Handler(unsigned int errorCode, EXCEPTION_POINTERS* pInfo);\r
+\r
+private:\r
+       const char* message_;\r
+\r
+       Address location_;\r
+       unsigned int errorCode_;\r
+};\r
+\r
+class Win32AccessViolationException : public Win32Exception\r
+{\r
+       mutable char messageBuffer_[256];\r
+\r
+public:\r
+       bool IsWrite() const {\r
+               return isWrite_;\r
+       }\r
+       Address BadAddress() const {\r
+               return badAddress_;\r
+       }\r
+       virtual const char* what() const;\r
+\r
+protected:\r
+       Win32AccessViolationException(const EXCEPTION_RECORD& info);\r
+       friend void Win32Exception::Handler(unsigned int errorCode, EXCEPTION_POINTERS* pInfo);\r
+\r
+private:\r
+       bool isWrite_;\r
+       Address badAddress_;\r
+};\r
+\r
+#endif //_CASPAR_WIN32EXCEPTION_H__
\ No newline at end of file
diff --git a/server/utils/event.cpp b/server/utils/event.cpp
new file mode 100644 (file)
index 0000000..9f69a3b
--- /dev/null
@@ -0,0 +1,53 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\StdAfx.h"\r
+\r
+#include <string>\r
+#include "Event.h"\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+Event::Event(bool bManualReset, bool bInitialState) : handle_(0)\r
+{\r
+       handle_ = CreateEvent(0, bManualReset, bInitialState, 0);\r
+       if(handle_ == 0) {\r
+               throw std::exception("Failed to create event");\r
+       }\r
+}\r
+\r
+void Event::Set() {\r
+       BOOL res = SetEvent(handle_);\r
+       if(res == FALSE) {\r
+               DWORD error = GetLastError();\r
+       }\r
+}\r
+void Event::Reset() {\r
+       ResetEvent(handle_);\r
+}\r
+\r
+Event::~Event()\r
+{\r
+       CloseHandle(handle_);\r
+}\r
+\r
+}      //namespace utils\r
+}      //namespace caspar
\ No newline at end of file
diff --git a/server/utils/functiontask.hpp b/server/utils/functiontask.hpp
new file mode 100644 (file)
index 0000000..2f47187
--- /dev/null
@@ -0,0 +1,77 @@
+#ifndef CASPAR_FUNCTION_TASK_H_\r
+\r
+#define CASPAR_FUNCTION_TASK_H_\r
+\r
+#include <tbb/task.h>\r
+#include <cassert>\r
+#include <tbb/concurrent_queue.h>\r
+#include <tbb/atomic.h>\r
+#include <functional>\r
+\r
+namespace caspar\r
+{\r
+       class function_task : tbb::task\r
+       {\r
+       public:\r
+               function_task(std::function<void()>&& func) : func_(std::move(func))\r
+               {\r
+                       assert(func_);\r
+               }\r
+\r
+               tbb::task* execute()\r
+               {\r
+                       func_();\r
+                       return nullptr;\r
+               }\r
+\r
+               inline static void enqueue(std::function<void()>&& func)\r
+               {\r
+                       tbb::task::enqueue(*new(tbb::task::allocate_root()) function_task(std::forward<std::function<void()>>(func)));\r
+               }\r
+\r
+       private:\r
+               std::function<void()> func_;\r
+       };\r
+\r
+       class function_task_serializer\r
+       {\r
+       public:\r
+               function_task_serializer()\r
+               {\r
+                       count_ = 0;\r
+               }\r
+\r
+               void enqueue(std::function<void()>&& func)\r
+               {\r
+                       assert(func);\r
+                       if(!func)\r
+                               return;\r
+\r
+                       queue_.push(std::forward<std::function<void()>>(func));\r
+                       if(++count_ == 1)\r
+                               function_task::enqueue([=]{execute();});\r
+               }\r
+\r
+       private:\r
+               void execute()\r
+               {\r
+                       std::function<void()> func;\r
+                       if(queue_.try_pop(func))\r
+                       {\r
+                               func();\r
+                               note_completion();\r
+                       }\r
+               }\r
+\r
+               void note_completion()\r
+               {\r
+                       if(--count_ != 0)\r
+                               function_task::enqueue([=]{execute();});\r
+               }\r
+\r
+               tbb::concurrent_bounded_queue<std::function<void()>> queue_;\r
+               tbb::atomic<int> count_;\r
+       };\r
+}\r
+\r
+#endif\r
diff --git a/server/utils/image/Clear.cpp b/server/utils/image/Clear.cpp
new file mode 100644 (file)
index 0000000..6d004e4
--- /dev/null
@@ -0,0 +1,92 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\..\stdafx.h"\r
+\r
+#include "Clear.hpp"\r
+\r
+#include <intrin.h>\r
+#include <functional>\r
+\r
+#include "../Types.hpp"\r
+\r
+#include "tbb/parallel_for.h"\r
+#include "tbb/blocked_range.h"\r
+\r
+using namespace std::tr1::placeholders;\r
+\r
+namespace caspar{\r
+namespace utils{\r
+namespace image{\r
+\r
+static const size_t STRIDE = sizeof(__m128i)*4;\r
+\r
+void DoClearParallel(const tbb::blocked_range<size_t>& r, const std::tr1::function<void(void*, size_t)>& func, void* dest)\r
+{\r
+       size_t offset = r.begin()*STRIDE;\r
+       size_t size = r.size()*STRIDE;\r
+       func(reinterpret_cast<s8*>(dest) + offset, size);\r
+}\r
+\r
+void ClearParallel(const std::tr1::function<void(void*, size_t)>& func, void* dest, size_t size)\r
+{\r
+       tbb::parallel_for(tbb::blocked_range<size_t>(0, size/STRIDE), std::tr1::bind(&DoClearParallel, _1, func, dest));        \r
+}\r
+\r
+ClearFun GetClearFun(SIMD simd)\r
+{\r
+       if(simd >= SSE2)\r
+               return ClearParallel_SSE2;\r
+       else\r
+               return ClearParallel_REF;\r
+}\r
+\r
+// TODO: (R.N) optimize => prefetch and cacheline loop unroll\r
+void Clear_SSE2(void* dest, size_t size)\r
+{\r
+       __m128i val = _mm_setzero_si128();\r
+       __m128i* ptr = reinterpret_cast<__m128i*>(dest);\r
+\r
+       int times = size / 16;\r
+       for(int i=0; i < times; ++i) \r
+       {\r
+               _mm_stream_si128(ptr, val);\r
+               ptr++;\r
+       }\r
+}\r
+\r
+void ClearParallel_SSE2(void* dest, size_t size)\r
+{\r
+       ClearParallel(&Clear_SSE2, dest, size);\r
+}\r
+\r
+void Clear_REF(void* dest, size_t size)\r
+{\r
+       __stosd(reinterpret_cast<unsigned long*>(dest), 0, size/4);\r
+}\r
+\r
+void ClearParallel_REF(void* dest, size_t size)\r
+{\r
+       ClearParallel(&Clear_REF, dest, size);\r
+}\r
+\r
+}\r
+}\r
+}
\ No newline at end of file
diff --git a/server/utils/image/Clear.hpp b/server/utils/image/Clear.hpp
new file mode 100644 (file)
index 0000000..7b86b9d
--- /dev/null
@@ -0,0 +1,51 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef CLEAR_H_\r
+#define CLEAR_H_\r
+\r
+#include "../CPUID.hpp"\r
+\r
+namespace caspar{\r
+namespace utils{\r
+namespace image{\r
+       \r
+void Clear_SSE2         (void* dest, size_t size);\r
+void Clear_REF  (void* dest, size_t size);\r
+void ClearParallel_SSE2         (void* dest, size_t size);\r
+void ClearParallel_REF  (void* dest, size_t size);\r
+\r
+typedef void(*ClearFun)(void*, size_t);\r
+ClearFun GetClearFun(SIMD simd = REF);\r
+\r
+\r
+//void StraightTransform_SSE2(const void* source, void* dest, size_t size);\r
+//void StraightTransform_REF(const void* source, void* dest, size_t size);\r
+//\r
+//typedef void(*StraightTransformFun)(const void*, void*, size_t);\r
+//StraightTransformFun GetStraightTransformFun(SIMD simd = REF);\r
+\r
+} // namespace image\r
+} // namespace utils\r
+} // namespace caspar\r
+\r
+#endif\r
+\r
+\r
diff --git a/server/utils/image/Copy.cpp b/server/utils/image/Copy.cpp
new file mode 100644 (file)
index 0000000..be78649
--- /dev/null
@@ -0,0 +1,97 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\..\stdafx.h"\r
+\r
+#include "Copy.hpp"\r
+\r
+#include <intrin.h>\r
+#include <functional>\r
+\r
+#include "../Types.hpp"\r
+\r
+#include "tbb/parallel_for.h"\r
+#include "tbb/blocked_range.h"\r
+\r
+using namespace std::tr1::placeholders;\r
+\r
+namespace caspar{\r
+namespace utils{\r
+namespace image{\r
+\r
+static const size_t STRIDE = sizeof(__m128i)*4;\r
+\r
+void DoCopyParallel(const tbb::blocked_range<size_t>& r, const std::tr1::function<void(void*, const void*, size_t)>& func, void* dest, const void* source)\r
+{\r
+       size_t offset = r.begin()*STRIDE;\r
+       size_t size = r.size()*STRIDE;\r
+       func(reinterpret_cast<s8*>(dest) + offset, reinterpret_cast<const s8*>(source) + offset, size);\r
+}\r
+\r
+void CopyParallel(const std::tr1::function<void(void*, const void*, size_t)>& func, void* dest, const void* source, size_t size)\r
+{\r
+       tbb::parallel_for(tbb::blocked_range<size_t>(0, size/STRIDE), std::tr1::bind(&DoCopyParallel, _1, func, dest, source)); \r
+}\r
+\r
+CopyFun GetCopyFun(SIMD simd)\r
+{\r
+       if(simd >= SSE2)\r
+               return CopyParallel_SSE2;\r
+       else\r
+               return CopyParallel_REF;\r
+}\r
+\r
+// TODO: (R.N) optimize => prefetch and cacheline loop unroll\r
+void Copy_SSE2(void* dest, const void* source, size_t size)\r
+{\r
+       __m128i val = _mm_setzero_si128();\r
+       __m128i* pD = reinterpret_cast<__m128i*>(dest);\r
+       const __m128i* pS = reinterpret_cast<const __m128i*>(source);\r
+\r
+       int times = size / 16;\r
+       for(int i=0; i < times; ++i) \r
+       {\r
+               val = _mm_load_si128(pS);\r
+               _mm_stream_si128(pD, val);\r
+\r
+               ++pD;\r
+               ++pS;\r
+       }\r
+       _mm_mfence();   //ensure last WC buffers get flushed to memory\r
+}\r
+\r
+void CopyParallel_SSE2(void* dest, const void* source, size_t size)\r
+{\r
+       CopyParallel(&Copy_SSE2, dest, source, size);\r
+}\r
+\r
+void Copy_REF(void* dest, const void* source, size_t size)\r
+{\r
+       __movsd(reinterpret_cast<unsigned long*>(dest), reinterpret_cast<const unsigned long*>(source), size/4);\r
+}\r
+\r
+void CopyParallel_REF(void* dest, const void* source, size_t size)\r
+{\r
+       CopyParallel(&Copy_REF, dest, source, size);\r
+}\r
+\r
+}\r
+}\r
+}
\ No newline at end of file
diff --git a/server/utils/image/Copy.hpp b/server/utils/image/Copy.hpp
new file mode 100644 (file)
index 0000000..e921d8b
--- /dev/null
@@ -0,0 +1,51 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef COPY_H_\r
+#define COPY_H_\r
+\r
+#include "../CPUID.hpp"\r
+\r
+namespace caspar{\r
+namespace utils{\r
+namespace image{\r
+       \r
+void Copy_SSE2  (void* dest, const void* source, size_t size);\r
+void Copy_REF   (void* dest, const void* source, size_t size);\r
+\r
+void CopyParallel_SSE2  (void* dest, const void* source, size_t size);\r
+void CopyParallel_REF   (void* dest, const void* source, size_t size);\r
+\r
+typedef void(*CopyFun)(void*, const void*, size_t);\r
+CopyFun GetCopyFun(SIMD simd = REF);\r
+\r
+//void StraightTransform_SSE2(const void* source, void* dest, size_t size);\r
+//void StraightTransform_REF(const void* source, void* dest, size_t size);\r
+//\r
+//typedef void(*StraightTransformFun)(const void*, void*, size_t);\r
+//StraightTransformFun GetStraightTransformFun(SIMD simd = REF);\r
+\r
+} // namespace image\r
+} // namespace utils\r
+} // namespace caspar\r
+\r
+#endif\r
+\r
+\r
diff --git a/server/utils/image/CopyField.cpp b/server/utils/image/CopyField.cpp
new file mode 100644 (file)
index 0000000..9c4d6af
--- /dev/null
@@ -0,0 +1,105 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\..\stdafx.h"\r
+\r
+#include "CopyField.hpp"\r
+#include "Copy.hpp"\r
+\r
+#include <intrin.h>\r
+#include <functional>\r
+\r
+#include "../Types.hpp"\r
+\r
+#include "tbb/parallel_for.h"\r
+#include "tbb/blocked_range.h"\r
+\r
+using namespace std::tr1::placeholders; \r
+\r
+namespace caspar{\r
+namespace utils{\r
+namespace image{\r
+\r
+void DoCopyFieldParallel(size_t index, const std::tr1::function<void(void*, const void*, size_t)>& func, void* dest, const void* source, size_t width4)\r
+{\r
+       size_t offset = index*width4;\r
+       size_t size = width4;\r
+       func(reinterpret_cast<s8*>(dest) + offset, reinterpret_cast<const s8*>(source) + offset, size);\r
+}\r
+\r
+void CopyFieldParallel(const std::tr1::function<void(void*, const void*, size_t)>& func, void* dest, const void* source, size_t fieldIndex, size_t width, size_t height)\r
+{\r
+       tbb::parallel_for(fieldIndex, height, static_cast<size_t>(2), std::tr1::bind(&DoCopyFieldParallel, _1, func, dest, source, width*4)); // copy for each row\r
+}\r
+\r
+CopyFieldFun GetCopyFieldFun(SIMD simd)\r
+{\r
+       //if(simd >= SSE2)\r
+       //      return CopyFieldParallel_SSE2;\r
+       //else\r
+       return CopyFieldParallel_REF; // REF is faster\r
+}\r
+\r
+// TODO: (R.N) optimize => prefetch and cacheline loop unroll\r
+void CopyField_SSE2(unsigned char* pDest, unsigned char* pSrc, size_t fieldIndex, size_t width, size_t height)\r
+{\r
+       for(int rowIndex=fieldIndex; rowIndex < height; rowIndex+=2) \r
+       {\r
+               int offset = width*4*rowIndex;\r
+\r
+               __m128i val = _mm_setzero_si128();\r
+               __m128i* pD = reinterpret_cast<__m128i*>(&(pDest[offset]));\r
+               const __m128i* pS = reinterpret_cast<const __m128i*>(&(pSrc[offset]));\r
+\r
+               int times = width / 4;\r
+               for(int i=0; i < times; ++i) \r
+               {\r
+                       val = _mm_load_si128(pS);\r
+                       _mm_stream_si128(pD, val);\r
+\r
+                       ++pD;\r
+                       ++pS;\r
+               }\r
+       }\r
+       _mm_mfence();   //ensure last WC buffers get flushed to memory\r
+}\r
+\r
+void CopyFieldParallel_SSE2(unsigned char* dest, unsigned char* source, size_t fieldIndex, size_t width, size_t height)\r
+{\r
+       CopyFieldParallel(&Copy_SSE2, dest, source, fieldIndex, width, height);\r
+}\r
+\r
+void CopyField_REF(unsigned char* pDest, unsigned char* pSrc, size_t fieldIndex, size_t width, size_t height)\r
+{\r
+       for(int rowIndex=fieldIndex; rowIndex < height; rowIndex+=2) \r
+       {\r
+               int offset = width*4*rowIndex;\r
+               __movsd(reinterpret_cast<unsigned long*>(&(pDest[offset])), reinterpret_cast<const unsigned long*>(&(pSrc[offset])), width);\r
+       }\r
+}\r
+\r
+void CopyFieldParallel_REF(unsigned char* dest, unsigned char* source, size_t fieldIndex, size_t width, size_t height)\r
+{\r
+       CopyFieldParallel(&Copy_REF, dest, source, fieldIndex, width, height);\r
+}\r
+\r
+}\r
+}\r
+}
\ No newline at end of file
diff --git a/server/utils/image/CopyField.hpp b/server/utils/image/CopyField.hpp
new file mode 100644 (file)
index 0000000..83c31bc
--- /dev/null
@@ -0,0 +1,52 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef COPY_FIELD_H_\r
+#define COPY_FIELD_H_\r
+\r
+#include "../CPUID.hpp"\r
+\r
+namespace caspar{\r
+namespace utils{\r
+namespace image{\r
+       \r
+void CopyField_SSE2     (unsigned char* pDest, unsigned char* pSrc, size_t fieldIndex, size_t width, size_t height);\r
+void CopyField_REF      (unsigned char* pDest, unsigned char* pSrc, size_t fieldIndex, size_t width, size_t height);\r
+\r
+void CopyFieldParallel_SSE2     (unsigned char* pDest, unsigned char* pSrc, size_t fieldIndex, size_t width, size_t height);\r
+void CopyFieldParallel_REF      (unsigned char* pDest, unsigned char* pSrc, size_t fieldIndex, size_t width, size_t height);\r
+\r
+typedef void(*CopyFieldFun)(unsigned char* pDest, unsigned char* pSrc, size_t fieldIndex, size_t width, size_t height);\r
+CopyFieldFun GetCopyFieldFun(SIMD simd = REF);\r
+\r
+\r
+//void StraightTransform_SSE2(const void* source, void* dest, size_t size);\r
+//void StraightTransform_REF(const void* source, void* dest, size_t size);\r
+//\r
+//typedef void(*StraightTransformFun)(const void*, void*, size_t);\r
+//StraightTransformFun GetStraightTransformFun(SIMD simd = REF);\r
+\r
+} // namespace image\r
+} // namespace utils\r
+} // namespace caspar\r
+\r
+#endif\r
+\r
+\r
diff --git a/server/utils/image/Image.cpp b/server/utils/image/Image.cpp
new file mode 100644 (file)
index 0000000..c8c155e
--- /dev/null
@@ -0,0 +1,108 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\..\stdafx.h"\r
+\r
+#include "Image.hpp"\r
+\r
+#include "Over.hpp"\r
+#include "Lerp.hpp"\r
+#include "Shuffle.hpp"\r
+#include "Premultiply.hpp"\r
+#include "Copy.hpp"\r
+#include "CopyField.hpp"\r
+#include "Clear.hpp"\r
+//#include "Transition.hpp"\r
+\r
+namespace caspar{\r
+namespace utils{\r
+namespace image{\r
+\r
+namespace detail\r
+{\r
+       ShuffleFun                      Shuffle                 = GetShuffleFun(REF);\r
+       PreOverFun                      PreOver                 = GetPreOverFun(REF);\r
+       LerpFun                         Lerp                    = GetLerpFun(REF);\r
+       PremultiplyFun          Premultiply             = GetPremultiplyFun(REF);\r
+       CopyFun                         Copy                    = GetCopyFun(REF);\r
+       CopyFieldFun            CopyField               = GetCopyFieldFun(REF);\r
+       ClearFun                        Clear                   = GetClearFun(REF);\r
+\r
+       const Initializer init;\r
+}\r
+\r
+void Shuffle(void* dest, const void* source, size_t size, const u8 red, const u8 green, const u8 blue, const u8 alpha)\r
+{\r
+       (*detail::Shuffle)(dest, source, size, red, green, blue, alpha);\r
+}\r
+\r
+void PreOver(void* dest, const void* source1, const void* source2, size_t size)\r
+{\r
+       (*detail::PreOver)(dest, source1, source2, size);\r
+}\r
+\r
+void Lerp(void* dest, const void* source1, const void* source2, float alpha, size_t size)\r
+{\r
+       (*detail::Lerp)(dest, source1, source2, alpha, size);\r
+}\r
+\r
+void Premultiply(void* dest, const void* source, size_t size)\r
+{\r
+       (*detail::Premultiply)(dest, source, size);\r
+}\r
+\r
+void Copy(void* dest, const void* source, size_t size)\r
+{\r
+       (*detail::Copy)(dest, source, size);\r
+}\r
+\r
+void CopyField(unsigned char* pDest, unsigned char* pSrc, size_t fieldIndex, size_t width, size_t height)\r
+{\r
+       (*detail::CopyField)(pDest, pSrc, fieldIndex, width, height);\r
+}\r
+\r
+void Clear(void* dest, size_t size)\r
+{\r
+       (*detail::Clear)(dest, size);\r
+}\r
+/*\r
+void Transition(void* dest, const void* source1, const void* source2, int currentFrame, size_t width, size_t height, const TransitionInfo& transitionInfo)\r
+{\r
+       (*detail::Transition)(dest, source1, source2, currentFrame, width, height, transitionInfo);\r
+}*/\r
+\r
+void SetVersion(SIMD simd)\r
+{      \r
+       if(simd == AUTO)\r
+               simd = CPUID().SIMD;\r
+       \r
+       detail::Shuffle                 = GetShuffleFun(simd);\r
+       detail::PreOver                 = GetPreOverFun(simd);\r
+       detail::Lerp                    = GetLerpFun(simd);\r
+       detail::Premultiply             = GetPremultiplyFun(simd);\r
+       detail::Copy                    = GetCopyFun(simd);\r
+       detail::CopyField               = GetCopyFieldFun(simd);\r
+       detail::Clear                   = GetClearFun(simd);\r
+       //detail::Transition            = GetTransitionFun(simd);\r
+}\r
+\r
+} // namespace image\r
+} // namespace utils\r
+} // namespace caspar
\ No newline at end of file
diff --git a/server/utils/image/Image.hpp b/server/utils/image/Image.hpp
new file mode 100644 (file)
index 0000000..d9a36b4
--- /dev/null
@@ -0,0 +1,173 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _IMAGE_H_\r
+#define _IMAGE_H_\r
+\r
+#include "../Types.hpp"\r
+#include "../CPUID.hpp"\r
+\r
+namespace caspar{\r
+\r
+class TransitionInfo;\r
+\r
+namespace utils{\r
+namespace image{       \r
+       \r
+/*\r
+   Function: SetVersion\r
+\r
+   Sets appropriate function pointers for image library functions depending on SIMD version.\r
+\r
+   Modified: 2009/4/14 (R.N)\r
+\r
+   Parameters:\r
+\r
+      simd     - SIMD version to use\r
+\r
+   Author: Robert Nagy, R.N (SVT 2009)\r
+               \r
+*/\r
+void SetVersion(SIMD simd = AUTO);\r
+\r
+/*\r
+   Function: Shuffle\r
+\r
+   Shuffles 8 byte channels in image\r
+\r
+   Modified: 2009/4/15 (R.N)\r
+\r
+   Parameters:\r
+\r
+      source1  - Image source\r
+         dest          - Image destination\r
+         size          - Size of image in bytes\r
+         mask0         - index of first channel\r
+         mask1         - index of second channel\r
+         mask2         - index of third channel\r
+         mask3         - index of fourth channel\r
+\r
+   Author: Robert Nagy, R.N (SVT 2009)\r
+               \r
+   See: Shuffle.hpp    \r
+*/\r
+void Shuffle(void* dest, const void* source, size_t size, const u8 red, const u8 green, const u8 blue, const u8 alpha);\r
+\r
+/*\r
+   Function: PreOver\r
+\r
+   Blends two images with premultiplied alpha.\r
+   Result is put into dest as an image with premultiplied alpha.\r
+\r
+   Modified: 2009/4/12 (R.N)\r
+\r
+   Parameters:\r
+\r
+      source1  - Image above\r
+      source2  - Image beneath\r
+         dest          - Image destination\r
+         size          - Size of image in bytes\r
+\r
+   Author: Robert Nagy, R.N (SVT 2009)\r
+\r
+   See: Over.hpp\r
+               \r
+*/\r
+void PreOver(void* dest, const void* source1, const void* source2, size_t size);\r
+\r
+/*\r
+   Function: Lerp\r
+\r
+   Blends two images based on alpha value;\r
+   Result is put into dest as an image with premultiplied alpha.\r
+\r
+   Modified: 2009/4/12 (R.N)\r
+                        2009/4/20 (R.N)        \r
+\r
+   Parameters:\r
+\r
+      source1  - Image above\r
+      source2  - Image beneath\r
+         dest          - Image destination\r
+         size          - Size of image in bytes\r
+\r
+   Author: Robert Nagy, R.N (SVT 2009)\r
+\r
+   See: Lerp.hpp               \r
+*/\r
+void Lerp(void* dest, const void* source1, const void* source2, float alpha, size_t size);\r
+\r
+/*\r
+   Function: Premultiply\r
+\r
+   Premultiplies color with alpha.\r
+\r
+   Modified: 2009/4/20 (R.N)\r
+\r
+   Parameters:\r
+\r
+      source1  - Image\r
+         dest          - Image destination\r
+         size          - Size of image in bytes\r
+\r
+   Author: Robert Nagy, R.N (SVT 2009)\r
+\r
+   See: Premultiply.hpp                \r
+*/\r
+void Premultiply(void* dest, const void* source, size_t size);\r
+\r
+void Copy(void* dest, const void* source, size_t size);\r
+\r
+void Clear(void* dest, size_t size);\r
+\r
+void CopyField(unsigned char* pDest, unsigned char* pSrc, size_t fieldIndex, size_t width, size_t height);\r
+\r
+//void Transition(void* dest, const void* source1, const void* source2, int currentFrame, size_t width, size_t height, const TransitionInfo& transitionInfo);\r
+\r
+//void Wipe(void* dest, const void* source1, const void* source2, u32 offset, u32 halfStep, Direction dir, size_t width, size_t height, size_t borderWidth, const void* border = NULL, u32 borderColor = 0);\r
+\r
+namespace detail\r
+{\r
+       typedef void(*PreOverFun)               (void*, const void*, const void*, size_t);\r
+       typedef void(*ShuffleFun)               (void*, const void*, size_t, const u8, const u8, const u8, const u8);\r
+       typedef void(*LerpFun)                  (void*, const void*, const void*, float, size_t);\r
+       typedef void(*PremultiplyFun)   (void*, const void*, size_t);\r
+       typedef void(*CopyFun)                  (void*, const void*, size_t);\r
+       typedef void(*CopyFieldFun)             (unsigned char* pDest, unsigned char* pSrc, size_t fieldIndex, size_t width, size_t height);\r
+       typedef void(*ClearFun)                 (void*, size_t);\r
+       //typedef void(*TransitionFun)(void*, const void*, const void*, int, size_t, size_t, const TransitionInfo&);\r
+\r
+       extern ShuffleFun               Shuffle;\r
+       extern PreOverFun               PreOver;\r
+       extern LerpFun                  Lerp;\r
+       extern PremultiplyFun   Premultiply;\r
+       extern CopyFun                  Copy;\r
+       extern CopyFieldFun             CopyField;\r
+       extern ClearFun                 Clear;\r
+       //extern TransitionFun  Transition;\r
+\r
+       extern const struct Initializer{Initializer(){SetVersion(AUTO);}} init;\r
+}\r
+\r
+} // namespace image\r
+} // namespace utils\r
+} // namespace caspar\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/utils/image/Lerp.cpp b/server/utils/image/Lerp.cpp
new file mode 100644 (file)
index 0000000..8d4d4fb
--- /dev/null
@@ -0,0 +1,220 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\..\stdafx.h"\r
+\r
+#include "Lerp.hpp"\r
+\r
+#include <intrin.h>\r
+#include <functional>\r
+\r
+#include "../Types.hpp"\r
+\r
+#include "tbb/parallel_for.h"\r
+#include "tbb/blocked_range.h"\r
+\r
+using namespace std::tr1::placeholders;\r
+\r
+namespace caspar{\r
+namespace utils{\r
+namespace image{\r
+\r
+static const size_t STRIDE = sizeof(__m128i)*4;\r
+\r
+void DoLerpParallel(const tbb::blocked_range<size_t>& r, const std::tr1::function<void(void*, const void*, const void*, float, size_t)>& func, void* dest, const void* source1, const void* source2, float alpha)\r
+{\r
+       size_t offset = r.begin()*STRIDE;\r
+       size_t size = r.size()*STRIDE;\r
+       func(reinterpret_cast<s8*>(dest) + offset, reinterpret_cast<const s8*>(source1) + offset, reinterpret_cast<const s8*>(source2) + offset, alpha, size);\r
+}\r
+\r
+void LerpParallel(const std::tr1::function<void(void*, const void*, const void*, float, size_t)>& func, void* dest, const void* source1, const void* source2, float alpha, size_t size)\r
+{\r
+       tbb::parallel_for(tbb::blocked_range<size_t>(0, size/STRIDE), std::tr1::bind(&DoLerpParallel, _1, func, dest, source1, source2, alpha));        \r
+}\r
+\r
+LerpFun GetLerpFun(SIMD simd)\r
+{\r
+       if(simd >= SSE2)\r
+               return LerpParallel_SSE2;\r
+       else\r
+               return LerpParallel_REF;\r
+}\r
+\r
+void Lerp_SSE2(void* dest, const void* source1, const void* source2, float alpha, size_t size)\r
+{\r
+       static const u32 PSD = 64;\r
+       \r
+       static const __m128i lomask = _mm_set1_epi32(0x00FF00FF);\r
+       static const __m128i round = _mm_set1_epi16(128);\r
+\r
+       assert(source1 != NULL && source2 != NULL && dest != NULL);\r
+       assert(size % STRIDE == 0);\r
+       assert(alpha >= 0.0 && alpha <= 1.0);\r
+\r
+       const __m128i* source128_1 = reinterpret_cast<const __m128i*>(source1);\r
+       const __m128i* source128_2 = reinterpret_cast<const __m128i*>(source2);\r
+       __m128i* dest128 = reinterpret_cast<__m128i*>(dest);\r
+\r
+       __m128i s = _mm_setzero_si128();\r
+       __m128i d = _mm_setzero_si128();\r
+       const __m128i a = _mm_set1_epi16(static_cast<u8>(alpha*256.0f+0.5f));\r
+       \r
+       __m128i drb, dga, srb, sga;\r
+       \r
+       for (size_t k = 0, length = size/STRIDE; k < length; ++k)\r
+       {               \r
+               _mm_prefetch(reinterpret_cast<const char*>(source128_1 + PSD), _MM_HINT_NTA);   \r
+               _mm_prefetch(reinterpret_cast<const char*>(source128_2 + PSD), _MM_HINT_NTA);\r
+               // TODO: assembly optimization use PSHUFD on moves before calculations, lower latency than MOVDQA (R.N) http://software.intel.com/en-us/articles/fast-simd-integer-move-for-the-intel-pentiumr-4-processor/\r
+\r
+               for(int n = 0; n < 4; ++n, ++dest128, ++source128_1, ++source128_2)\r
+               {\r
+                       // r = d + (s-d)*alpha/256\r
+                       s = _mm_load_si128(source128_1);        // AABBGGRR\r
+                       d = _mm_load_si128(source128_2);        // AABBGGRR\r
+\r
+                       srb = _mm_and_si128(lomask, s);         // 00BB00RR             // unpack\r
+                       sga = _mm_srli_epi16(s, 8);                     // AA00GG00             // unpack\r
+                       \r
+                       drb = _mm_and_si128(lomask, d);         // 00BB00RR             // unpack\r
+                       dga = _mm_srli_epi16(d, 8);                     // AA00GG00             // unpack\r
+\r
+                       srb = _mm_sub_epi16(srb, drb);          // BBBBRRRR             // sub\r
+                       srb = _mm_mullo_epi16(srb, a);          // BBBBRRRR             // mul\r
+                       srb = _mm_add_epi16(srb, round);\r
+                       \r
+                       sga = _mm_sub_epi16(sga, dga);          // AAAAGGGG             // sub\r
+                       sga = _mm_mullo_epi16(sga, a);          // AAAAGGGG             // mul\r
+                       sga = _mm_add_epi16(sga, round);\r
+\r
+                       srb = _mm_srli_epi16(srb, 8);           // 00BB00RR             // prepack and div\r
+                       sga = _mm_andnot_si128(lomask, sga);// AA00GG00         // prepack and div\r
+\r
+                       srb = _mm_or_si128(srb, sga);           // AABBGGRR             // pack\r
+\r
+                       srb = _mm_add_epi8(srb, d);                     // AABBGGRR             // add          there is no overflow(R.N)\r
+\r
+                       _mm_stream_si128(dest128, srb);\r
+               }\r
+       }\r
+       _mm_mfence();   //ensure last WC buffers get flushed to memory\r
+}\r
+\r
+void LerpParallel_SSE2(void* dest, const void* source1, const void* source2, float alpha, size_t size)\r
+{\r
+       LerpParallel(&Lerp_SSE2, dest, source1, source2, alpha, size);\r
+}\r
+\r
+void Lerp_REF(void* dest, const void* source1, const void* source2, float alpha, size_t size)\r
+{\r
+       assert(source1 != NULL && source2 != NULL && dest != NULL);\r
+       assert(size % 4 == 0);\r
+       assert(alpha >= 0.0f && alpha <= 1.0f);\r
+\r
+       const u8* source8_1 = reinterpret_cast<const u8*>(source1);\r
+       const u8* source8_2 = reinterpret_cast<const u8*>(source2);\r
+       u8* dest8 = reinterpret_cast<u8*>(dest);\r
+\r
+       u8 a = static_cast<u8>(alpha*256.0f);\r
+       for(size_t n = 0; n < size; n+=4)\r
+       {\r
+               // s\r
+               u32 sr = source8_1[n+0];\r
+               u32 sg = source8_1[n+1];\r
+               u32 sb = source8_1[n+2];\r
+               u32 sa = source8_1[n+3];\r
+\r
+               // d\r
+               u32 dr = source8_2[n+0];\r
+               u32 dg = source8_2[n+1];\r
+               u32 db = source8_2[n+2];\r
+               u32 da = source8_2[n+3];\r
+\r
+               //dest8[n+0] = dr + ((sr-dr)*a)/256;\r
+               //dest8[n+1] = dg + ((sg-dg)*a)/256;\r
+               //dest8[n+2] = db + ((sb-db)*a)/256;\r
+               //dest8[n+3] = da + ((sa-da)*a)/256;\r
+\r
+               dest8[n+0] = dr + int(float((sr-dr)*a)/256.0f+0.5f);\r
+               dest8[n+1] = dg + int(float((sg-dg)*a)/256.0f+0.5f);\r
+               dest8[n+2] = db + int(float((sb-db)*a)/256.0f+0.5f);\r
+               dest8[n+3] = da + int(float((sa-da)*a)/256.0f+0.5f);\r
+\r
+       }\r
+}\r
+\r
+void LerpParallel_REF(void* dest, const void* source1, const void* source2, float alpha, size_t size)\r
+{\r
+       LerpParallel(&Lerp_REF, dest, source1, source2, alpha, size);\r
+}\r
+\r
+// Author: Niclas P Andersson\r
+void Lerp_OLD(void* dest, const void* source1, const void* source2, float alpha, size_t size)\r
+{\r
+       __m128i ps1, ps2, pd1, pd2, m0, m1, pr1, pr2;\r
+\r
+       __m128i* pSource = (__m128i*)source1;\r
+       __m128i* pDest = (__m128i*)source2;\r
+       __m128i* pResult = (__m128i*)dest;\r
+\r
+       __m128i a = _mm_set1_epi16(static_cast<u8>(alpha*256.0f+0.5f));\r
+       m0 = _mm_setzero_si128();\r
+\r
+       int count = size/4;\r
+       for ( int i = 0; i < count; i+=4 )\r
+       {\r
+               ps1 = _mm_load_si128(pSource);          //load 4 pixels from source\r
+               pd1 = _mm_load_si128(pDest);            //load 4 pixels from dest\r
+               ps2 = _mm_unpackhi_epi64(ps1, m0);      //move the 2 high pixels from source\r
+               pd2 = _mm_unpackhi_epi64(pd1, m0);      //move the 2 high pixels from dest\r
+\r
+               //compute the 2 "lower" pixels\r
+               ps1 = _mm_unpacklo_epi8(ps1, m0);       //unpack the 2 low pixels from source (bytes -> words)\r
+               pd1 = _mm_unpacklo_epi8(pd1, m0);       //unpack the 2 low pixels from dest (bytes -> words)\r
+\r
+               pr1 = _mm_sub_epi16(ps1, pd1);          //x = src - dest\r
+               pr1 = _mm_mullo_epi16(pr1, a);          //y = x*alpha\r
+               pr1 = _mm_srli_epi16(pr1, 8);       //w = y/256         \r
+               pr1 = _mm_add_epi8(pr1, pd1);           //z = w + dest\r
+\r
+               //same thing for the 2 "high" pixels\r
+               ps2 = _mm_unpacklo_epi8(ps2, m0);\r
+               pd2 = _mm_unpacklo_epi8(pd2, m0);\r
+\r
+               pr2 = _mm_sub_epi16(ps2, pd2);          //x = src - dest\r
+               pr2 = _mm_mullo_epi16(pr2, a);          //y = x*alpha\r
+               pr2 = _mm_srli_epi16(pr2, 8);       //w = y/256         \r
+               pr2 = _mm_add_epi8(pr2, pd2);           //z = w + dest\r
+\r
+               m1 = _mm_packus_epi16(pr1, pr2);        //pack all 4 together again (words -> bytes)\r
+               _mm_store_si128(pResult, m1);\r
+\r
+               pSource++;\r
+               pDest++;\r
+               pResult++;\r
+       }\r
+}\r
+\r
+} // namespace image\r
+} // namespace utils\r
+} // namespace caspar\r
+\r
+\r
diff --git a/server/utils/image/Lerp.hpp b/server/utils/image/Lerp.hpp
new file mode 100644 (file)
index 0000000..746e387
--- /dev/null
@@ -0,0 +1,45 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _LERP_H_\r
+#define _LERP_H_\r
+\r
+#include "../CPUID.hpp"\r
+\r
+namespace caspar{\r
+namespace utils{\r
+namespace image{\r
+               \r
+void Lerp_SSE2(void* dest, const void* source1, const void* source2, float alpha, size_t size);\r
+void Lerp_REF (void* dest, const void* source1, const void* source2, float alpha, size_t size);\r
+void LerpParallel_SSE2(void* dest, const void* source1, const void* source2, float alpha, size_t size);\r
+void LerpParallel_REF (void* dest, const void* source1, const void* source2, float alpha, size_t size);\r
+void Lerp_OLD (void* dest, const void* source1, const void* source2, float alpha, size_t size);\r
+\r
+typedef void(*LerpFun)(void*, const void*, const void*, float, size_t);\r
+LerpFun GetLerpFun(SIMD simd = REF);\r
+\r
+} // namespace image\r
+} // namespace utils\r
+} // namespace caspar\r
+\r
+#endif\r
+\r
+\r
diff --git a/server/utils/image/Over.cpp b/server/utils/image/Over.cpp
new file mode 100644 (file)
index 0000000..79b09d6
--- /dev/null
@@ -0,0 +1,246 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\..\stdafx.h"\r
+\r
+#include "Over.hpp"\r
+\r
+#include <intrin.h>\r
+#include <functional>\r
+\r
+#include "../Types.hpp"\r
+\r
+#include "tbb/parallel_for.h"\r
+#include "tbb/blocked_range.h"\r
+\r
+using namespace std::tr1::placeholders;\r
+\r
+namespace caspar{\r
+namespace utils {\r
+namespace image        {\r
+\r
+static const size_t STRIDE = sizeof(__m128i)*4;\r
+\r
+void DoPreOverParallel(const tbb::blocked_range<size_t>& r, const std::tr1::function<void(void*, const void*, const void*, size_t)>& func, void* dest, const void* source1, const void* source2)\r
+{\r
+       size_t offset = r.begin()*STRIDE;\r
+       size_t size = r.size()*STRIDE;\r
+       func(reinterpret_cast<s8*>(dest) + offset, reinterpret_cast<const s8*>(source1) + offset, reinterpret_cast<const s8*>(source2) + offset, size);\r
+}\r
+\r
+void PreOverParallel(const std::tr1::function<void(void*, const void*, const void*, size_t)>& func, void* dest, const void* source1, const void* source2, size_t size)\r
+{\r
+       tbb::parallel_for(tbb::blocked_range<size_t>(0, size/STRIDE), std::tr1::bind(&DoPreOverParallel, _1, func, dest, source1, source2));    \r
+}\r
+\r
+PreOverFun GetPreOverFun(SIMD simd)\r
+{\r
+       if(simd >= SSE2)\r
+               return PreOverParallel_SSE2;\r
+       else\r
+               return PreOverParallel_REF;\r
+}\r
+\r
+// this function performs precise calculations\r
+void PreOver_SSE2(void* dest, const void* source1, const void* source2, size_t size)\r
+{\r
+       static const u32 PSD = 64;\r
+\r
+       static const __m128i round = _mm_set1_epi16(128);\r
+       static const __m128i lomask = _mm_set1_epi32(0x00FF00FF);\r
+\r
+       assert(source1 != NULL && source2 != NULL && dest != NULL);\r
+       assert(size % STRIDE == 0);\r
+\r
+       const __m128i* source128_1 = reinterpret_cast<const __m128i*>(source1);\r
+       const __m128i* source128_2 = reinterpret_cast<const __m128i*>(source2);\r
+       __m128i*           dest128 = reinterpret_cast<__m128i*>(dest);  \r
+       \r
+       __m128i d, s, a, rb, ag, t;\r
+\r
+       // TODO: dynamic prefetch schedluing distance? needs to be optimized (R.N)\r
+\r
+       for(size_t k = 0, length = size/STRIDE; k < length; ++k)        \r
+       {\r
+               // TODO: put prefetch between calculations?(R.N)\r
+               _mm_prefetch(reinterpret_cast<const s8*>(source128_1+PSD), _MM_HINT_NTA);\r
+               _mm_prefetch(reinterpret_cast<const s8*>(source128_2+PSD), _MM_HINT_NTA);       \r
+\r
+               // work on entire cacheline before next prefetch\r
+               for(int n = 0; n < 4; ++n, ++dest128, ++source128_1, ++source128_2)\r
+               {\r
+                       // TODO: assembly optimization use PSHUFD on moves before calculations, lower latency than MOVDQA (R.N) http://software.intel.com/en-us/articles/fast-simd-integer-move-for-the-intel-pentiumr-4-processor/\r
+\r
+                       // TODO: load entire cacheline at the same time? are there enough registers? 32 bit mode (special compile for 64bit?) (R.N)\r
+                       s = _mm_load_si128(source128_1);                // AABGGRR\r
+                       d = _mm_load_si128(source128_2);                // AABGGRR\r
+                                               \r
+                       // PRELERP(S, D) = S+D - ((S*D[A]+0x80)>>8)+(S*D[A]+0x80))>>8\r
+                       // T = S*D[A]+0x80 => PRELERP(S,D) = S+D - ((T>>8)+T)>>8\r
+\r
+                       // set alpha to lo16 from dest_\r
+                       a = _mm_srli_epi32(d, 24);                      // 000000AA     \r
+                       rb = _mm_slli_epi32(a, 16);                     // 00AA0000\r
+                       a = _mm_or_si128(rb, a);                        // 00AA00AA\r
+\r
+                       rb = _mm_and_si128(lomask, s);          // 00BB00RR             \r
+                       rb = _mm_mullo_epi16(rb, a);            // BBBBRRRR     \r
+                       rb = _mm_add_epi16(rb, round);          // BBBBRRRR\r
+                       t = _mm_srli_epi16(rb, 8);                      \r
+                       t = _mm_add_epi16(t, rb);\r
+                       rb = _mm_srli_epi16(t, 8);                      // 00BB00RR     \r
+\r
+                       ag = _mm_srli_epi16(s, 8);                      // 00AA00GG             \r
+                       ag = _mm_mullo_epi16(ag, a);            // AAAAGGGG             \r
+                       ag = _mm_add_epi16(ag, round);\r
+                       t = _mm_srli_epi16(ag, 8);\r
+                       t = _mm_add_epi16(t, ag);\r
+                       ag = _mm_andnot_si128(lomask, t);       // AA00GG00             \r
+                                       \r
+                       rb = _mm_or_si128(rb, ag);                      // AABGGRR              pack\r
+                                       \r
+                       rb = _mm_sub_epi8(s, rb);                       // sub S-[(D[A]*S)/255]\r
+                       d = _mm_add_epi8(d, rb);                        // add D+[S-(D[A]*S)/255]\r
+\r
+                       _mm_stream_si128(dest128, d);\r
+               }\r
+       }       \r
+       _mm_mfence();   //ensure last WC buffers get flushed to memory          \r
+}\r
+\r
+void PreOverParallel_SSE2(void* dest, const void* source1, const void* source2, size_t size)\r
+{\r
+       PreOverParallel(&PreOver_SSE2, dest, source1, source2, size);   \r
+}\r
+\r
+void PreOver_FastSSE2(void* dest, const void* source1, const void* source2, size_t size)\r
+{\r
+       static const u32 PSD = 64;\r
+\r
+       static const __m128i lomask = _mm_set1_epi32(0x00FF00FF);\r
+\r
+       assert(source1 != NULL && source2 != NULL && dest != NULL);\r
+       assert(size % STRIDE == 0);\r
+\r
+       const __m128i* source128_1 = reinterpret_cast<const __m128i*>(source1);\r
+       const __m128i* source128_2 = reinterpret_cast<const __m128i*>(source2);\r
+       __m128i*           dest128 = reinterpret_cast<__m128i*>(dest);          \r
+\r
+       __m128i d, s, a, rb, ag;\r
+       \r
+       // TODO: dynamic prefetch schedluing distance? needs to be optimized (R.N)\r
+       for(int k = 0, length = size/STRIDE; k < length; ++k)   \r
+       {\r
+               // TODO: put prefetch between calculations?(R.N)\r
+               _mm_prefetch(reinterpret_cast<const s8*>(source128_1+PSD), _MM_HINT_NTA);\r
+               _mm_prefetch(reinterpret_cast<const s8*>(source128_2+PSD), _MM_HINT_NTA);       \r
+\r
+               //work on entire cacheline before next prefetch\r
+               for(int n = 0; n < 4; ++n, ++dest128, ++source128_1, ++source128_2)\r
+               {\r
+                       // TODO: assembly optimization use PSHUFD on moves before calculations, lower latency than MOVDQA (R.N) http://software.intel.com/en-us/articles/fast-simd-integer-move-for-the-intel-pentiumr-4-processor/\r
+\r
+                       s = _mm_load_si128(source128_1);                // AABGGRR\r
+                       d = _mm_load_si128(source128_2);                // AABGGRR\r
+                                               \r
+                       // set alpha to lo16 from dest_\r
+                       rb = _mm_srli_epi32(d, 24);                     // 000000AA\r
+                       a = _mm_slli_epi32(rb, 16);                     // 00AA0000\r
+                       a = _mm_or_si128(rb, a);                        // 00AA00AA\r
+\r
+                       // fix alpha a = a > 127 ? a+1 : a\r
+                       // NOTE: If removed an *overflow* will occur with large values (R.N)\r
+                       rb = _mm_srli_epi16(a, 7);\r
+                       a = _mm_add_epi16(a, rb);\r
+                       \r
+                       rb = _mm_and_si128(lomask, s);          // 00B00RR              unpack\r
+                       rb = _mm_mullo_epi16(rb, a);            // BBRRRR               mul (D[A]*S)\r
+                       rb = _mm_srli_epi16(rb, 8);                     // 00B00RR              prepack and div [(D[A]*S)]/255\r
+\r
+                       ag = _mm_srli_epi16(s, 8);                      // 00AA00GG             unpack\r
+                       ag = _mm_mullo_epi16(ag, a);            // AAAAGGGG             mul (D[A]*S)\r
+                       ag = _mm_andnot_si128(lomask, ag);      // AA00GG00             prepack and div [(D[A]*S)]/255\r
+                                       \r
+                       rb = _mm_or_si128(rb, ag);                      // AABGGRR              pack\r
+                                       \r
+                       rb = _mm_sub_epi8(s, rb);                       // sub S-[(D[A]*S)/255]\r
+                       d = _mm_add_epi8(d, rb);                        // add D+[S-(D[A]*S)/255]\r
+\r
+                       _mm_stream_si128(dest128, d);\r
+               }\r
+       }       \r
+       _mm_mfence();   //ensure last WC buffers get flushed to memory  \r
+}\r
+\r
+// TODO: optimize\r
+void PreOver_REF(void* dest, const void* source1, const void* source2, size_t size)\r
+{      \r
+       assert(source1 != NULL && source2 != NULL && dest != NULL);\r
+       assert(size % 4 == 0);\r
+\r
+       const u8* source8_1 = reinterpret_cast<const u8*>(source1);\r
+       const u8* source8_2 = reinterpret_cast<const u8*>(source2);\r
+       u8* dest8 = reinterpret_cast<u8*>(dest);\r
+\r
+       for(size_t n = 0; n < size; n+=4)\r
+       {\r
+               u32 r1 = source8_1[n+0];\r
+               u32 g1 = source8_1[n+1];\r
+               u32 b1 = source8_1[n+2];\r
+               u32 a1 = source8_1[n+3];\r
+\r
+               u32 r2 = source8_2[n+0];\r
+               u32 g2 = source8_2[n+1];\r
+               u32 b2 = source8_2[n+2];\r
+               u32 a2 = source8_2[n+3];\r
+\r
+               dest8[n+0] = r2 + r1 - (a2*r1)/255;\r
+               dest8[n+1] = g2 + g1 - (a2*g1)/255;\r
+               dest8[n+2] = b2 + b1 - (a2*b1)/255;\r
+               dest8[n+3] = a2 + a1 - (a2*a1)/255;\r
+\r
+               // PRECISE\r
+               //if(a2 > 0)\r
+               //{\r
+               //      dest8[n+0] = r2 + r1 - int(float(a2*r1)/255.0f+0.5f);\r
+               //      dest8[n+1] = g2 + g1 - int(float(a2*g1)/255.0f+0.5f);\r
+               //      dest8[n+2] = b2 + b1 - int(float(a2*b1)/255.0f+0.5f);\r
+               //      dest8[n+3] = a2 + a1 - int(float(a2*a1)/255.0f+0.5f);\r
+               //}\r
+               //else\r
+               //{\r
+               //      dest8[n+0] = r1;\r
+               //      dest8[n+1] = g1;\r
+               //      dest8[n+2] = b1;\r
+               //      dest8[n+3] = a1;\r
+               //}\r
+       }\r
+}\r
+\r
+void PreOverParallel_REF(void* dest, const void* source1, const void* source2, size_t size)\r
+{\r
+       PreOverParallel(&PreOver_REF, dest, source1, source2, size);    \r
+}\r
+\r
+} // namespace image\r
+} // namespace utils\r
+} // namespace caspar\r
+\r
+\r
diff --git a/server/utils/image/Over.hpp b/server/utils/image/Over.hpp
new file mode 100644 (file)
index 0000000..ea7a7c4
--- /dev/null
@@ -0,0 +1,45 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef OVER_H_\r
+#define OVER_H_\r
+\r
+#include "../CPUID.hpp"\r
+\r
+namespace caspar{\r
+namespace utils{\r
+namespace image{\r
+               \r
+void PreOver_SSE2(void* dest, const void* source1, const void* source2, size_t size);\r
+void PreOverParallel_SSE2(void* dest, const void* source1, const void* source2, size_t size);\r
+void PreOver_FastSSE2(void* dest, const void* source1, const void* source2, size_t size);\r
+void PreOver_REF(void* dest, const void* source1, const void* source2, size_t size);\r
+void PreOverParallel_REF(void* dest, const void* source1, const void* source2, size_t size);\r
+\r
+typedef void(*PreOverFun)(void*, const void*, const void*, size_t);\r
+PreOverFun GetPreOverFun(SIMD simd = REF);\r
+\r
+} // namespace image\r
+} // namespace utils\r
+} // namespace caspar\r
+\r
+#endif\r
+\r
+\r
diff --git a/server/utils/image/Premultiply.cpp b/server/utils/image/Premultiply.cpp
new file mode 100644 (file)
index 0000000..9b5239a
--- /dev/null
@@ -0,0 +1,255 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\..\stdafx.h"\r
+\r
+#include "Premultiply.hpp"\r
+\r
+#include <intrin.h>\r
+#include <functional>\r
+\r
+#include "../Types.hpp"\r
+\r
+#include "tbb/parallel_for.h"\r
+#include "tbb/blocked_range.h"\r
+\r
+using namespace std::tr1::placeholders;\r
+\r
+namespace caspar{\r
+namespace utils{\r
+namespace image{\r
+\r
+static const size_t STRIDE = sizeof(__m128i)*4;\r
+\r
+void DoPreMultiplyParallel(const tbb::blocked_range<size_t>& r, const std::tr1::function<void(void*, const void*, size_t)>& func, void* dest, const void* source)\r
+{\r
+       size_t offset = r.begin()*STRIDE;\r
+       size_t size = r.size()*STRIDE;\r
+       func(reinterpret_cast<s8*>(dest) + offset, reinterpret_cast<const s8*>(source) + offset, size);\r
+}\r
+\r
+void PreMultiplyParallel(const std::tr1::function<void(void*, const void*, size_t)>& func, void* dest, const void* source, size_t size)\r
+{\r
+       tbb::parallel_for(tbb::blocked_range<size_t>(0, size/STRIDE), std::tr1::bind(&DoPreMultiplyParallel, _1, func, dest, source));  \r
+}\r
+\r
+PremultiplyFun GetPremultiplyFun(SIMD simd)\r
+{\r
+       if(simd >= SSE2)\r
+               return PremultiplyParallel_SSE2;\r
+       else\r
+               return PremultiplyParallel_REF;\r
+}\r
+\r
+// this function performs precise calculations\r
+void Premultiply_SSE2(void* dest, const void* source, size_t size)\r
+{\r
+       static const u32 PSD = 64;\r
+\r
+       static const __m128i lomask = _mm_set1_epi32(0x00FF00FF);\r
+       static const __m128i amask = _mm_set1_epi32(0xFF000000);\r
+       static const __m128i round = _mm_set1_epi16(128);       \r
+\r
+       assert(source != NULL && dest != NULL);\r
+       assert(size % STRIDE == 0);\r
+       \r
+       const __m128i* source128 = reinterpret_cast<const __m128i*>(source);\r
+       __m128i*           dest128 = reinterpret_cast<__m128i*>(dest);  \r
+\r
+       __m128i s, rb, ag, a, t;                \r
+       \r
+       for(size_t k = 0, length = size/STRIDE; k != length; ++k)       \r
+       {\r
+               // TODO: put prefetch between calculations?(R.N)\r
+               _mm_prefetch(reinterpret_cast<const s8*>(source128 + PSD), _MM_HINT_NTA);\r
+\r
+               // prefetch fetches entire cacheline (512bit). work on entire cacheline before next prefetch. 512/128 = 4, unroll four times = 16 pixels\r
+\r
+               // TODO: assembly optimization use PSHUFD on moves before calculations, lower latency than MOVDQA (R.N) http://software.intel.com/en-us/articles/fast-simd-integer-move-for-the-intel-pentiumr-4-processor/\r
+\r
+               for(int n = 0; n < 4; ++n, ++dest128, ++source128)\r
+               {\r
+                       s = _mm_load_si128(source128);          // AABBGGRR\r
+\r
+                       // set alpha to lo16 from source\r
+                       rb = _mm_srli_epi32(s, 24);                     // 000000AA\r
+                       a = _mm_slli_epi32(rb, 16);                     // 00AA0000\r
+                       a = _mm_or_si128(rb, a);                        // 00AA00AA\r
+\r
+                       rb = _mm_and_si128(lomask, s);          // 00BB00RR             \r
+                       rb = _mm_mullo_epi16(rb, a);            // BBBBRRRR     \r
+                       rb = _mm_add_epi16(rb, round);          // BBBBRRRR\r
+                       t = _mm_srli_epi16(rb, 8);                      // 00BB00RR     \r
+                       t = _mm_add_epi16(t, rb);\r
+                       rb = _mm_srli_epi16(t, 8);\r
+\r
+                       ag = _mm_srli_epi16(s, 8);                      // 00AA00GG             \r
+                       ag = _mm_mullo_epi16(ag, a);            // AAAAGGGG             \r
+                       ag = _mm_add_epi16(ag, round);\r
+                       t = _mm_srli_epi16(ag, 8);\r
+                       t = _mm_add_epi16(t, ag);\r
+                       ag = _mm_andnot_si128(lomask, t);       // AA00GG00             \r
+                                       \r
+                       a = _mm_or_si128(rb, ag);                       // XXBBGGRR\r
+                       a = _mm_andnot_si128(amask, a);         // 00BBGGRR\r
+\r
+                       s = _mm_and_si128(amask, s);            // AA000000\r
+\r
+                       s = _mm_or_si128(a, s);                         // AABBGGRR             pack\r
+\r
+                       // TODO: store entire cache line at the same time (write-combining => burst)? are there enough registers? 32 bit mode (special compile for 64bit?) (R.N)\r
+                       _mm_stream_si128(dest128, s);\r
+               }               \r
+       }\r
+       _mm_mfence();   //ensure last WC buffers get flushed to memory\r
+}\r
+\r
+void PremultiplyParallel_SSE2(void* dest, const void* source1, size_t size)\r
+{\r
+       PreMultiplyParallel(&Premultiply_SSE2, dest, source1, size);\r
+}\r
+\r
+void Premultiply_FastSSE2(void* dest, const void* source, size_t size)\r
+{\r
+       static const size_t stride = sizeof(__m128i)*4;\r
+       static const u32 PSD = 64;\r
+\r
+       static const __m128i lomask = _mm_set1_epi32(0x00FF00FF);\r
+       static const __m128i amask = _mm_set1_epi32(0xFF000000);\r
+       \r
+\r
+       assert(source != NULL && dest != NULL);\r
+       assert(size % stride == 0);\r
+\r
+       const __m128i* source128 = reinterpret_cast<const __m128i*>(source);\r
+       __m128i*           dest128 = reinterpret_cast<__m128i*>(dest);  \r
+\r
+       __m128i s = _mm_setzero_si128();        \r
+       __m128i rb = _mm_setzero_si128();       \r
+       __m128i ag = _mm_setzero_si128();       \r
+       __m128i a = _mm_setzero_si128();\r
+\r
+       for(size_t k = 0, length = size/stride; k != length; ++k)       \r
+       {\r
+               // TODO: put prefetch between calculations?(R.N)\r
+               _mm_prefetch(reinterpret_cast<const s8*>(source128 + PSD), _MM_HINT_NTA);\r
+\r
+               //work on entire cacheline before next prefetch\r
+\r
+               // TODO: assembly optimization use PSHUFD on moves before calculations, lower latency than MOVDQA (R.N) http://software.intel.com/en-us/articles/fast-simd-integer-move-for-the-intel-pentiumr-4-processor/\r
+\r
+               for(int n = 0; n < 4; ++n, ++dest128, ++source128)\r
+               {\r
+                       s = _mm_load_si128(source128);          // AABBGGRR\r
+\r
+                       // set alpha to lo16 from source\r
+                       rb = _mm_srli_epi32(s, 24);                     // 000000AA\r
+                       a = _mm_slli_epi32(rb, 16);                     // 00AA0000\r
+                       a = _mm_or_si128(rb, a);                        // 00AA00AA\r
+\r
+                       // fix alpha a = a > 127 ? a+1 : a\r
+                       rb = _mm_srli_epi16(a, 7);\r
+                       a = _mm_add_epi16(a, rb);\r
+                       \r
+                       rb = _mm_and_si128(lomask, s);          // 00BB00RR             unpack\r
+                       rb = _mm_mullo_epi16(rb, a);            // BBBBRRRR             mul (D[A]*S)\r
+                       rb = _mm_srli_epi16(rb, 8);                     // 00BB00RR             prepack and div [(D[A]*S)]/255\r
+\r
+                       ag = _mm_srli_epi16(s, 8);                      // 00AA00GG             unpack\r
+                       ag = _mm_mullo_epi16(ag, a);            // XXXXGGGG             mul (D[A]*S)\r
+                       ag = _mm_andnot_si128(lomask, ag);      // XX00GG00             prepack and div [(D[A]*S)]/255\r
+                                       \r
+                       a = _mm_or_si128(rb, ag);                       // XXBBGGRR\r
+                       a = _mm_andnot_si128(amask, a);         // 00BBGGRR\r
+\r
+                       s = _mm_and_si128(amask, s);            // AA000000\r
+\r
+                       s = _mm_or_si128(a, s);                         // AABBGGRR             pack\r
+\r
+                       // TODO: store entire cache line at the same time (write-combining => burst)? are there enough registers? 32 bit mode (special compile for 64bit?) (R.N)\r
+                       _mm_store_si128(dest128, s);\r
+               }               \r
+       }\r
+}\r
+\r
+void Premultiply_REF(void* dest, const void* source, size_t size)\r
+{\r
+       assert(source != NULL && dest != NULL);\r
+       assert(size % 4 == 0);\r
+\r
+       const u8* source8 = reinterpret_cast<const u8*>(source);\r
+       u8* dest8 = reinterpret_cast<u8*>(dest);\r
+\r
+       for(size_t n = 0; n < size; n+=4)\r
+       {\r
+               u32 r = source8[n+0];\r
+               u32 g = source8[n+1];\r
+               u32 b = source8[n+2];\r
+               u32 a = source8[n+3];\r
+\r
+               dest8[n+0] = (r*a)/255;\r
+               dest8[n+1] = (g*a)/255;\r
+               dest8[n+2] = (b*a)/255;\r
+               dest8[n+3] = a;\r
+       }\r
+}\r
+\r
+void PremultiplyParallel_REF(void* dest, const void* source1,  size_t size)\r
+{\r
+       PreMultiplyParallel(&Premultiply_REF, dest, source1, size);\r
+}\r
+\r
+\r
+//void StraightTransform_REF(const void* source, void* dest, size_t size)\r
+//{\r
+//     assert(source != NULL && dest != NULL);\r
+//     assert((size % 4) == 0);\r
+//\r
+//     const u8* source8 = reinterpret_cast<const u8*>(source);\r
+//     u8* dest8 = reinterpret_cast<u8*>(dest);\r
+//\r
+//     for(int n = 0; n < size; n+=4)\r
+//     {\r
+//             u32 r = source8[n+0];\r
+//             u32 g = source8[n+1];\r
+//             u32 b = source8[n+2];\r
+//             u32 a = source8[n+3];\r
+//\r
+//             if(a > 0)\r
+//             {\r
+//                     dest8[n+0] = (r*255)/a;\r
+//                     dest8[n+1] = (g*255)/a;\r
+//                     dest8[n+2] = (b*255)/a;\r
+//                     dest8[n+3] = a;\r
+//             }\r
+//             else\r
+//             {\r
+//                     dest8[n+0] = 0;\r
+//                     dest8[n+1] = 0;\r
+//                     dest8[n+2] = 0;\r
+//                     dest8[n+3] = 0;\r
+//             }\r
+//     }\r
+//}\r
+\r
+\r
+} // namespace image\r
+} // namespace utils\r
+} // namespace caspar\r
diff --git a/server/utils/image/Premultiply.hpp b/server/utils/image/Premultiply.hpp
new file mode 100644 (file)
index 0000000..7b3d146
--- /dev/null
@@ -0,0 +1,52 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef PREMULTIPLY_H_\r
+#define PREMULTIPLY_H_\r
+\r
+#include "../CPUID.hpp"\r
+\r
+namespace caspar{\r
+namespace utils{\r
+namespace image{\r
+       \r
+void Premultiply_SSE2   (void* dest, const void* source, size_t size);\r
+void PremultiplyParallel_SSE2   (void* dest, const void* source, size_t size);\r
+void Premultiply_FastSSE2(void* dest, const void* source, size_t size);\r
+void Premultiply_REF    (void* dest, const void* source, size_t size);\r
+void PremultiplyParallel_REF    (void* dest, const void* source, size_t size);\r
+\r
+typedef void(*PremultiplyFun)(void*, const void*, size_t);\r
+PremultiplyFun GetPremultiplyFun(SIMD simd = REF);\r
+\r
+\r
+//void StraightTransform_SSE2(const void* source, void* dest, size_t size);\r
+//void StraightTransform_REF(const void* source, void* dest, size_t size);\r
+//\r
+//typedef void(*StraightTransformFun)(const void*, void*, size_t);\r
+//StraightTransformFun GetStraightTransformFun(SIMD simd = REF);\r
+\r
+} // namespace image\r
+} // namespace utils\r
+} // namespace caspar\r
+\r
+#endif\r
+\r
+\r
diff --git a/server/utils/image/Shuffle.cpp b/server/utils/image/Shuffle.cpp
new file mode 100644 (file)
index 0000000..5633b6d
--- /dev/null
@@ -0,0 +1,210 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\..\stdafx.h"\r
+\r
+#include "Shuffle.hpp"\r
+\r
+#include <intrin.h>\r
+#include <functional>\r
+\r
+#include "../Types.hpp"\r
+\r
+#include "tbb/parallel_for.h"\r
+#include "tbb/blocked_range.h"\r
+\r
+using namespace std::tr1::placeholders;\r
+\r
+namespace caspar{\r
+namespace utils{\r
+namespace image{\r
+\r
+static const size_t STRIDE = sizeof(__m128i)*4;\r
+\r
+void DoShuffleParallel(const tbb::blocked_range<size_t>& r, const std::tr1::function<void(void*, const void*, size_t, const u8, const u8, const u8, const u8)>& func, void* dest, const void* source, const u8 red, const u8 green, const u8 blue, const u8 alpha)\r
+{\r
+       size_t offset = r.begin()*STRIDE;\r
+       size_t size = r.size()*STRIDE;\r
+       func(reinterpret_cast<s8*>(dest) + offset, reinterpret_cast<const s8*>(source) + offset, size, red, green, blue, alpha);\r
+}\r
+\r
+void ShuffleParallel(const std::tr1::function<void(void*, const void*, size_t, const u8, const u8, const u8, const u8)>& func, void* dest, const void* source, size_t size, const u8 red, const u8 green, const u8 blue, const u8 alpha)\r
+{\r
+       tbb::parallel_for(tbb::blocked_range<size_t>(0, size/STRIDE), std::tr1::bind(&DoShuffleParallel, _1, func, dest, source, red, green, blue, alpha));     \r
+}\r
+\r
+ShuffleFun GetShuffleFun(SIMD simd)\r
+{\r
+       if(simd >= SSSE3)\r
+               return ShuffleParallel_SSSE3;\r
+       else if(simd >= SSE2)\r
+               return ShuffleParallel_SSE2;\r
+       else\r
+               return ShuffleParallel_REF;\r
+}\r
+\r
+void Shuffle_SSSE3(void* dest, const void* source, size_t size, const u8 red, const u8 green, const u8 blue, const u8 alpha)\r
+{\r
+       static const unsigned int PSD = 64;     \r
+\r
+       assert(source != NULL && dest != NULL);\r
+       assert(red > -1 && red < 4 && green > -1 && green < 4 && blue > -1 && blue < 4 && alpha > -1 && alpha < 4 && "Invalid mask");\r
+       assert(size % STRIDE == 0);\r
+\r
+       const __m128i* source128 = reinterpret_cast<const __m128i*>(source);\r
+       __m128i*           dest128 = reinterpret_cast<__m128i*>(dest);  \r
+\r
+       __m128i reg0 = _mm_setzero_si128();     \r
+       __m128i reg1 = _mm_setzero_si128();     \r
+       __m128i reg2 = _mm_setzero_si128();     \r
+       __m128i reg3 = _mm_setzero_si128();     \r
+\r
+       const __m128i mask128 = _mm_set_epi8(alpha+12, blue+12, green+12, red+12, alpha+8, blue+8, green+8, red+8, alpha+4, blue+4, green+4, red+4, alpha, blue, green, red);\r
+\r
+       for(size_t k = 0, length = size/STRIDE; k < length; ++k)        \r
+       {\r
+               // TODO: put prefetch between calculations?(R.N)\r
+               _mm_prefetch(reinterpret_cast<const s8*>(source128 + PSD), _MM_HINT_NTA);\r
+\r
+               // work on entire cacheline before next prefetch\r
+\r
+               // TODO: assembly optimization use PSHUFD on moves before calculations, lower latency than MOVDQA (R.N) http://software.intel.com/en-us/articles/fast-simd-integer-move-for-the-intel-pentiumr-4-processor/\r
+\r
+               reg0 = _mm_load_si128(source128++);     \r
+               reg1 = _mm_load_si128(source128++);     \r
+\r
+               _mm_stream_si128(dest128++, _mm_shuffle_epi8(reg0, mask128));\r
+\r
+               reg2 = _mm_load_si128(source128++);     \r
+\r
+               _mm_stream_si128(dest128++, _mm_shuffle_epi8(reg1, mask128));\r
+\r
+               reg3 = _mm_load_si128(source128++);     \r
+               \r
+               _mm_stream_si128(dest128++, _mm_shuffle_epi8(reg2, mask128));   \r
+               _mm_stream_si128(dest128++, _mm_shuffle_epi8(reg3, mask128));           \r
+       }\r
+       _mm_mfence();   //ensure last WC buffers get flushed to memory\r
+}\r
+\r
+void ShuffleParallel_SSSE3(void* dest, const void* source, size_t size, const u8 red, const u8 green, const u8 blue, const u8 alpha)\r
+{\r
+       ShuffleParallel(&Shuffle_SSSE3, dest, source, size, red, green, blue, alpha);\r
+}\r
+\r
+// TODO: should be optimized for different combinations (R.N)\r
+void Shuffle_SSE2(void* dest, const void* source, size_t size, const u8 red, const u8 green, const u8 blue, const u8 alpha)\r
+{\r
+       static const size_t stride = sizeof(__m128i)*4;\r
+       static const u32 PSD = 64;\r
+\r
+       static const __m128i himask     = _mm_set1_epi32(0xFF000000);   \r
+       static const __m128i lomask     = _mm_set1_epi32(0x000000FF);\r
+       \r
+       assert(source != NULL && dest != NULL);\r
+       assert(red > -1 && red < 4 && green > -1 && green < 4 && blue > -1 && blue < 4 && alpha > -1 && alpha < 4);\r
+       assert(size % stride == 0);\r
+\r
+       const __m128i* source128 = reinterpret_cast<const __m128i*>(source);\r
+       __m128i*           dest128 = reinterpret_cast<__m128i*>(dest);  \r
+\r
+       __m128i s, m0, m1, r;\r
+\r
+       const int shft0 = (red)*8;\r
+       const int shft1 = (green)*8;\r
+       const int shft2 = (3-blue)*8;\r
+       const int shft3 = (3-alpha)*8;\r
+\r
+       for(int k = 0, length = size/stride; k < length; ++k)   \r
+       {\r
+               // TODO: dynamic prefetch schedluing distance? needs to be optimized (R.N)              \r
+               // TODO: put prefetch between calculations?(R.N)\r
+               _mm_prefetch(reinterpret_cast<const s8*>(source128 + PSD), _MM_HINT_NTA);\r
+\r
+               // work on entire cacheline before next prefetch\r
+\r
+               // TODO: assembly optimization use PSHUFD on moves before calculations, lower latency than MOVDQA (R.N) http://software.intel.com/en-us/articles/fast-simd-integer-move-for-the-intel-pentiumr-4-processor/\r
+\r
+               for(int n = 0; n < 4; ++n, ++dest128, ++source128)\r
+               {\r
+                       s = _mm_load_si128(source128);\r
+                       \r
+                       m0 = _mm_srli_epi32(s, shft0);\r
+                       m0 = _mm_and_si128(m0, lomask);\r
+\r
+                       m1 = _mm_srli_epi32(s, shft1);\r
+                       m1 = _mm_and_si128(m1, lomask);\r
+                       m1 = _mm_slli_epi32(m1, 8);\r
+                       \r
+                       r = _mm_or_si128(m0, m1);\r
+\r
+                       m0 = _mm_slli_epi32(s, shft2);\r
+                       m0 = _mm_and_si128(m0, himask);\r
+                       m0 = _mm_srli_epi32(m0, 8);                     \r
+\r
+                       m1 = _mm_slli_epi32(s, shft3);\r
+                       m1 = _mm_and_si128(m1, himask);\r
+                       \r
+                       m0 = _mm_or_si128(m0, m1);\r
+\r
+                       r = _mm_or_si128(r, m0);\r
+\r
+                       _mm_stream_si128(dest128, r);\r
+               }\r
+       }\r
+       _mm_mfence();   //ensure last WC buffers get flushed to memory\r
+}\r
+\r
+void ShuffleParallel_SSE2(void* dest, const void* source, size_t size, const u8 red, const u8 green, const u8 blue, const u8 alpha)\r
+{\r
+       ShuffleParallel(&Shuffle_SSE2, dest, source, size, red, green, blue, alpha);\r
+}\r
+\r
+void Shuffle_REF(void* dest, const void* source, size_t size, const u8 red, const u8 green, const u8 blue, const u8 alpha)\r
+{\r
+       assert(source != NULL && dest != NULL);\r
+       assert(red > -1 && red < 4 && green > -1 && green < 4 && blue > -1 && blue < 4 && alpha > -1 && alpha < 4);\r
+       assert(size % 4 == 0);\r
+\r
+       const u8* source8 = reinterpret_cast<const u8*>(source);\r
+       u8*               dest8 = reinterpret_cast<u8*>(dest);  \r
+\r
+       for(size_t n = 0; n < size; n+=4)\r
+       {\r
+               u8 r = source8[n+red];\r
+               u8 g = source8[n+green];\r
+               u8 b = source8[n+blue];\r
+               u8 a = source8[n+alpha];\r
+\r
+               dest8[n+0] = r;\r
+               dest8[n+1] = g;\r
+               dest8[n+2] = b;\r
+               dest8[n+3] = a;\r
+       }\r
+}\r
+\r
+void ShuffleParallel_REF(void* dest, const void* source, size_t size, const u8 red, const u8 green, const u8 blue, const u8 alpha)\r
+{\r
+       ShuffleParallel(&Shuffle_REF, dest, source, size, red, green, blue, alpha);\r
+}\r
+\r
+} // namespace image\r
+} // namespace utils\r
+} // namespace caspar\r
diff --git a/server/utils/image/Shuffle.hpp b/server/utils/image/Shuffle.hpp
new file mode 100644 (file)
index 0000000..c7973fe
--- /dev/null
@@ -0,0 +1,45 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _SHUFFLE_\r
+#define _SHUFFLE_\r
+\r
+#include "../CPUID.hpp"\r
+#include "../Types.hpp"\r
+\r
+namespace caspar{\r
+namespace utils{\r
+namespace image{\r
+\r
+void Shuffle_SSSE3(void* dest, const void* source, size_t size, const u8 red, const u8 green, const u8 blue, const u8 alpha);\r
+void Shuffle_SSE2 (void* dest, const void* source, size_t size, const u8 red, const u8 green, const u8 blue, const u8 alpha);\r
+void Shuffle_REF  (void* dest, const void* source, size_t size, const u8 red, const u8 green, const u8 blue, const u8 alpha);\r
+void ShuffleParallel_SSSE3(void* dest, const void* source, size_t size, const u8 red, const u8 green, const u8 blue, const u8 alpha);\r
+void ShuffleParallel_SSE2 (void* dest, const void* source, size_t size, const u8 red, const u8 green, const u8 blue, const u8 alpha);\r
+void ShuffleParallel_REF  (void* dest, const void* source, size_t size, const u8 red, const u8 green, const u8 blue, const u8 alpha);\r
+\r
+typedef void(*ShuffleFun)(void*, const void*, size_t, const u8, const u8, const u8, const u8);\r
+ShuffleFun GetShuffleFun(SIMD simd = REF);\r
+\r
+} // namespace image\r
+} // namespace utils\r
+} // namespace caspar\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/utils/object_pool.h b/server/utils/object_pool.h
new file mode 100644 (file)
index 0000000..4368c48
--- /dev/null
@@ -0,0 +1,84 @@
+#ifndef _OBJECTPOOL_H_\r
+#define _OBJECTPOOL_H_\r
+\r
+#include <functional>\r
+#include <memory>\r
+#include <type_traits>\r
+\r
+#include <tbb/concurrent_queue.h>\r
+\r
+namespace caspar\r
+{\r
+\r
+namespace utils\r
+{\r
+\r
+template<typename T>\r
+struct default_new_delete_allocator\r
+{      \r
+       static T* construct()\r
+       { return new T(); }\r
+\r
+       \r
+       template<typename P0>\r
+       static T* construct(P0&& p0)\r
+       { return new T(std::forward<P0>(p0)); }\r
+\r
+       template<typename P0, typename P1>\r
+       static T* construct(P0&& p0, P1&& p1)\r
+       { return new T(std::forward<P0>(p0), std::forward<P1>(p1)); }\r
+       \r
+       template<typename P0, typename P1, typename P2>\r
+       static T* construct(P0&& p0, P1&& p1, P2&& p2)\r
+       { return new T(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2)); }\r
+\r
+       static void destroy(T* const block)\r
+       { delete block; }\r
+};\r
+\r
+template<typename T, typename allocator = default_new_delete_allocator<T>>\r
+class object_pool\r
+{\r
+       typedef std::shared_ptr<T> Ptr;\r
+public:\r
+\r
+       ~object_pool()\r
+       {\r
+               T* item;\r
+               while(pool_.try_pop(item))\r
+                       allocator::destroy(item);\r
+       }\r
+\r
+       Ptr construct()\r
+       {\r
+               T* item = pool_.try_pop(item) ? item : allocator::construct();\r
+               return Ptr(item, [&](T* item){ pool_.push(item); });\r
+       }\r
+       \r
+       template<typename P0>\r
+       Ptr construct(P0&& p0)\r
+       {\r
+               T* item = pool_.try_pop(item) ? item : allocator::construct(std::forward<P0>(p0));\r
+               return Ptr(item, [&](T* item){ pool_.push(item); });\r
+       }\r
+       \r
+       template<typename P0, typename P1>\r
+       Ptr construct(P0&& p0, P1&& p1)\r
+       {\r
+               T* item = pool_.try_pop(item) ? item : allocator::construct(std::forward<P0>(p0), std::forward<P1>(p1));\r
+               return Ptr(item, [&](T* item){ pool_.push(item); });\r
+       }\r
+       \r
+       template<typename P0, typename P1, typename P2>\r
+       Ptr construct(P0&& p0, P1&& p1, P1&& p2)\r
+       {\r
+               T* item = pool_.try_pop(item) ? item : allocator::construct(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2));\r
+               return Ptr(item, [&](T* item){ pool_.push(item); });\r
+       }\r
+private:\r
+       tbb::concurrent_queue<T*> pool_;\r
+};\r
+\r
+}}\r
+\r
+#endif
\ No newline at end of file
diff --git a/server/utils/runnable.h b/server/utils/runnable.h
new file mode 100644 (file)
index 0000000..935cf35
--- /dev/null
@@ -0,0 +1,42 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#ifndef _CASPAR_RUNNABLE_H__\r
+#define _CASPAR_RUNNABLE_H__\r
+\r
+#pragma once\r
+\r
+namespace caspar {\r
+namespace utils {\r
+\r
+class IRunnable\r
+{\r
+public:\r
+       virtual ~IRunnable() {}\r
+       virtual void Run(HANDLE stopEvent) = 0;\r
+       virtual bool OnUnhandledException(const std::exception&) throw() = 0;\r
+};\r
+\r
+typedef std::tr1::shared_ptr<IRunnable> RunnablePtr;\r
+\r
+}      //namespace utils\r
+}      //namespace caspar\r
+\r
+#endif //_CASPAR_RUNNABLE_H__
\ No newline at end of file
diff --git a/server/utils/scope_exit.h b/server/utils/scope_exit.h
new file mode 100644 (file)
index 0000000..24de34e
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef _CASPAR_SCOPE_EXIT_H_\r
+#define _CASPAR_SCOPE_EXIT_H_\r
+\r
+#include <utility>\r
+#include <functional>\r
+#include "Noncopyable.hpp"\r
+\r
+namespace caspar\r
+{\r
+       namespace utils \r
+       {\r
+               class scope_exit\r
+               {\r
+                       scope_exit( const scope_exit& );\r
+                       const scope_exit& operator=( const scope_exit& );\r
+               public:\r
+                       \r
+                       template <typename T, typename F>\r
+                       explicit scope_exit(T& obj, const F& func) : exitScope_(std::bind(func, obj))\r
+                       {}\r
+\r
+                       explicit scope_exit(std::function<void()>&& exitScope) : exitScope_(std::move(exitScope))\r
+                       {}\r
+\r
+                       ~scope_exit()\r
+                       {\r
+                               exitScope_();\r
+                       }\r
+\r
+               private:\r
+                       std::function<void()> exitScope_;\r
+               };              \r
+               \r
+       }\r
+}\r
+\r
+#define _CASPAR_EXIT_SCOPE_LINENAME_CAT(name, line) name##line\r
+#define _CASPAR_EXIT_SCOPE_LINENAME(name, line) _CASPAR_EXIT_SCOPE_LINENAME_CAT(name, line)\r
+#define CASPAR_SCOPE_EXIT caspar::utils::scope_exit _CASPAR_EXIT_SCOPE_LINENAME(EXIT, __LINE__)\r
+\r
+#endif
\ No newline at end of file